config.c
上传用户:seven77cht
上传日期:2007-01-04
资源大小:486k
文件大小:92k
- /***************************************
- $Header: /home/amb/wwwoffle/RCS/config.c 2.80 2000/01/22 13:26:22 amb Exp $
- WWWOFFLE - World Wide Web Offline Explorer - Version 2.5d.
- Configuration file management functions.
- ******************/ /******************
- Written by Andrew M. Bishop
- This file Copyright 1997,98,99,2000 Andrew M. Bishop
- It may be distributed under the GNU Public License, version 2, or
- any higher version. See section COPYING of the GNU Public license
- for conditions under which this file may be redistributed.
- ***************************************/
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <ctype.h>
- #include <limits.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/utsname.h>
- #include <dirent.h>
- #include <pwd.h>
- #include <grp.h>
- #include "misc.h"
- #include "config.h"
- #include "proto.h"
- #include "sockets.h"
- #include "errors.h"
- #include "wwwoffle.h"
- #ifndef SPOOL_DIR
- #define SPOOL_DIR DEF_SPOOL
- #endif
- #ifndef CONF_DIR
- #define CONF_DIR DEF_CONF
- #endif
- /* Type definitions */
- /*+ The type of value to expect for a value. +*/
- typedef enum _ConfigType
- {
- Fixed, /*+ When the left hand side is fixed. +*/
- None, /*+ When there is no right hand side. +*/
- CfgMaxServers, /*+ Max number of servers to fork (>0, <MAX_SERVERS). +*/
- CfgMaxFetchServers, /*+ Max number of servers for fetching pages (>0, <MAX_FETCH_SERVERS). +*/
- CfgLogLevel, /*+ A log level (debug, info, important, warning or fatal). +*/
- Boolean, /*+ A boolean response (yes/no 1/0 true/false). +*/
- PortNumber, /*+ For port numbers (>0). +*/
- AgeDays, /*+ An age in days (can be -ve). +*/
- TimeSecs, /*+ A time in seconds (can be -ve). +*/
- CacheSize, /*+ The cache size (must be >=0). +*/
- FileSize, /*+ A file size (must be >=0) +*/
- Percentage, /*+ A percentage (must be >=0 and <=100) +*/
- UserId, /*+ For user IDs, (numeric or string). +*/
- GroupId, /*+ For group IDs, (numeric or string). +*/
- String, /*+ For an arbitrary string. +*/
- PathName, /*+ For pathname values (string starting with '/'). +*/
- FileExt, /*+ A file extension (.string). +*/
- FileMode, /*+ The mode for dir/file creation. +*/
- MIMEType, /*+ A MIME type (string/string). +*/
- Host, /*+ For host names (string). +*/
- HostAndPort, /*+ For host name and port numbers (string[:port]). +*/
- HostAndPortOrNone, /*+ For host name and port numbers (string[:port]) or nothing. +*/
- UserPass, /*+ A username and password (string:string) +*/
- Url, /*+ For a URL ([proto://host[:port]]/path). +*/
- OptionalUrl, /*+ For an optional URL ([proto://host[:port]]/path). +*/
- UrlSpecification /*+ A URL specification as described in README.CONF. +*/
- }
- ConfigType;
- /*+ A description of an entry in a section of the config file. +*/
- typedef struct _Entry
- {
- char *name; /*+ The name of the entry. +*/
- void *pointer; /*+ A pointer to the value of the entry. +*/
- char list; /*+ Set to true if it is a list of KeyPairs. +*/
- ConfigType left_type; /*+ The type of the left side of the equals sign. +*/
- ConfigType right_type; /*+ The type of the right side of the equals sign. +*/
- }
- Entry;
- /*+ A description of a section in the config file. +*/
- typedef struct _Section
- {
- char *name; /*+ The name of the section. +*/
- Entry *entries; /*+ The entries in the section (NULL terminated). +*/
- }
- Section;
- /*+ A URL-SPECIFICATION as described in README.CONF. +*/
- typedef struct _UrlSpec
- {
- int negated; /*+ Set to true if this is a negated URL-SPECIFICATION +*/
- char *proto; /*+ The protocol (or NULL). +*/
- char *host; /*+ The hostname (or NULL). +*/
- int port; /*+ The port number (or 0 or -1). +*/
- char *path; /*+ The pathname (or NULL). +*/
- char *args; /*+ The arguments (or NULL) +*/
- }
- UrlSpec;
- /*+ A key or a value. +*/
- typedef union _KeyOrValue
- {
- char *string; /*+ A string value. +*/
- int integer; /*+ An integer value. +*/
- UrlSpec *urlspec; /*+ A URL-SPECIFICATION +*/
- }
- KeyOrValue;
- /*+ A key and value pair. +*/
- typedef struct _KeyPair
- {
- KeyOrValue key; /*+ The key. +*/
- KeyOrValue value; /*+ The value. +*/
- }
- KeyPair;
- /*+ The last of a KeyPair list. +*/
- static KeyPair KeyPairEnd;
- /* StartUp section */
- /*+ The name of the configuration file. +*/
- char *ConfigFile=CONF_DIR "/wwwoffle.conf";
- /*+ The port number to use for the HTTP proxy port. +*/
- int HTTP_Port=DEF_HTTP_PORT;
- /*+ The port number to use for the wwwoffle port. +*/
- int WWWOFFLE_Port=DEF_WWWOFFLE_PORT;
- /*+ The spool directory. +*/
- char *SpoolDir=SPOOL_DIR;
- /*+ The user id for wwwoffled or -1 for none. +*/
- int WWWOFFLE_Uid=-1;
- /*+ The group id for wwwoffled or -1 for none. +*/
- int WWWOFFLE_Gid=-1;
- /*+ Whether to use the syslog facility or not. +*/
- int UseSyslog=1;
- /*+ The password required for demon configuration. +*/
- char *PassWord=NULL;
- /*+ Maximum number of servers +*/
- int MaxServers=DEF_MAX_SERVERS; /*+ in total. +*/
- int MaxFetchServers=DEF_MAX_FETCH_SERVERS; /*+ for fetching. +*/
- /*+ The permissions for creation of +*/
- mode_t DirPerm=DEF_DIR_PERM; /*+ directories. +*/
- mode_t FilePerm=DEF_FILE_PERM; /*+ files. +*/
- /*+ The name of a progam to run when changing mode to +*/
- char *RunOnline=NULL; /*+ online. +*/
- char *RunOffline=NULL; /*+ offline. +*/
- char *RunAutodial=NULL; /*+ auto dial. +*/
- /*+ The entries in the StartUp section. +*/
- static Entry startup_entries[]={{"http-port" ,(void*)&HTTP_Port ,0,Fixed,PortNumber },
- {"wwwoffle-port" ,(void*)&WWWOFFLE_Port ,0,Fixed,PortNumber },
- {"spool-dir" ,(void*)&SpoolDir ,0,Fixed,PathName },
- {"run-uid" ,(void*)&WWWOFFLE_Uid ,0,Fixed,UserId },
- {"run-gid" ,(void*)&WWWOFFLE_Gid ,0,Fixed,GroupId },
- {"use-syslog" ,(void*)&UseSyslog ,0,Fixed,Boolean },
- {"password" ,(void*)&PassWord ,0,Fixed,String },
- {"max-servers" ,(void*)&MaxServers ,0,Fixed,CfgMaxServers },
- {"max-fetch-servers",(void*)&MaxFetchServers ,0,Fixed,CfgMaxFetchServers},
- {"dir-perm" ,(void*)&DirPerm ,0,Fixed,FileMode },
- {"file-perm" ,(void*)&FilePerm ,0,Fixed,FileMode },
- {"run-online" ,(void*)&RunOnline ,0,Fixed,PathName },
- {"run-offline" ,(void*)&RunOffline ,0,Fixed,PathName },
- {"run-autodial" ,(void*)&RunAutodial ,0,Fixed,PathName },
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The StartUp section. +*/
- static Section startup_section={"StartUp",startup_entries};
- /* Options Section */
- /*+ The level of error logging (see ErrorLevel in errors.h) +*/
- int LogLevel=Important, /*+ in the config file for syslog and stderr. +*/ /* see SetDefaultValues() */
- DebugLevel=-1; /*+ on the command line for stderr. +*/ /* not in the config file */
- /*+ The number of days to display in the index of the latest pages. +*/
- int IndexLatestDays; /* see SetDefaultValues() */
- /*+ The maximum age of a cached page to use in preference while online. +*/
- int RequestChanged; /* see SetDefaultValues() */
- /*+ The option to only request changes to a page once per session online. +*/
- int RequestChangedOnce; /* see SetDefaultValues() */
- /*+ The option to re-request pages that have expired. +*/
- int RequestExpired; /* see SetDefaultValues() */
- /*+ The option to re-request pages that have the no-cache flag set. +*/
- int RequestNoCache; /* see SetDefaultValues() */
- /*+ The option to allow or ignore the 'Pragma: no-cache' request. +*/
- int PragmaNoCache; /* see SetDefaultValues() */
- /*+ The option to not automatically make requests while offline but to need confirmation. +*/
- int ConfirmRequests; /* see SetDefaultValues() */
- /*+ The amount of time that a socket connection will wait for data. +*/
- int SocketTimeout=120; /* see SetDefaultValues() */
- /*+ The amount of time that a socket will wait for the intial connection. +*/
- int ConnectTimeout=30; /* see SetDefaultValues() */
- /*+ The option to retry a failed connection. +*/
- int ConnectRetry; /* see SetDefaultValues() */
- /*+ The list of allowed SSL port numbers. +*/
- static KeyPair **SSLAllowPort; /* see SetDefaultValues() */
- /*+ The option to disable the lasttime/prevtime indexs. +*/
- int NoLasttimeIndex; /* see SetDefaultValues() */
- /*+ The option to keep downloads that are interrupted by the user. +*/
- int IntrDownloadKeep; /* see SetDefaultValues() */
- /*+ The option to keep on downloading interrupted pages if +*/
- int IntrDownloadSize; /*+ smaller than a given size. +*/ /* see SetDefaultValues() */
- int IntrDownloadPercent; /*+ more than a given percentage complete. +*/ /* see SetDefaultValues() */
- /*+ The option to keep downloads that time out. +*/
- int TimeoutDownloadKeep; /* see SetDefaultValues() */
- /*+ The entries in the Options section. +*/
- static Entry options_entries[]={{"log-level" ,(void*)&LogLevel ,0,Fixed,CfgLogLevel},
- {"index-latest-days" ,(void*)&IndexLatestDays ,0,Fixed,AgeDays },
- {"request-changed" ,(void*)&RequestChanged ,0,Fixed,TimeSecs },
- {"request-changed-once" ,(void*)&RequestChangedOnce ,0,Fixed,Boolean },
- {"request-expired" ,(void*)&RequestExpired ,0,Fixed,Boolean },
- {"request-no-cache" ,(void*)&RequestNoCache ,0,Fixed,Boolean },
- {"pragma-no-cache" ,(void*)&PragmaNoCache ,0,Fixed,Boolean },
- {"confirm-requests" ,(void*)&ConfirmRequests ,0,Fixed,Boolean },
- {"socket-timeout" ,(void*)&SocketTimeout ,0,Fixed,TimeSecs },
- {"connect-timeout" ,(void*)&ConnectTimeout ,0,Fixed,TimeSecs },
- {"connect-retry" ,(void*)&ConnectRetry ,0,Fixed,Boolean },
- {"ssl-allow-port" ,(void*)&SSLAllowPort ,1,Fixed,PortNumber },
- {"no-lasttime-index" ,(void*)&NoLasttimeIndex ,0,Fixed,Boolean },
- {"intr-download-keep" ,(void*)&IntrDownloadKeep ,0,Fixed,Boolean },
- {"intr-download-size" ,(void*)&IntrDownloadSize ,0,Fixed,FileSize },
- {"intr-download-percent",(void*)&IntrDownloadPercent,0,Fixed,Percentage },
- {"timeout-download-keep",(void*)&TimeoutDownloadKeep,0,Fixed,Boolean },
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The Options section. +*/
- static Section options_section={"Options",options_entries};
- /* FetchOptions section */
- /*+ The option to also fetch style sheets. +*/
- int FetchStyleSheets; /* see SetDefaultValues() */
- /*+ The option to also fetch images. +*/
- int FetchImages; /* see SetDefaultValues() */
- /*+ The option to also fetch frames. +*/
- int FetchFrames; /* see SetDefaultValues() */
- /*+ The option to also fetch scripts. +*/
- int FetchScripts; /* see SetDefaultValues() */
- /*+ The option to also fetch objects. +*/
- int FetchObjects; /* see SetDefaultValues() */
- /*+ The entries in the FetchOptions section. +*/
- static Entry fetchoptions_entries[]={{"stylesheets",(void*)&FetchStyleSheets,0,Fixed,Boolean},
- {"images" ,(void*)&FetchImages ,0,Fixed,Boolean},
- {"frames" ,(void*)&FetchFrames ,0,Fixed,Boolean},
- {"scripts" ,(void*)&FetchScripts ,0,Fixed,Boolean},
- {"objects" ,(void*)&FetchObjects ,0,Fixed,Boolean},
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The FetchOptions section. +*/
- static Section fetchoptions_section={"FetchOptions",fetchoptions_entries};
- /* ModifyHTML section */
- /*+ The option to turn on the modifications in this section. +*/
- int EnableHTMLModifications; /* see SetDefaultValues() */
- /*+ The option of a tag that can be added to the bottom of the spooled pages with the date and some buttons. +*/
- int AddCacheInfo; /* see SetDefaultValues() */
- /*+ The options to modify the anchor tags in the HTML. +*/
- char *AnchorModifyBegin[3], /* see SetDefaultValues() */
- *AnchorModifyEnd[3]; /* see SetDefaultValues() */
- /*+ The option to disable scripts and scripted actions. +*/
- int DisableHTMLScript; /* see SetDefaultValues() */
- /*+ The option to disable the <blink> tag. +*/
- int DisableHTMLBlink; /* see SetDefaultValues() */
- /*+ The option to disable animated GIFs. +*/
- int DisableAnimatedGIF; /* see SetDefaultValues() */
- /*+ The entries in the ModifyHTMLOptions section. +*/
- static Entry modifyhtml_entries[]={{"enable-modify-html" ,(void*)&EnableHTMLModifications,0,Fixed,Boolean},
- {"add-cache-info" ,(void*)&AddCacheInfo ,0,Fixed,Boolean},
- {"anchor-cached-begin" ,(void*)&AnchorModifyBegin[0] ,0,Fixed,String },
- {"anchor-cached-end" ,(void*)&AnchorModifyEnd[0] ,0,Fixed,String },
- {"anchor-requested-begin" ,(void*)&AnchorModifyBegin[1] ,0,Fixed,String },
- {"anchor-requested-end" ,(void*)&AnchorModifyEnd[1] ,0,Fixed,String },
- {"anchor-not-cached-begin",(void*)&AnchorModifyBegin[2] ,0,Fixed,String },
- {"anchor-not-cached-end" ,(void*)&AnchorModifyEnd[2] ,0,Fixed,String },
- {"disable-script" ,(void*)&DisableHTMLScript ,0,Fixed,Boolean},
- {"disable-blink" ,(void*)&DisableHTMLBlink ,0,Fixed,Boolean},
- {"disable-animated-gif" ,(void*)&DisableAnimatedGIF ,0,Fixed,Boolean},
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The ModifyHTML section. +*/
- static Section modifyhtml_section={"ModifyHTML",modifyhtml_entries};
- /* LocalHost section */
- /*+ The list of localhost hostnames. +*/
- static KeyPair **LocalHost; /* see SetDefaultValues() */
- /*+ The entries in the LocalHost section. +*/
- static Entry localhost_entries[]={{"" ,(void*)&LocalHost,1,Host,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The LocalHost section. +*/
- static Section localhost_section={"LocalHost",localhost_entries};
- /* LocalNet section */
- /*+ The list of local network hostnames. +*/
- static KeyPair **LocalNet; /* see SetDefaultValues() */
- /*+ The entries in the LocalNet section. +*/
- static Entry localnet_entries[]={{"" ,(void*)&LocalNet,1,Host,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The LocalNet section. +*/
- static Section localnet_section={"LocalNet",localnet_entries};
- /* AllowedConnectHosts section */
- /*+ The list of allowed hostnames. +*/
- static KeyPair **AllowedConnectHosts; /* see SetDefaultValues() */
- /*+ The entries in the AllowedConnectHosts section. +*/
- static Entry allowedconnecthosts_entries[]={{"" ,(void*)&AllowedConnectHosts,1,Host,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The AllowedConnectHosts section. +*/
- static Section allowedconnecthosts_section={"AllowedConnectHosts",allowedconnecthosts_entries};
- /* AllowedConnectUsers section */
- /*+ The list of allowed usernames and paswords. +*/
- static KeyPair **AllowedConnectUsers; /* see SetDefaultValues() */
- /*+ The entries in the AllowedConnectUsers section. +*/
- static Entry allowedconnectusers_entries[]={{"" ,(void*)&AllowedConnectUsers,1,UserPass,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The AllowedConnectUsers section. +*/
- static Section allowedconnectusers_section={"AllowedConnectUsers",allowedconnectusers_entries};
- /* DontCache section */
- /*+ The list of URLs not to cache. +*/
- static KeyPair **DontCache; /* see SetDefaultValues() */
- /*+ The entries in the DontCache section. +*/
- static Entry dontcache_entries[]={{"" ,(void*)&DontCache,1,UrlSpecification,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The DontCache section. +*/
- static Section dontcache_section={"DontCache",dontcache_entries};
- /* DontGet section */
- /*+ The list of URLs not to get. +*/
- static KeyPair **DontGet; /* see SetDefaultValues() */
- /*+ The replacement URL. +*/
- char *DontGetReplacementURL; /* see SetDefaultValues() */
- /*+ The entries in the DontGet section. +*/
- static Entry dontget_entries[]={{"replacement",(void*)&DontGetReplacementURL,0,Fixed ,Url },
- {"" ,(void*)&DontGet ,1,UrlSpecification,OptionalUrl},
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The DontGet section. +*/
- static Section dontget_section={"DontGet",dontget_entries};
- /* DontGetRecursive section */
- /*+ The list of URLs not to get. +*/
- static KeyPair **DontGetRecursive; /* see SetDefaultValues() */
- /*+ The entries in the DontGetRecursive section. +*/
- static Entry dontgetrecursive_entries[]={{"" ,(void*)&DontGetRecursive,1,UrlSpecification,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The DontGetRecursive section. +*/
- static Section dontgetrecursive_section={"DontGetRecursive",dontgetrecursive_entries};
- /* DontRequestOffline section */
- /*+ The list of URLs not to request. +*/
- static KeyPair **DontRequestOffline; /* see SetDefaultValues() */
- /*+ The entries in the DontRequestOffline section. +*/
- static Entry dontrequestoffline_entries[]={{"" ,(void*)&DontRequestOffline,1,UrlSpecification,None},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The DontRequestOffline section. +*/
- static Section dontrequestoffline_section={"DontRequestOffline",dontrequestoffline_entries};
- /* CensorHeader section */
- /*+ The list of censored headers. +*/
- static KeyPair **CensorHeader; /* see SetDefaultValues() */
- /*+ Flags to cause the referer header to be mangled. +*/
- static int RefererSelf, /* see SetDefaultValues() */
- RefererSelfDir; /* see SetDefaultValues() */
- /*+ The entries in the censor headers section. +*/
- static Entry censorheader_entries[]={{"referer-self" ,(void*)&RefererSelf ,0,Fixed ,Boolean},
- {"referer-self-dir",(void*)&RefererSelfDir,0,Fixed ,Boolean},
- {"" ,(void*)&CensorHeader ,1,String,String },
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The CensorHeader section. +*/
- static Section censorheader_section={"CensorHeader",censorheader_entries};
- /* FTPOptions section */
- /*+ The anon-ftp username. +*/
- static char *FTPUserName; /* see SetDefaultValues() */
- /*+ The anon-ftp password. +*/
- static char *FTPPassWord; /* see SetDefaultValues() */
- /*+ The information that is needed to allow non-anonymous access, +*/
- static KeyPair **FTPAuthHost, /*+ hostname +*/ /* see SetDefaultValues() */
- **FTPAuthUser, /*+ username +*/ /* see SetDefaultValues() */
- **FTPAuthPass; /*+ password +*/ /* see SetDefaultValues() */
- /*+ The entries in the FTPOptions section. +*/
- static Entry ftpoptions_entries[]={{"anon-username",(void*)&FTPUserName,0,Fixed,String },
- {"anon-password",(void*)&FTPPassWord,0,Fixed,String },
- {"auth-hostname",(void*)&FTPAuthHost,1,Fixed,HostAndPort},
- {"auth-username",(void*)&FTPAuthUser,1,Fixed,String },
- {"auth-password",(void*)&FTPAuthPass,1,Fixed,String },
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The FTPOptions section. +*/
- static Section ftpoptions_section={"FTPOptions",ftpoptions_entries};
- /* MIMETypes section */
- /*+ The default MIME type. +*/
- static char *DefaultMIMEType; /* see SetDefaultValues() */
- /*+ The list of MIME types. +*/
- static KeyPair **MIMETypes; /* see SetDefaultValues() */
- /*+ The entries in the FTPOptions section. +*/
- static Entry mimetypes_entries[]={{"default",(void*)&DefaultMIMEType,0,Fixed ,MIMEType},
- {"" ,(void*)&MIMETypes ,1,FileExt,MIMEType},
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The MIMETypes section. +*/
- static Section mimetypes_section={"MIMETypes",mimetypes_entries};
- /* Proxy section */
- /*+ The list of hostnames and proxies. +*/
- static KeyPair **Proxies; /* see SetDefaultValues() */
- /*+ The information that is needed to allow authorisation headers to be added, +*/
- static KeyPair **ProxyAuthHost, /*+ hostname +*/ /* see SetDefaultValues() */
- **ProxyAuthUser, /*+ username +*/ /* see SetDefaultValues() */
- **ProxyAuthPass; /*+ password +*/ /* see SetDefaultValues() */
- /*+ The SSL proxy to use. +*/
- char *SSLProxy; /* see SetDefaultValues() */
- /*+ The entries in the Proxy section. +*/
- static Entry proxy_entries[]={{"auth-hostname",(void*)&ProxyAuthHost,1,Fixed ,HostAndPort },
- {"auth-username",(void*)&ProxyAuthUser,1,Fixed ,String },
- {"auth-password",(void*)&ProxyAuthPass,1,Fixed ,String },
- {"ssl" ,(void*)&SSLProxy ,0,Fixed ,HostAndPortOrNone},
- {"" ,(void*)&Proxies ,1,UrlSpecification,HostAndPortOrNone},
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The Proxy section. +*/
- static Section proxy_section={"Proxy",proxy_entries};
- /* DontIndex section */
- /*+ The list of URLs not to index in the outgoing index. +*/
- static KeyPair **DontIndexOutgoing; /* see SetDefaultValues() */
- /*+ The list of URLs not to index in the latest/lastime/prevtime indexes. +*/
- static KeyPair **DontIndexLatest; /* see SetDefaultValues() */
- /*+ The list of URLs not to index in the monitor index. +*/
- static KeyPair **DontIndexMonitor; /* see SetDefaultValues() */
- /*+ The list of URLs not to index in the host indexes. +*/
- static KeyPair **DontIndexHost; /* see SetDefaultValues() */
- /*+ The list of URLs not to index. +*/
- static KeyPair **DontIndex; /* see SetDefaultValues() */
- /*+ The entries in the DontIndex section. +*/
- static Entry dontindex_entries[]={{"outgoing" ,(void*)&DontIndexOutgoing,1,Fixed ,UrlSpecification},
- {"latest" ,(void*)&DontIndexLatest ,1,Fixed ,UrlSpecification},
- {"monitor" ,(void*)&DontIndexMonitor ,1,Fixed ,UrlSpecification},
- {"host" ,(void*)&DontIndexHost ,1,Fixed ,UrlSpecification},
- {"" ,(void*)&DontIndex ,1,UrlSpecification,None },
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The DontIndex section. +*/
- static Section dontindex_section={"DontIndex",dontindex_entries};
- /* Alias section */
- /*+ The list of protocols/hostnames and their aliases. +*/
- static KeyPair **Aliases; /* see SetDefaultValues() */
- /*+ The entries in the Alias section. +*/
- static Entry alias_entries[]={{"" ,(void*)&Aliases,1,UrlSpecification,UrlSpecification},
- {NULL,NULL ,0,-1 ,-1 }};
- /*+ The Alias section. +*/
- static Section alias_section={"Alias",alias_entries};
- /* Purge section */
- /*+ A flag to indicate that the modification time is used instead of the access time. +*/
- int PurgeUseMTime; /* see SetDefaultValues() */
- /*+ The default age for purging files. +*/
- int DefaultPurgeAge; /* see SetDefaultValues() */
- /*+ The maximum allowed size of the cache. +*/
- int PurgeCacheSize; /* see SetDefaultValues() */
- /*+ The minimum allowed free disk space. +*/
- int PurgeDiskFree; /* see SetDefaultValues() */
- /*+ A flag to indicate it the whole URL is used to choose the purge age. +*/
- int PurgeUseURL; /* see SetDefaultValues() */
- /*+ A flag to indicate if the DontGet hosts are to be purged. +*/
- static int PurgeDontGet; /* see SetDefaultValues() */
- /*+ A flag to indicate if the DontCache hosts are to be purged. +*/
- static int PurgeDontCache; /* see SetDefaultValues() */
- /*+ The list of hostnames and purge ages. +*/
- static KeyPair **PurgeAges; /* see SetDefaultValues() */
- /*+ The entries in the Purge section. +*/
- static Entry purge_entries[]={{"use-mtime" ,(void*)&PurgeUseMTime ,0,Fixed ,Boolean },
- {"default" ,(void*)&DefaultPurgeAge,0,Fixed ,AgeDays },
- {"max-size" ,(void*)&PurgeCacheSize ,0,Fixed ,CacheSize},
- {"min-free" ,(void*)&PurgeDiskFree ,0,Fixed ,CacheSize},
- {"use-url" ,(void*)&PurgeUseURL ,0,Fixed ,Boolean },
- {"del-dontget" ,(void*)&PurgeDontGet ,0,Fixed ,Boolean },
- {"del-dontcache" ,(void*)&PurgeDontCache ,0,Fixed ,Boolean },
- {"" ,(void*)&PurgeAges ,1,UrlSpecification,AgeDays },
- {NULL ,NULL ,0,-1 ,-1 }};
- /*+ The Purge section. +*/
- static Section purge_section={"Purge",purge_entries};
- /* All sections */
- /*+ The list of sections (NULL terminated). +*/
- static Section *sections[]={&startup_section,
- &options_section,
- &fetchoptions_section,
- &modifyhtml_section,
- &localhost_section,
- &localnet_section,
- &allowedconnecthosts_section,
- &allowedconnectusers_section,
- &dontcache_section,
- &dontget_section,
- &dontgetrecursive_section,
- &dontrequestoffline_section,
- &censorheader_section,
- &ftpoptions_section,
- &mimetypes_section,
- &proxy_section,
- &dontindex_section,
- &alias_section,
- &purge_section,
- NULL};
- /* Local functions */
- static int match_url_specification(UrlSpec *spec,char *proto,char *host,char *path,char *args);
- static int wildcard_match(char *string,char *pattern);
- static char *DefaultFTPPassWord(void);
- static KeyPair **DefaultAliasLinks(void);
- static void ReadFile(FILE *config);
- static void ReadSection(FILE *config,Section *section);
- static char* ReadLine(FILE *config);
- static int ParseEntry(Entry *entry,char *left,char *right);
- static int ParseValue(char *text,ConfigType type,void *pointer,int rhs);
- static int isanumber(const char *string);
- static void SetDefaultValues(void);
- static void SaveOldValues(void);
- static void RestoreOldValues(void);
- static void RemoveOldValues(void);
- static void FreeKeyPairList(KeyPair **list,int freewhat);
- #define FREE_KEY_STRING 1
- #define FREE_KEY_URLSPEC 2
- #define FREE_VALUE_STRING 4
- #define FREE_VALUE_URLSPEC 8
- /*+ Only the first time that the config file is read can the StartUp section be used. +*/
- static int first_time=1;
- /*+ The error message. +*/
- static char *errmsg;
- /*+ The line number in the configuration file. +*/
- static int line_no;
- /*+ The name of the configuration file. +*/
- char *file_name;
- /*++++++++++++++++++++++++++++++++++++++
- Read in the configuration file.
- int fd The file descriptor to write the error message to.
- ++++++++++++++++++++++++++++++++++++++*/
- int ReadConfigFile(int fd)
- {
- FILE* config;
- if(first_time)
- SetDefaultValues();
- errmsg=NULL;
- if(*ConfigFile!='/')
- {
- static char cwd[PATH_MAX+1];
- if(getcwd(cwd,PATH_MAX))
- {
- strcat(cwd,"/");
- strcat(cwd,ConfigFile);
- ConfigFile=cwd;
- }
- }
- config=fopen(ConfigFile,"r");
- if(!config)
- {
- write_formatted(fd,"Cannot open the configuration file '%s'n",ConfigFile);
- return(1);
- }
- SaveOldValues();
- SetDefaultValues();
- ReadFile(config);
- if(errmsg)
- RestoreOldValues();
- else
- RemoveOldValues();
- fclose(config);
- if(errmsg)
- {
- write_formatted(fd,"Syntax error at line %d in '%s'; %sn",line_no,file_name,errmsg);
- free(errmsg);
- }
- if(first_time)
- first_time=0;
- if(errmsg)
- return(1);
- else
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Decide if the specified host and port number is allowed for SSL.
- int IsSSLAllowedPort Returns true if it is allowed.
- char *host The hostname and port number to check.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsSSLAllowedPort(char *host)
- {
- KeyPair **p;
- char *colon=strchr(host,':');
- int port,isit=0;
- if(!colon)
- return(0);
- port=atoi(colon+1);
- if(SSLAllowPort)
- for(p=SSLAllowPort;(*p)!=&KeyPairEnd;p++)
- if((*p)->value.integer==port)
- {isit=1;break;}
- return(isit);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Get the first specified name of the server host.
- char *GetLocalHost Returns the first named localhost.
- int port If true then return the port as well.
- ++++++++++++++++++++++++++++++++++++++*/
- char *GetLocalHost(int port)
- {
- char *localhost,*ret;
- if(LocalHost)
- localhost=(*LocalHost)->key.string;
- else
- localhost="localhost";
- ret=(char*)malloc(strlen(localhost)+8);
- if(port)
- sprintf(ret,"%s:%d",localhost,HTTP_Port);
- else
- strcpy(ret,localhost);
- return(ret);
- }
- #if !defined(SETUP_ONLY)
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified hostname is the localhost.
- int IsLocalHost Return true if the host is the local host.
- char *host The name of the host (and port number) to be checked.
- int port If true then check the port number as well.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsLocalHost(char *host,int port)
- {
- KeyPair **p;
- char *colon=strchr(host,':');
- int isit=0;
- if(colon)
- *colon=0;
- if(LocalHost)
- for(p=LocalHost;(*p)!=&KeyPairEnd;p++)
- if(!strcmp((*p)->key.string,host))
- {isit=1;break;}
- if(colon)
- *colon=':';
- if(isit && port)
- {
- if((colon && atoi(colon+1)==HTTP_Port) ||
- (!colon && HTTP_Port==80))
- ;
- else
- isit=0;
- }
- return(isit);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified hostname is in the local network.
- int IsLocalNetHost Return true if the host is on the local network.
- char *host The name of the host (and port number) to be checked.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsLocalNetHost(char *host)
- {
- KeyPair **p;
- char *colon=strchr(host,':');
- int isit=0;
- if(colon)
- *colon=0;
- if(IsLocalHost(host,0))
- isit=1;
- if(LocalNet && !isit)
- for(p=LocalNet;(*p)!=&KeyPairEnd;p++)
- if(*(*p)->key.string=='!')
- {
- if(wildcard_match(host,(*p)->key.string+1))
- {isit=0;break;}
- }
- else if(wildcard_match(host,(*p)->key.string))
- {isit=1;break;}
- if(colon)
- *colon=':';
- return(isit);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified hostname is allowed to connect.
- int IsAllowedConnectHost Return true if it is allowed to connect.
- char *host The name of the host to be checked.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsAllowedConnectHost(char *host)
- {
- KeyPair **p;
- int isit=0;
- if(LocalHost)
- for(p=LocalHost;(*p)!=&KeyPairEnd;p++)
- if(!strcmp((*p)->key.string,host))
- {isit=1;break;}
- if(AllowedConnectHosts && !isit)
- for(p=AllowedConnectHosts;(*p)!=&KeyPairEnd;p++)
- if(*(*p)->key.string=='!')
- {
- if(wildcard_match(host,(*p)->key.string+1))
- {isit=0;break;}
- }
- else if(wildcard_match(host,(*p)->key.string))
- {isit=1;break;}
- return(isit);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified username and password is allowed to connect.
- char *IsAllowedConnectUser Return the username if it is allowed to connect.
- char *userpass The encoded username and password of the user to be checked.
- ++++++++++++++++++++++++++++++++++++++*/
- char *IsAllowedConnectUser(char *userpass)
- {
- KeyPair **p;
- char *isit;
- if(AllowedConnectUsers)
- isit=NULL;
- else
- isit="anybody";
- if(AllowedConnectUsers && userpass)
- {
- char *up=userpass;
- while(*up!=' ') up++;
- while(*up==' ') up++;
- for(p=AllowedConnectUsers;(*p)!=&KeyPairEnd;p++)
- if(!strcmp((*p)->key.string,up))
- {
- char *colon;
- int l;
- isit=Base64Decode((*p)->key.string,&l);
- colon=strchr(isit,':');
- *colon=0;
- break;
- }
- }
- return(isit);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified URL is to be cached.
- int IsNotCached Return true if it is not to be cached.
- char *proto The name of the protocol to check.
- char *host The name of the host to check.
- char *path The pathname of the URL to check.
- char *args The arguments of the URL to check.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsNotCached(char *proto,char *host,char *path,char *args)
- {
- KeyPair **p;
- if(DontCache)
- for(p=DontCache;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->key.urlspec,proto,host,path,args);
- if(match)
- return(!(*p)->key.urlspec->negated);
- }
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified URL is to be got.
- int IsNotGot Return true if it is not to be got.
- char *proto The name of the protocol to check.
- char *host The name of the host to check.
- char *path The pathname of the URL to check.
- char *args The arguments of the URL to check.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsNotGot(char *proto,char *host,char *path,char *args)
- {
- KeyPair **p;
- if(DontGet)
- for(p=DontGet;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->key.urlspec,proto,host,path,args);
- if(match)
- return(!(*p)->key.urlspec->negated);
- }
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Get the replacement URL for an URL that is not to be got.
- int NotGotReplacement Returns the URL if a specific one is specified or the default one.
- char *proto The name of the protocol to check.
- char *host The name of the host to check.
- char *path The pathname of the URL to check.
- char *args The arguments of the URL to check.
- ++++++++++++++++++++++++++++++++++++++*/
- char *NotGotReplacement(char *proto,char *host,char *path,char *args)
- {
- KeyPair **p;
- if(DontGet)
- for(p=DontGet;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->key.urlspec,proto,host,path,args);
- if(match && !(*p)->key.urlspec->negated && (*p)->value.string)
- return((*p)->value.string);
- }
- return(DontGetReplacementURL);
- }
-
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified URL is to be got recursively.
- int IsNotGotRecursive Return true if it is not to be got recursively.
- char *proto The name of the protocol to check.
- char *host The name of the host to check.
- char *path The pathname of the URL to check.
- char *args The arguments of the URL to check.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsNotGotRecursive(char *proto,char *host,char *path,char *args)
- {
- KeyPair **p;
- if(DontGetRecursive)
- for(p=DontGetRecursive;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->key.urlspec,proto,host,path,args);
- if(match)
- return(!(*p)->key.urlspec->negated);
- }
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified URL is to be requested while offline.
- int IsNotRequestedOffline Return true if it is not to be requested.
- char *proto The name of the protocol to check.
- char *host The name of the host to check.
- char *path The pathname of the URL to check.
- char *args The arguments of the URL to check.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsNotRequestedOffline(char *proto,char *host,char *path,char *args)
- {
- KeyPair **p;
- if(DontRequestOffline)
- for(p=DontRequestOffline;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->key.urlspec,proto,host,path,args);
- if(match)
- return(!(*p)->key.urlspec->negated);
- }
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Decide if the header line is to be sent to the server/browser.
- char *CensoredHeader Returns the value to be inserted or NULL if it is to be removed.
- char *url the URL that is being requested, or NULL for a reply.
- char *key The key to check.
- char *val The default value to use.
- ++++++++++++++++++++++++++++++++++++++*/
- char *CensoredHeader(char *url,char *key,char *val)
- {
- KeyPair **p;
- char *new=val;
- if(CensorHeader)
- for(p=CensorHeader;(*p)!=&KeyPairEnd;p++)
- if(!strcmp((*p)->key.string,key))
- {
- if(!(*p)->value.string)
- new=NULL;
- else if(strcmp((*p)->value.string,val))
- {
- new=(char*)malloc(strlen((*p)->value.string)+1);
- strcpy(new,(*p)->value.string);
- }
- break;
- }
- if(url && new && (RefererSelf || RefererSelfDir) && !strcmp("Referer",key))
- {
- new=(char*)malloc(strlen(url)+1);
- strcpy(new,url);
- if(RefererSelfDir)
- {
- char *p=new+strlen(new)-1,*ques=strchr(new,'?');
- if(ques)
- p=ques;
- while(*p!='/')
- *p--=0;
- }
- }
- return(new);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Determine an email address to use as the FTP password.
- char *DefaultFTPPassword Returns a best-guess password.
- ++++++++++++++++++++++++++++++++++++++*/
- static char *DefaultFTPPassWord(void)
- {
- struct passwd *pwd;
- char *username,*fqdn,*password;
- pwd=getpwuid(getuid());
- if(!pwd)
- username="root";
- else
- username=pwd->pw_name;
- fqdn=GetFQDN();
- if(!fqdn)
- fqdn="";
- password=(char*)malloc(strlen(username)+strlen(fqdn)+4);
- sprintf(password,"%s@%s",username,fqdn);
- return(password);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Determine what username and password to use for the FTP server.
- int WhatFTPUserPass Return 1 if there is a non-default one.
- char *host The FTP server.
- char **user Returns the username.
- char **pass Returns the password.
- ++++++++++++++++++++++++++++++++++++++*/
- int WhatFTPUserPass(char *host,char **user,char **pass)
- {
- int def=0;
- KeyPair **h,**u,**p;
- *user=FTPUserName;
- *pass=FTPPassWord;
- if(FTPAuthHost && FTPAuthUser && FTPAuthPass)
- for(h=FTPAuthHost,u=FTPAuthUser,p=FTPAuthPass;(*h)!=&KeyPairEnd && (*u)!=&KeyPairEnd && (*p)!=&KeyPairEnd;h++,u++,p++)
- {
- if(!strcmp(host,(*h)->value.string))
- {
- *user=(*u)->value.string;
- *pass=(*p)->value.string;
- def=1;
- break;
- }
- }
- return(def);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Decide what mime type to apply for a given file.
- char *WhatMIMEType Returns the MIME Type.
- char *path The path of the file.
- ++++++++++++++++++++++++++++++++++++++*/
- char *WhatMIMEType(char *path)
- {
- char *mimetype=DefaultMIMEType;
- int maxlen=0;
- KeyPair **m;
- if(MIMETypes)
- for(m=MIMETypes;(*m)!=&KeyPairEnd;m++)
- if(strlen(path)>strlen((*m)->key.string) &&
- strlen((*m)->key.string)>maxlen &&
- !strcmp((*m)->key.string,path+strlen(path)-strlen((*m)->key.string)))
- {mimetype=(*m)->value.string;maxlen=strlen((*m)->value.string);}
- return(mimetype);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Determine the proxy to use for a specified host.
- char *WhichProxy Return a pointer to the proxy.
- char *proto The name of the protocol used.
- char *host The name of the host to be contacted.
- ++++++++++++++++++++++++++++++++++++++*/
- char *WhichProxy(char *proto,char *host)
- {
- KeyPair **p;
- char *proxy=NULL;
- int matchlen=0,ml;
- if(Proxies)
- for(p=Proxies;(*p)!=&KeyPairEnd;p++)
- if((ml=match_url_specification((*p)->key.urlspec,proto,host,"/",NULL)))
- if(ml>matchlen)
- {
- matchlen=ml;
- proxy=(*p)->value.string;
- }
- return(proxy);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Determine what authentication password is required for the proxy.
- char *WhatProxyAuth Returns the password:username combination.
- char *proxy The name of the proxy.
- ++++++++++++++++++++++++++++++++++++++*/
- char *WhatProxyAuth(char *proxy)
- {
- KeyPair **h,**u,**p;
- char *user=NULL,*pass=NULL;
- char *userpass=NULL;
- if(ProxyAuthHost && ProxyAuthUser && ProxyAuthPass)
- {
- for(h=ProxyAuthHost,u=ProxyAuthUser,p=ProxyAuthPass;(*h)!=&KeyPairEnd && (*u)!=&KeyPairEnd && (*p)!=&KeyPairEnd;h++,u++,p++)
- {
- if(!strcmp(proxy,(*h)->value.string))
- {
- user=(*u)->value.string;
- pass=(*p)->value.string;
- break;
- }
- }
- if(user)
- {
- userpass=(char*)malloc(strlen(user)+strlen(pass)+2);
- strcpy(userpass,user);
- strcat(userpass,":");
- strcat(userpass,pass);
- }
- }
- return(userpass);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if the specified URL is to be indexed.
- int IsNotIndexed Return true if it is not to be indexed.
- URL *Url The URL to check.
- char *index The type of index that is being checked.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsNotIndexed(URL *Url,char *index)
- {
- KeyPair **p;
- KeyPair **special=NULL;
- if(DontIndexOutgoing && !strcmp(index,"outgoing"))
- special=DontIndexOutgoing;
- else if(DontIndexLatest && !strcmp(index,"latest"))
- special=DontIndexLatest;
- else if(DontIndexMonitor && !strcmp(index,"monitor"))
- special=DontIndexMonitor;
- else if(DontIndexHost && !strcmp(index,"host"))
- special=DontIndexHost;
- if(special)
- for(p=special;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->value.urlspec,Url->proto,Url->host,Url->path,Url->args);
- if(match)
- return(!(*p)->value.urlspec->negated);
- }
- if(DontIndex)
- for(p=DontIndex;(*p)!=&KeyPairEnd;p++)
- {
- int match=match_url_specification((*p)->key.urlspec,Url->proto,Url->host,Url->path,Url->args);
- if(match)
- return(!(*p)->key.urlspec->negated);
- }
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if a specified protocol and host is aliased to another host.
- int IsAliased Returns non-zero if this is host is aliased to another host.
- char *proto The protocol to check.
- char *host The hostname to check.
- char *path The pathname to check.
- char **new_proto The protocol of the alias.
- char **new_host The hostname of the alias.
- char **new_path The pathname of the alias.
- ++++++++++++++++++++++++++++++++++++++*/
- int IsAliased(char *proto,char *host,char *path,char **new_proto,char **new_host,char **new_path)
- {
- KeyPair **a;
- *new_proto=*new_host=*new_path=NULL;
- if(Aliases)
- for(a=Aliases;(*a)!=&KeyPairEnd;a++)
- if(match_url_specification((*a)->key.urlspec,proto,host,path,NULL))
- {
- if((*a)->value.urlspec->proto)
- {
- *new_proto=(char*)malloc(strlen((*a)->value.urlspec->proto)+1);
- strcpy(*new_proto,(*a)->value.urlspec->proto);
- }
- else
- {
- *new_proto=(char*)malloc(strlen(proto)+1);
- strcpy(*new_proto,proto);
- }
- if((*a)->value.urlspec->host)
- {
- *new_host=(char*)malloc(strlen((*a)->value.urlspec->host)+8);
- strcpy(*new_host,(*a)->value.urlspec->host);
- if((*a)->value.urlspec->port>0)
- sprintf((*new_host)+strlen(*new_host),":%d",(*a)->value.urlspec->port);
- }
- else
- {
- *new_host=(char*)malloc(strlen(host)+1);
- strcpy(*new_host,host);
- }
- if((*a)->value.urlspec->path)
- {
- int oldlen=(*a)->key.urlspec->path?strlen((*a)->key.urlspec->path):0;
- int newlen=(*a)->value.urlspec->path?strlen((*a)->value.urlspec->path):0;
- *new_path=(char*)malloc(newlen-oldlen+strlen(path)+1);
- if(newlen)
- {
- strcpy(*new_path,(*a)->value.urlspec->path);
- if((*new_path)[newlen-1]=='/')
- (*new_path)[newlen-1]=0;
- }
- strcat(*new_path,path+oldlen);
- }
- else
- {
- *new_path=(char*)malloc(strlen(path)+1);
- strcpy(*new_path,path);
- }
- }
- return(!!*new_proto);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Search through the cache for the symbolic links that are also alias entries.
- KeyPair **DefaultAliasLinks Return the list of links.
- ++++++++++++++++++++++++++++++++++++++*/
- static KeyPair **DefaultAliasLinks(void)
- {
- KeyPair **links=NULL;
- int p;
- for(p=0;p<NProtocols;p++)
- {
- struct stat buf;
- if(!lstat(Protocols[p].name,&buf) && S_ISDIR(buf.st_mode))
- {
- DIR *dir2;
- struct dirent* ent2;
- if(chdir(Protocols[p].name))
- {PrintMessage(Warning,"Cannot change to directory '%s' [%!s]; no aliases.",Protocols[p].name);continue;}
- /* Open the spool directory. */
- dir2=opendir(".");
- if(!dir2)
- {PrintMessage(Warning,"Cannot open directory '%s' [%!s]; no aliases.",Protocols[p].name);chdir("..");continue;}
- ent2=readdir(dir2); /* skip . */
- if(!ent2)
- {PrintMessage(Warning,"Cannot read directory '%s' [%!s]; no aliases.",Protocols[p].name);closedir(dir2);chdir("..");continue;}
- ent2=readdir(dir2); /* skip .. */
- /* Search for all of the symbolic links. */
- while((ent2=readdir(dir2)))
- {
- struct stat buf2;
- char *host=ent2->d_name;
- if(!lstat(host,&buf2) && S_ISLNK(buf2.st_mode))
- PrintMessage(Warning,"Symbolic links (like '%s/%s') are obsoleted by the 'Alias' configuration file section.n",Protocols[p].name,ent2->d_name);
- }
- closedir(dir2);
- chdir("..");
- }
- }
- return(links);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Determine the age to use when purging for a specified URL.
- int WhatPurgeAge Return the age in days.
- char *proto The name of the protocol used.
- char *host The name of the host to be purged.
- char *path The pathname of the URL to be purged.
- char *args The arguments of the URL to be purged.
- ++++++++++++++++++++++++++++++++++++++*/
- int WhatPurgeAge(char *proto,char *host,char *path,char *args)
- {
- KeyPair **p;
- int age=DefaultPurgeAge;
- int matchlen=0,ml;
- if(PurgeAges)
- for(p=PurgeAges;(*p)!=&KeyPairEnd;p++)
- if((ml=match_url_specification((*p)->key.urlspec,proto,host,path,args)))
- if(ml>matchlen)
- {
- matchlen=ml;
- age=(*p)->value.integer;
- }
- if(PurgeDontGet && IsNotGot(proto,host,path,args))
- age=0;
- if(PurgeDontCache && (IsNotCached(proto,host,path,args) || IsLocalNetHost(host)))
- age=0;
- return(age);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Check if a protocol, host and path match a URL-SPECIFICATION in the config file.
- int match_url_specification Return the matching length if true else 0.
- UrlSpec *spec The URL-SPECIFICATION.
- char *proto The protocol.
- char *host The host.
- char *path The path.
- char *args The arguments.
- ++++++++++++++++++++++++++++++++++++++*/
- static int match_url_specification(UrlSpec *spec,char *proto,char *host,char *path,char *args)
- {
- int match=0;
- char *colon=strchr(host,':');
- if(colon)
- *colon=0;
- if((!spec->proto || !strcmp(spec->proto,proto)) &&
- (!spec->host || wildcard_match(host,spec->host)) &&
- (spec->port==-1 || (!colon && spec->port==0) || (colon && atoi(colon+1)==spec->port)) &&
- (!spec->path || wildcard_match(path,spec->path)) &&
- (!spec->args || (args && wildcard_match(args,spec->args)) || (!args && *spec->args==0)))
- {
- match=(spec->proto?strlen(spec->proto):0)+
- (spec->host?strlen(spec->host):0)+
- (spec->path?strlen(spec->path):0)+
- (spec->args?strlen(spec->args):0)+1;
- }
- if(colon)
- *colon=':';
- return(match);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Do a match using a wildcard specified with '*' in it.
- int wildcard_match returns 1 if there is a match.
- char *string The fixed string that is being matched.
- char *pattern The pattern to match against.
- ++++++++++++++++++++++++++++++++++++++*/
- static int wildcard_match(char *string,char *pattern)
- {
- int i,nstars=0;
- for(i=0;pattern[i];i++)
- if(pattern[i]=='*')
- nstars++;
- if(nstars)
- {
- int len_pat=strlen(pattern);
- int len_str=strlen(string);
- if((len_pat-nstars)>len_str)
- {
- if(!strcmp(string,"/") && !strcmp(pattern,"/*/"))
- return(1);
- else
- return(0);
- }
- else
- {
- char *str_beg=NULL,*str_mid=NULL,*str_end=NULL;
- int len_beg=0,len_mid=0,len_end=0;
- /* Look for a star at the start. */
- if(pattern[0]!='*')
- {
- str_beg=pattern;
- while(pattern[len_beg]!='*')
- len_beg++;
- if(len_beg>len_str || strncmp(str_beg,string,len_beg))
- return(0);
- }
- /* Look for a star at the end. */
- if(pattern[strlen(pattern)-1]!='*')
- {
- str_end=pattern+len_pat-2;
- while(*str_end!='*')
- str_end--;
- str_end++;
- len_end=pattern+len_pat-str_end;
- if(len_end>len_str || strncmp(str_end,string+len_str-len_end,len_end))
- return(0);
- }
- /* Check the rest. */
- if(nstars==1)
- return(1);
- else if(nstars==2)
- {
- char *copy=malloc(len_pat+1),*p;
- strcpy(copy,pattern);
- copy[len_beg]=0;
- copy[len_pat-1-len_end]=0;
- str_mid=copy+len_beg+1;
- len_mid=len_pat-len_beg-len_end-2;
- if((p=strstr(string+len_beg,str_mid)) && (p+len_mid)<=(string+len_str-len_end))
- {free(copy);return(1);}
- else
- {free(copy);return(0);}
- }
- else
- return(0);
- }
- }
- return(!strcmp(string,pattern));
- }
- #endif /* !defined(STARTUP_ONLY) */
- /*++++++++++++++++++++++++++++++++++++++
- Read the data from the file.
- FILE *config The file to read from.
- ++++++++++++++++++++++++++++++++++++++*/
- static void ReadFile(FILE *config)
- {
- char *line;
- line_no=0;
- file_name=ConfigFile;
- while((line=ReadLine(config)))
- {
- int i;
- for(i=0;sections[i];i++)
- if(!strcmp(sections[i]->name,line))
- break;
- if(!sections[i])
- {errmsg=(char*)malloc(48+strlen(line));sprintf(errmsg,"Unrecognised section label '%s'.",line);return;}
- if(!(line=ReadLine(config)))
- {errmsg=(char*)malloc(32);strcpy(errmsg,"Unexpected end of file.");return;}
- if(*line!='{' && *line!='[')
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Start of section must be '{' or '['.");return;}
- if(*(line+1))
- {*(line+1)=0;errmsg=(char*)malloc(48);sprintf(errmsg,"Start of section '%c' has trailing junk.",*line);return;}
- if(!first_time && sections[i]==*sections)
- {
- while((line=ReadLine(config)))
- if(*line=='}' || *line==']')
- break;
- }
- else if(*line=='{')
- {
- ReadSection(config,sections[i]);
- }
- else if(*line=='[')
- {
- int save_line_no;
- char *name,*r;
- FILE *file;
- if(!(line=ReadLine(config)))
- {errmsg=(char*)malloc(32);strcpy(errmsg,"Unexpected end of file.");return;}
- name=(char*)malloc(strlen(ConfigFile)+strlen(line)+1);
- strcpy(name,ConfigFile);
- r=name+strlen(name)-1;
- while(r>name && *r!='/')
- r--;
- strcpy(r+1,line);
- if(!(file=fopen(name,"r")))
- {errmsg=(char*)malloc(32+strlen(name));sprintf(errmsg,"Cannot open included file '%s.",name);return;}
- save_line_no=line_no;
- file_name=name;
- ReadSection(file,sections[i]);
- line_no=save_line_no;
- file_name=ConfigFile;
- fclose(file);
- if(!(line=ReadLine(config)))
- {errmsg=(char*)malloc(32);strcpy(errmsg,"Unexpected end of file.");return;}
- if(*line!=']')
- {errmsg=(char*)malloc(48);strcpy(errmsg,"End of section must be '}' or ']'.");return;}
- }
- if(errmsg)
- return;
- #if defined(STARTUP_ONLY)
- if(sections[i]==*sections)
- break;
- #endif
- }
- }
- /*++++++++++++++++++++++++++++++++++++++
- Read all the data from a section.
- FILE *config The file to read from.
- Section *section The section to read.
- ++++++++++++++++++++++++++++++++++++++*/
- static void ReadSection(FILE *config,Section *section)
- {
- char *line;
- while((line=ReadLine(config)))
- {
- if(*line=='}' || *line==']')
- {
- if(*(line+1))
- {*(line+1)=0;errmsg=(char*)malloc(48);sprintf(errmsg,"End of section '%c' has trailing junk.",*line);return;}
- return;
- }
- else
- {
- int i;
- char *l=line,*r=NULL;
- for(i=0;section->entries[i].name;i++)
- if(!*section->entries[i].name || !strncmp(section->entries[i].name,l,strlen(section->entries[i].name)))
- {
- char *ll;
- if(*section->entries[i].name)
- {
- ll=l+strlen(section->entries[i].name);
- if(*ll && *ll!='=' && !isspace(*ll))
- continue;
- }
- else
- {
- ll=l;
- while(*ll && *ll!='=' && !isspace(*ll))
- ll++;
- }
- if(section->entries[i].right_type==None ||
- (section->entries[i].right_type==OptionalUrl && !strchr(line, '=')))
- {
- *ll=0;
- r=NULL;
- }
- else
- {
- r=strchr(line,'=');
- if(!r)
- {errmsg=(char*)malloc(32);strcpy(errmsg,"No equal sign for entry.");return;}
- *ll=0;
- if(!*l)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Nothing to the left of the equal sign.");return;}
- r++;
- while(isspace(*r))
- r++;
- }
- break;
- }
- if(!section->entries[i].name)
- {errmsg=(char*)malloc(32+strlen(l));sprintf(errmsg,"Unrecognised entry label '%s'.",l);return;}
- if(ParseEntry(§ion->entries[i],l,r))
- return;
- }
- }
- }
- /*++++++++++++++++++++++++++++++++++++++
- Read a line from the configuration file, skipping over comments and blank lines.
- char *ReadLine Returns a pointer to the first thing in the line.
- FILE *config The file to read from.
- ++++++++++++++++++++++++++++++++++++++*/
- static char *ReadLine(FILE *config)
- {
- static char *line=NULL;
- char *l=NULL,*r;
- while((line=fgets_realloc(line,config)))
- {
- l=line;
- r=line+strlen(line)-1;
- line_no++;
- while(isspace(*l))
- l++;
- if(!*l || *l=='#')
- continue;
- while(r>l && isspace(*r))
- *r--=0;
- break;
- }
- if(!line)
- l=NULL;
- return(l);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Parse an entry from the file.
- int ParseEntry Return 1 in case of error.
- Entry *entries The list of matching entry in the section.
- char *left The string to the left of the equals sign.
- char *right The string to the right of the equals sign.
- ++++++++++++++++++++++++++++++++++++++*/
- static int ParseEntry(Entry *entry,char *left,char *right)
- {
- if(entry->list)
- {
- KeyPair **p,*new=(KeyPair*)malloc(sizeof(KeyPair));
- int i;
- if(entry->left_type==Fixed)
- new->key.string=entry->name;
- else
- if(ParseValue(left,entry->left_type,(void*)&new->key,0))
- {free(new);return(1);}
- if(entry->right_type==None || !right)
- new->value.string=NULL;
- else
- if(ParseValue(right,entry->right_type,(void*)&new->value,1))
- {free(new);return(1);}
- if(!*(KeyPair***)entry->pointer)
- {
- *(KeyPair***)entry->pointer=(KeyPair**)malloc(8*sizeof(KeyPair*));
- **(KeyPair***)entry->pointer=&KeyPairEnd;
- }
- p=*(KeyPair***)entry->pointer;
- for(i=0;(*p)!=&KeyPairEnd;p++,i++);
- if(i%8==7)
- *(KeyPair***)entry->pointer=(KeyPair**)realloc(*(void**)entry->pointer,(i+9)*sizeof(KeyPair*));
- for(p=*(KeyPair***)entry->pointer;(*p)!=&KeyPairEnd;p++);
- *p=new;
- p++;
- *p=&KeyPairEnd;
- }
- else
- if(ParseValue(right,entry->right_type,entry->pointer,1))
- return(1);
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Parse the text and put a value into the location.
- int ParseValue Returns non-zero in case of error.
- char *text The text string to parse.
- ConfigType type The type we are looking for.
- void *pointer The location to store the key or value.
- int rhs Set to true if this is the right hand side.
- ++++++++++++++++++++++++++++++++++++++*/
- static int ParseValue(char *text,ConfigType type,void *pointer,int rhs)
- {
- #define INTEGER(pointer) (*((int*) pointer))
- #define MODE_T(pointer) (*((mode_t*) pointer))
- #define STRING(pointer) (*((char**) pointer))
- #define URLSPEC(pointer) (*((UrlSpec**)pointer))
- switch(type)
- {
- case Fixed:
- case None:
- break;
- case CfgMaxServers:
- if(!*text)
- {errmsg=(char*)malloc(56);strcpy(errmsg,"Expecting a maximum server count, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a maximum server count, got '%s'.",text);}
- else
- {
- INTEGER(pointer)=atoi(text);
- if(INTEGER(pointer)<=0 || INTEGER(pointer)>MAX_SERVERS)
- {errmsg=(char*)malloc(48);sprintf(errmsg,"Invalid maximum server count: %d.",INTEGER(pointer));}
- }
- break;
- case CfgMaxFetchServers:
- if(!*text)
- {errmsg=(char*)malloc(56);strcpy(errmsg,"Expecting a maximum fetch server count, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(56+strlen(text));sprintf(errmsg,"Expecting a maximum fetch server count, got '%s'.",text);}
- else
- {
- INTEGER(pointer)=atoi(text);
- if(INTEGER(pointer)<=0 || INTEGER(pointer)>MAX_FETCH_SERVERS)
- {errmsg=(char*)malloc(48);sprintf(errmsg,"Invalid maximum fetch server count: %d.",INTEGER(pointer));}
- }
- break;
- case CfgLogLevel:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a log level, got nothing.");}
- else if(strcasecmp(text,"debug")==0)
- INTEGER(pointer)=Debug;
- else if(strcasecmp(text,"info")==0)
- INTEGER(pointer)=Inform;
- else if(strcasecmp(text,"important")==0)
- INTEGER(pointer)=Important;
- else if(strcasecmp(text,"warning")==0)
- INTEGER(pointer)=Warning;
- else if(strcasecmp(text,"fatal")==0)
- INTEGER(pointer)=Fatal;
- else
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a log level, got '%s'.",text);}
- break;
- case Boolean:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a Boolean, got nothing.");}
- else if(!strcasecmp(text,"yes") || !strcasecmp(text,"true"))
- INTEGER(pointer)=1;
- else if(!strcasecmp(text,"no") || !strcasecmp(text,"false"))
- INTEGER(pointer)=0;
- else
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a Boolean, got '%s'.",text);}
- break;
- case PortNumber:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a port number, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting a port number, got '%s'.",text);}
- else
- {
- INTEGER(pointer)=atoi(text);
- if(INTEGER(pointer)<=0 || INTEGER(pointer)>65535)
- {errmsg=(char*)malloc(32);sprintf(errmsg,"Invalid port number %d.",INTEGER(pointer));}
- }
- break;
- case AgeDays:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting an age in days, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting an age in days, got '%s'.",text);}
- else
- INTEGER(pointer)=atoi(text);
- break;
- case TimeSecs:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a time in seconds, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting an time in seconds, got '%s'.",text);}
- else
- INTEGER(pointer)=atoi(text);
- break;
- case CacheSize:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a cache size in MB, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting a cache size in MB, got '%s'.",text);}
- else
- {
- INTEGER(pointer)=atoi(text);
- if(INTEGER(pointer)<0)
- {errmsg=(char*)malloc(48);sprintf(errmsg,"Invalid cache size %d.",INTEGER(pointer));}
- }
- break;
- case FileSize:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a file size in kB, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting a file size in kB, got '%s'.",text);}
- else
- {
- INTEGER(pointer)=atoi(text);
- if(INTEGER(pointer)<0)
- {errmsg=(char*)malloc(48);sprintf(errmsg,"Invalid file size %d.",INTEGER(pointer));}
- }
- break;
- case Percentage:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a percentage, got nothing.");}
- else if(!isanumber(text))
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting a percentage, got '%s'.",text);}
- else
- {
- INTEGER(pointer)=atoi(text);
- if(INTEGER(pointer)<0)
- {errmsg=(char*)malloc(48);sprintf(errmsg,"Invalid percentage %d.",INTEGER(pointer));}
- }
- break;
- case UserId:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a username or uid, got nothing.");}
- else
- {
- int uid;
- struct passwd *userInfo=getpwnam(text);
- if(userInfo)
- uid=userInfo->pw_uid;
- else
- {
- if(sscanf(text,"%d",&uid)!=1)
- {errmsg=(char*)malloc(32+strlen(text));sprintf(errmsg,"Invalid user %s.",text);}
- else if(!getpwuid(uid))
- {errmsg=(char*)malloc(32);sprintf(errmsg,"Unknown user id %d.",uid);}
- }
- INTEGER(pointer)=uid;
- }
- break;
- case GroupId:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a group name or gid, got nothing.");}
- else
- {
- int gid;
- struct group *groupInfo=getgrnam(text);
- if(groupInfo)
- gid=groupInfo->gr_gid;
- else
- {
- if(sscanf(text,"%d",&gid)!=1)
- {errmsg=(char*)malloc(32+strlen(text));sprintf(errmsg,"Invalid group %s.",text);}
- else if(!getgrgid(gid))
- {errmsg=(char*)malloc(32);sprintf(errmsg,"Unknown group id %d.",gid);}
- }
- INTEGER(pointer)=gid;
- }
- break;
- case String:
- if(!*text || !strcasecmp(text,"none"))
- STRING(pointer)=NULL;
- else
- {
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- strcpy(STRING(pointer),text);
- }
- break;
- case PathName:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a pathname, got nothing.");}
- else if(*text!='/')
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting an absolute pathname, got '%s'.",text);}
- else
- {
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- strcpy(STRING(pointer),text);
- }
- break;
- case FileExt:
- if(!*text)
- {errmsg=(char*)malloc(40);strcpy(errmsg,"Expecting a file extension, got nothing.");}
- else if(*text!='.')
- {errmsg=(char*)malloc(40+strlen(text));sprintf(errmsg,"Expecting a file extension, got '%s'.",text);}
- else
- {
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- strcpy(STRING(pointer),text);
- }
- break;
- case FileMode:
- if(!*text)
- {errmsg=(char*)malloc(40);strcpy(errmsg,"Expecting a file permissions mode, got nothing.");}
- else if(!isanumber(text) || *text!='0')
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a file permissions mode, got '%s'.",text);}
- else
- MODE_T(pointer)=strtol(text,NULL,8);
- break;
- case MIMEType:
- if(!*text)
- {errmsg=(char*)malloc(40);strcpy(errmsg,"Expecting a MIME Type, got nothing.");}
- else
- {
- char *slash=strchr(text,'/');
- if(!slash)
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a MIME Type/Subtype, got '%s'.",text);}
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- strcpy(STRING(pointer),text);
- }
- break;
- case Host:
- if(!*text)
- {errmsg=(char*)malloc(40);strcpy(errmsg,"Expecting a hostname, got nothing.");}
- else
- {
- char *colon=strchr(text,':'),*p;
- if(colon)
- {errmsg=(char*)malloc(56+strlen(text));sprintf(errmsg,"Expecting a hostname not a port number, got '%s'.",text);}
- else
- {
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- for(p=text;*p;p++)
- *p=tolower(*p);
- strcpy(STRING(pointer),text);
- }
- }
- break;
- case HostAndPortOrNone:
- if(rhs && (!*text || !strcasecmp(text,"none")))
- {
- STRING(pointer)=NULL;
- break;
- }
- /* fall through */
- case HostAndPort:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a hostname (and port), got nothing.");}
- else
- {
- char *colon=strchr(text,':'),*p;
- if(*text==':')
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a hostname before the ':', got '%s'.",text);}
- else
- {
- if(colon && (!isanumber(colon+1) || atoi(colon+1)<=0 || atoi(colon+1)>65535))
- {errmsg=(char*)malloc(32+strlen(colon));sprintf(errmsg,"Invalid port number %s.",colon+1);}
- else
- {
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- for(p=text;*p;p++)
- *p=tolower(*p);
- strcpy(STRING(pointer),text);
- }
- }
- }
- break;
- case UserPass:
- if(!*text)
- {errmsg=(char*)malloc(48);strcpy(errmsg,"Expecting a username and password, got nothing.");}
- else if(!strchr(text,':'))
- {errmsg=(char*)malloc(48+strlen(text));sprintf(errmsg,"Expecting a username and password, got '%s'.",text);}
- else
- STRING(pointer)=Base64Encode(text,strlen(text));
- break;
- case Url:
- case OptionalUrl:
- if(!*text || !strcasecmp(text,"none"))
- STRING(pointer)=NULL;
- else
- {
- URL *tempUrl=SplitURL(text);
- if(!tempUrl->Protocol)
- {errmsg=(char*)malloc(32+strlen(text));sprintf(errmsg,"Expecting a URL, got '%s'.",text);}
- else
- {
- STRING(pointer)=(char*)malloc(strlen(text)+1);
- strcpy(STRING(pointer),text);
- FreeURL(tempUrl);
- }
- }
- break;
- case UrlSpecification:
- if(!*text)
- {errmsg=(char*)malloc(64);strcpy(errmsg,"Expecting a URL-SPECIFICATION, got nothing.");}
- else
- {
- char *p,*orgtext=text;
- URLSPEC(pointer)=(UrlSpec*)malloc(sizeof(UrlSpec));
- URLSPEC(pointer)->negated=0;
- URLSPEC(pointer)->proto=NULL;
- URLSPEC(pointer)->host=NULL;
- URLSPEC(pointer)->port=-1;
- URLSPEC(pointer)->path=NULL;
- URLSPEC(pointer)->args=NULL;
- if(!strcmp("default",text))
- break;
- /* ! */
- if(*text=='!')
- {
- URLSPEC(pointer)->negated=1;
- text++;
- }
- /* protocol */
- if(!strncmp(text,"*://",4))
- {
- p=text+4;
- URLSPEC(pointer)->proto=NULL;
- }
- else if(!strncmp(text,"://",3))
- {
- p=text+3;
- URLSPEC(pointer)->proto=NULL;
- }
- else if((p=strstr(text,"://")))
- {
- URLSPEC(pointer)->proto=(char*)malloc(p-text+1);
- strncpy(URLSPEC(pointer)->proto,text,p-text);
- *(URLSPEC(pointer)->proto+(p-text))=0;
- p+=3;
- }
- else
- {errmsg=(char*)malloc(64+strlen(orgtext));sprintf(errmsg,"Expecting a URL-SPECIFICATION, got this '%s'.",orgtext); break;}
- if(URLSPEC(pointer)->proto)
- {
- char *q;
- for(q=URLSPEC(pointer)->proto;*q;q++)
- *q=tolower(*q);
- }
- text=p;
- /* host */
- if(*text=='*' && (*(text+1)=='/' || !*(text+1)))
- p=text+1;
- else if(*text==':')
- p=text;
- else if((p=strstr(text,":")))
- {
- URLSPEC(pointer)->host=(char*)malloc(p-text+1);
- strncpy(URLSPEC(pointer)->host,text,p-text);
- *(URLSPEC(pointer)->host+(p-text))=0;
- }
- else if((p=strstr(text,"/")))
- {
- URLSPEC(pointer)->host=(char*)malloc(p-text+1);
- strncpy(URLSPEC(pointer)->host,text,p-text);
- *(URLSPEC(pointer)->host+(p-text))=0;
- }
- else if(*text)
- {
- URLSPEC(pointer)->host=(char*)malloc(strlen(text)+1);
- strcpy(URLSPEC(pointer)->host,text);
- p=text+strlen(text);
- }
- else
- p=text;
- if(URLSPEC(pointer)->host)
- {
- char *q;
- for(q=URLSPEC(pointer)->host;*q;q++)
- *q=tolower(*q);
- }
- text=p;
- /* port */
- if(*text==':' && isdigit(*(text+1)))
- {
- URLSPEC(pointer)->port=atoi(text+1);
- p=text+1;
- while(isdigit(*p))
- p++;
- }
- else if(*text==':' && (*(text+1)=='/' || *(text+1)==0))
- {
- URLSPEC(pointer)->port=0;
- p=text+1;
- }
- else if(*text==':' && *(text+1)=='*')
- {
- p=text+2;
- }
- else if(*text==':')
- {errmsg=(char*)malloc(64+strlen(orgtext));sprintf(errmsg,"Expecting a URL-SPECIFICATION, got this '%s'.",orgtext); break;}
- text=p;
- /* path */
- if(!*text)
- ;
- else if(*text=='/' && !*(text+1))
- p=text+1;
- else if(*text=='?')
- ;
- else if(*text=='/' && (p=strchr(text,'?')))
- {
- URLSPEC(pointer)->path=(char*)malloc(p-text+1);
- strncpy(URLSPEC(pointer)->path,text,p-text);
- URLSPEC(pointer)->path[p-text]=0;
- }
- else if(*text=='/')
- {
- URLSPEC(pointer)->path=(char*)malloc(strlen(text)+1);
- strcpy(URLSPEC(pointer)->path,text);
- p=text+strlen(text);
- }
- else
- {errmsg=(char*)malloc(64+strlen(orgtext));sprintf(errmsg,"Expecting a URL-SPECIFICATION, got this '%s'.",orgtext); break;}
- text=p;
- /* args */
- if(!*text)
- ;
- else if(*text=='?' && !*(text+1))
- URLSPEC(pointer)->args="";
- else if(*text=='?')
- {
- URLSPEC(pointer)->args=(char*)malloc(strlen(text+1)+1);
- strcpy(URLSPEC(pointer)->args,text+1);
- }
- else
- {errmsg=(char*)malloc(64+strlen(orgtext));sprintf(errmsg,"Expecting a URL-SPECIFICATION, got this '%s'.",orgtext); break;}
- }
- break;
- }
- if(errmsg)
- return(1);
- else
- return(0);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Decide if a string is an integer.
- int isanumber Returns 1 if it is, 0 if not.
- const char *string The string that may be an integer.
- ++++++++++++++++++++++++++++++++++++++*/
- static int isanumber(const char *string)
- {
- int i=0;
- if(string[0]=='-' || string[i]=='+')
- i++;
- for(;string[i];i++)
- if(!isdigit(string[i]))
- return(0);
- return(1);
- }
- /*+ The old value of the level of error logging, see ErrorLevel in errors.h +*/
- static int old_LogLevel;
- /*+ The old value of the number of days to display in the index of the latest pages. +*/
- static int old_IndexLatestDays;
- /*+ The old value of the option to turn on the modifications in this section. +*/
- static int old_EnableHTMLModifications;
- /*+ The old value of the option of a tag that can be added to the bottom of the spooled pages with the date and some buttons. +*/
- static int old_AddCacheInfo;
- /*+ The old value of the options to modify the anchor tags in the HTML. +*/
- static char *old_AnchorModifyBegin[3],
- *old_AnchorModifyEnd[3];
- /*+ The old value of the option to disable scripts and scripted actions. +*/
- static int old_DisableHTMLScript;
- /*+ The old value of the option to disable the <blink> tag. +*/
- static int old_DisableHTMLBlink;
- /*+ The old value of the option to disable animated GIFs. +*/
- static int old_DisableAnimatedGIF;
- /*+ The old value of the maximum age of a cached page to use in preference while online. +*/
- static int old_RequestChanged;
- /*+ The old value of the option to only request changes to a page once per session online. +*/
- static int old_RequestChangedOnce;
- /*+ The old value of the option to re-request pages that have expired. +*/
- static int old_RequestExpired;
- /*+ The old value of the option to re-request pages that have the no-cache flag set. +*/
- static int old_RequestNoCache;
- /*+ The old value of the option to allow or ignore the 'Pragma: no-cache' request. +*/
- static int old_PragmaNoCache;
- /*+ The old value of the option to not automatically make requests while offline but to need confirmation. +*/
- static int old_ConfirmRequests;
- /*+ The old value of the amount of time that a socket connection will wait for data. +*/
- static int old_SocketTimeout;
- /*+ The old value of the amount of time that a socket will wait for the intial connection. +*/
- static int old_ConnectTimeout;
- /*+ The old value of the option to retry a failed connection. +*/
- static int old_ConnectRetry;
- /*+ The old value of the list of allowed SSL port numbers. +*/
- static KeyPair **old_SSLAllowPort;
- /*+ The old value of the option to disable the lasttime/prevtime indexs. +*/
- static int old_NoLasttimeIndex;
- /*+ The old value of the option to keep downloads that are interrupted by the user. +*/
- static int old_IntrDownloadKeep;
- /*+ The old value of the option to keep on downloading interrupted pages if +*/
- static int old_IntrDownloadSize; /*+ smaller than a given size. +*/
- static int old_IntrDownloadPercent; /*+ more than a given percentage complete. +*/
- /*+ The old value of the option to keep downloads that time out. +*/
- int old_TimeoutDownloadKeep;
- /*+ The old value of the option to also fetch style sheets. +*/
- static int old_FetchStyleSheets;
- /*+ The old value of the option to also fetch images. +*/
- static int old_FetchImages;
- /*+ The old value of the option to also fetch frames. +*/
- static int old_FetchFrames;
- /*+ The old value of the option to also fetch scripts. +*/
- static int old_FetchScripts;
- /*+ The old value of the option to also fetch objects. +*/
- static int old_FetchObjects;
- /*+ The old values of the list of localhost hostnames. +*/
- static KeyPair **old_LocalHost;
- /*+ The old value of the list of local network hostnames. +*/
- static KeyPair **old_LocalNet;
- /*+ The old values of the list of allowed hostnames. +*/
- static KeyPair **old_AllowedConnectHosts;
- /*+ The old values of the list of allowed usernames and passwords. +*/
- static KeyPair **old_AllowedConnectUsers;
- /*+ The old value of the list of URLs not to cache. +*/
- static KeyPair **old_DontCache;
- /*+ The old value of the list of URLs not to get. +*/
- static KeyPair **old_DontGet;
- /*+ The old value of the replacement URL. +*/
- static char *old_DontGetReplacementURL;
- /*+ The old value of the list of URLs not to get. +*/
- static KeyPair **old_DontGetRecursive;
- /*+ The old value of the list of URLs not to request when offline. +*/
- static KeyPair **old_DontRequestOffline;
- /*+ The old value of the list of censored headers. +*/
- static KeyPair **old_CensorHeader;
- /*+ The old value of the flags to cause the referer header to be mangled. +*/
- static int old_RefererSelf,
- old_RefererSelfDir;
- /*+ The old value of the anon-ftp username. +*/
- static char *old_FTPUserName;
- /*+ The old value of the anon-ftp password. +*/
- static char *old_FTPPassWord;
- /*+ The old value of the information that is needed to allow non-anonymous access, +*/
- static KeyPair **old_FTPAuthHost, /*+ hostname +*/
- **old_FTPAuthUser, /*+ username +*/
- **old_FTPAuthPass; /*+ password +*/
- /*+ The old value of the default MIME type. +*/
- static char *old_DefaultMIMEType;
- /*+ The old value of the list of MIME types. +*/
- static KeyPair **old_MIMETypes;
- /*+ The old value of the list of hostnames and proxies. +*/
- static KeyPair **old_Proxies;
- /*+ The old value of the information that is needed to allow authorisation headers to be added, +*/
- static KeyPair **old_ProxyAuthHost, /*+ hostname +*/
- **old_ProxyAuthUser, /*+ username +*/
- **old_ProxyAuthPass; /*+ password +*/
- /*+ The old value of the SSL proxy to use. +*/
- static char *old_SSLProxy;
- /*+ The old value of the list of URLs not to index in the outgoing index. +*/
- static KeyPair **old_DontIndexOutgoing;
- /*+ The old value of the list of URLs not to index in the latest/lastime/prevtime indexes. +*/
- static KeyPair **old_DontIndexLatest;
- /*+ The old value of the list of URLs not to index in the monitor index. +*/
- static KeyPair **old_DontIndexMonitor;
- /*+ The old value of the list of URLs not to index in the host indexes. +*/
- static KeyPair **old_DontIndexHost;
- /*+ The old value of the list of URLs not to index. +*/
- static KeyPair **old_DontIndex;
- /*+ The old value of the list of protocols/hostnames and their aliases. +*/
- static KeyPair **old_Aliases;
- /*+ The old value of the flag to indicate that the modification time is used instead of the access time. +*/
- static int old_PurgeUseMTime;
- /*+ The old value of the default age for purging files. +*/
- static int old_DefaultPurgeAge;
- /*+ The old value of the maximum allowed size of the cache. +*/
- static int old_PurgeCacheSize;
- /*+ The old value of the minimum allowed free disk space. +*/
- static int old_PurgeDiskFree;
- /*+ The old value of the flag to indicate it the whole URL is used to choose the purge age. +*/
- static int old_PurgeUseURL;
- /*+ The old value of the flag to indicate if the DontGet hosts are to be purged. +*/
- static int old_PurgeDontGet;
- /*+ The old value of the flag to indicate if the DontCache hosts are to be purged. +*/
- static int old_PurgeDontCache;
- /*+ The old value of the list of hostnames and purge ages. +*/
- static KeyPair **old_PurgeAges;
- /*++++++++++++++++++++++++++++++++++++++
- Set default values.
- ++++++++++++++++++++++++++++++++++++++*/
- static void SetDefaultValues(void)
- {
- int i;
- LogLevel=Important;
- IndexLatestDays=7;
- RequestChanged=600;
- RequestChangedOnce=1;
- RequestExpired=0;
- RequestNoCache=0;
- PragmaNoCache=1;
- ConfirmRequests=0;
- /* These variables are now set at variable declaration because the
- wwwoffle program can be run without a configuration file. */
- /*
- SocketTimeout=120;
- ConnectTimeout=30;
- */
- ConnectRetry=0;
- SSLAllowPort=NULL;
- NoLasttimeIndex=0;
- IntrDownloadKeep=0;
- IntrDownloadSize=1;
- IntrDownloadPercent=80;
- TimeoutDownloadKeep=0;
- FetchStyleSheets=0;
- FetchImages=0;
- FetchFrames=0;
- FetchScripts=0;
- FetchObjects=0;
- EnableHTMLModifications=0;
- AddCacheInfo=0;
- for(i=0;i<3;i++)
- {
- AnchorModifyBegin[i]=NULL;
- AnchorModifyEnd[i]=NULL;
- }
- DisableHTMLScript=0;
- DisableHTMLBlink=0;
- DisableAnimatedGIF=0;
- LocalHost=NULL;
- LocalNet=NULL;
- AllowedConnectHosts=NULL;
- AllowedConnectUsers=NULL;
- DontCache=NULL;
- DontGet=NULL;
- DontGetReplacementURL=NULL;
- DontGetRecursive=NULL;
- DontRequestOffline=NULL;
- CensorHeader=NULL;
- RefererSelf=0;
- RefererSelfDir=0;
- FTPUserName=(char*)malloc(16); strcpy(FTPUserName,"anonymous");
- FTPPassWord=DefaultFTPPassWord();
- FTPAuthHost=NULL;
- FTPAuthUser=NULL;
- FTPAuthPass=NULL;
- DefaultMIMEType=(char*)malloc(32); strcpy(DefaultMIMEType,"text/plain");
- MIMETypes=NULL;
- Proxies=NULL;
- ProxyAuthHost=NULL;
- ProxyAuthUser=NULL;
- ProxyAuthPass=NULL;
- SSLProxy=NULL;
- DontIndexOutgoing=NULL;
- DontIndexLatest=NULL;
- DontIndexMonitor=NULL;
- DontIndexHost=NULL;
- DontIndex=NULL;
- Aliases=DefaultAliasLinks();
- PurgeUseMTime=0;
- DefaultPurgeAge=14;
- PurgeCacheSize=0;
- PurgeDiskFree=0;
- PurgeUseURL=0;
- PurgeDontGet=0;
- PurgeDontCache=0;
- PurgeAges=NULL;
- }
- /*++++++++++++++++++++++++++++++++++++++
- Save the old values in case the re-read of the file fails.
- ++++++++++++++++++++++++++++++++++++++*/
- static void SaveOldValues(void)
- {
- int i;
- old_LogLevel=LogLevel;
- old_IndexLatestDays=IndexLatestDays;
- old_RequestChanged=RequestChanged;
- old_RequestChangedOnce=RequestChangedOnce;
- old_RequestExpired=RequestExpired;
- old_RequestNoCache=RequestNoCache;
- old_PragmaNoCache=PragmaNoCache;
- old_ConfirmRequests=ConfirmRequests;
- old_SocketTimeout=SocketTimeout;
- old_ConnectTimeout=ConnectTimeout;
- old_ConnectRetry=ConnectRetry;
- old_SSLAllowPort=SSLAllowPort;
- old_NoLasttimeIndex=NoLasttimeIndex;
- old_IntrDownloadKeep=IntrDownloadKeep;
- old_IntrDownloadSize=IntrDownloadSize;
- old_IntrDownloadPercent=IntrDownloadPercent;
- old_TimeoutDownloadKeep=TimeoutDownloadKeep;
- old_FetchStyleSheets=FetchStyleSheets;
- old_FetchImages=FetchImages;
- old_FetchFrames=FetchFrames;
- old_FetchScripts=FetchScripts;
- old_FetchObjects=FetchObjects;
- old_EnableHTMLModifications=EnableHTMLModifications;
- old_AddCacheInfo=AddCacheInfo;
- for(i=0;i<3;i++)
- {
- old_AnchorModifyBegin[i]=AnchorModifyBegin[i];
- old_AnchorModifyEnd[i]=AnchorModifyEnd[i];
- }
- old_DisableHTMLScript=DisableHTMLScript;
- old_DisableHTMLBlink=DisableHTMLBlink;
- old_DisableAnimatedGIF=DisableAnimatedGIF;
- old_LocalHost=LocalHost;
- old_LocalNet=LocalNet;
- old_AllowedConnectHosts=AllowedConnectHosts;
- old_AllowedConnectUsers=AllowedConnectUsers;
- old_DontCache=DontCache;
- old_DontGet=DontGet;
- old_DontGetReplacementURL=DontGetReplacementURL;
- old_DontGetRecursive=DontGetRecursive;
- old_DontRequestOffline=DontRequestOffline;
- old_CensorHeader=CensorHeader;
- old_RefererSelf=RefererSelf;
- old_RefererSelfDir=RefererSelfDir;
- old_FTPUserName=FTPUserName;
- old_FTPPassWord=FTPPassWord;
- old_FTPAuthHost=FTPAuthHost;
- old_FTPAuthUser=FTPAuthUser;
- old_FTPAuthPass=FTPAuthPass;
- old_DefaultMIMEType=DefaultMIMEType;
- old_MIMETypes=MIMETypes;
- old_Proxies=Proxies;
- old_ProxyAuthHost=ProxyAuthHost;
- old_ProxyAuthUser=ProxyAuthUser;
- old_ProxyAuthPass=ProxyAuthPass;
- old_SSLProxy=SSLProxy;
- old_DontIndexOutgoing=DontIndexOutgoing;
- old_DontIndexLatest=DontIndexLatest;
- old_DontIndexMonitor=DontIndexMonitor;
- old_DontIndexHost=DontIndexHost;
- old_DontIndex=DontIndex;
- old_Aliases=Aliases;
- old_PurgeUseMTime=PurgeUseMTime;
- old_DefaultPurgeAge=DefaultPurgeAge;
- old_PurgeCacheSize=PurgeCacheSize;
- old_PurgeDiskFree=PurgeDiskFree;
- old_PurgeUseURL=PurgeUseURL;
- old_PurgeDontGet=PurgeDontGet;
- old_PurgeDontCache=PurgeDontCache;
- old_PurgeAges=PurgeAges;
- }
- /*++++++++++++++++++++++++++++++++++++++
- Restore the old values if the re-read failed.
- ++++++++++++++++++++++++++++++++++++++*/
- static void RestoreOldValues(void)
- {
- int i;
- LogLevel=old_LogLevel;
- IndexLatestDays=old_IndexLatestDays;
- RequestChanged=old_RequestChanged;
- RequestChangedOnce=old_RequestChangedOnce;
- RequestExpired=old_RequestExpired;
- RequestNoCache=old_RequestNoCache;
- PragmaNoCache=old_PragmaNoCache;
- ConfirmRequests=old_ConfirmRequests;
- SocketTimeout=old_SocketTimeout;
- ConnectTimeout=old_ConnectTimeout;
- ConnectRetry=old_ConnectRetry;
- if(SSLAllowPort)
- FreeKeyPairList(SSLAllowPort,0);
- SSLAllowPort=old_SSLAllowPort;
- NoLasttimeIndex=old_NoLasttimeIndex;
- IntrDownloadKeep=old_IntrDownloadKeep;
- IntrDownloadSize=old_IntrDownloadSize;
- IntrDownloadPercent=old_IntrDownloadPercent;
- TimeoutDownloadKeep=old_TimeoutDownloadKeep;
- FetchStyleSheets=old_FetchStyleSheets;
- FetchImages=old_FetchImages;
- FetchFrames=old_FetchFrames;
- FetchScripts=old_FetchScripts;
- FetchObjects=old_FetchObjects;
- EnableHTMLModifications=old_EnableHTMLModifications;
- AddCacheInfo=old_AddCacheInfo;
- for(i=0;i<3;i++)
- {
- if(AnchorModifyBegin[i])
- free(AnchorModifyBegin[i]);
- AnchorModifyBegin[i]=old_AnchorModifyBegin[i];
- if(AnchorModifyEnd[i])
- free(AnchorModifyEnd[i]);
- AnchorModifyEnd[i]=old_AnchorModifyEnd[i];
- }
- DisableHTMLScript=old_DisableHTMLScript;
- DisableHTMLBlink=old_DisableHTMLBlink;
- DisableAnimatedGIF=old_DisableAnimatedGIF;
- if(LocalHost)
- FreeKeyPairList(LocalHost,FREE_KEY_STRING);
- LocalHost=old_LocalHost;
- if(LocalNet)
- FreeKeyPairList(LocalNet,FREE_KEY_STRING);
- LocalNet=old_LocalNet;
- if(AllowedConnectHosts)
- FreeKeyPairList(AllowedConnectHosts,FREE_KEY_STRING);
- AllowedConnectHosts=old_AllowedConnectHosts;
- if(AllowedConnectUsers)
- FreeKeyPairList(AllowedConnectUsers,FREE_KEY_STRING);
- AllowedConnectUsers=old_AllowedConnectUsers;
- if(DontCache)
- FreeKeyPairList(DontCache,FREE_KEY_URLSPEC);
- DontCache=old_DontCache;
- if(DontGet)
- FreeKeyPairList(DontGet,FREE_KEY_URLSPEC|FREE_VALUE_STRING);
- DontGet=old_DontGet;
- if(DontGetReplacementURL)
- free(DontGetReplacementURL);
- DontGetReplacementURL=old_DontGetReplacementURL;
- if(DontGetRecursive)
- FreeKeyPairList(DontGetRecursive,FREE_KEY_URLSPEC);
- DontGetRecursive=old_DontGetRecursive;
- if(DontRequestOffline)
- FreeKeyPairList(DontRequestOffline,FREE_KEY_URLSPEC);
- DontRequestOffline=old_DontRequestOffline;
- if(CensorHeader)
- FreeKeyPairList(CensorHeader,FREE_KEY_STRING|FREE_VALUE_STRING);
- CensorHeader=old_CensorHeader;
- RefererSelf=old_RefererSelf;
- RefererSelfDir=old_RefererSelfDir;
- if(FTPUserName)
- free(FTPUserName);
- FTPUserName=old_FTPUserName;
- if(FTPPassWord)
- free(FTPPassWord);
- FTPPassWord=old_FTPPassWord;
- if(FTPAuthHost)
- FreeKeyPairList(FTPAuthHost,FREE_VALUE_STRING);
- FTPAuthHost=old_FTPAuthHost;
- if(FTPAuthUser)
- FreeKeyPairList(FTPAuthUser,FREE_VALUE_STRING);
- FTPAuthUser=old_FTPAuthUser;
- if(FTPAuthPass)
- FreeKeyPairList(FTPAuthPass,FREE_VALUE_STRING);
- FTPAuthPass=old_FTPAuthPass;
- if(DefaultMIMEType)
- free(DefaultMIMEType);
- DefaultMIMEType=old_DefaultMIMEType;
- if(MIMETypes)
- FreeKeyPairList(MIMETypes,FREE_KEY_STRING|FREE_VALUE_STRING);
- MIMETypes=old_MIMETypes;
- if(Proxies)
- FreeKeyPairList(Proxies,FREE_KEY_STRING|FREE_VALUE_STRING);
- Proxies=old_Proxies;
- if(ProxyAuthHost)
- FreeKeyPairList(ProxyAuthHost,FREE_VALUE_STRING);
- ProxyAuthHost=old_ProxyAuthHost;
- if(ProxyAuthUser)
- FreeKeyPairList(ProxyAuthUser,FREE_VALUE_STRING);
- ProxyAuthUser=old_ProxyAuthUser;
- if(ProxyAuthPass)
- FreeKeyPairList(ProxyAuthPass,FREE_VALUE_STRING);
- ProxyAuthPass=old_ProxyAuthPass;
- if(SSLProxy)
- free(SSLProxy);
- SSLProxy=old_SSLProxy;
- if(DontIndexOutgoing)
- FreeKeyPairList(DontIndexOutgoing,FREE_VALUE_URLSPEC);
- DontIndexOutgoing=old_DontIndexOutgoing;
- if(DontIndexLatest)
- FreeKeyPairList(DontIndexLatest,FREE_VALUE_URLSPEC);
- DontIndexLatest=old_DontIndexLatest;
- if(DontIndexMonitor)
- FreeKeyPairList(DontIndexMonitor,FREE_VALUE_URLSPEC);
- DontIndexMonitor=old_DontIndexMonitor;
- if(DontIndexHost)
- FreeKeyPairList(DontIndexHost,FREE_VALUE_URLSPEC);
- DontIndexHost=old_DontIndexHost;
- if(DontIndex)
- FreeKeyPairList(DontIndex,FREE_KEY_URLSPEC);
- DontIndex=old_DontIndex;
- if(Aliases)
- FreeKeyPairList(Aliases,FREE_KEY_URLSPEC|FREE_VALUE_URLSPEC);
- Aliases=old_Aliases;
- PurgeUseMTime=old_PurgeUseMTime;
- DefaultPurgeAge=old_DefaultPurgeAge;
- PurgeCacheSize=old_PurgeCacheSize;
- PurgeDiskFree=old_PurgeDiskFree;
- PurgeUseURL=old_PurgeUseURL;
- PurgeDontGet=old_PurgeDontGet;
- PurgeDontCache=old_PurgeDontCache;
- if(PurgeAges)
- FreeKeyPairList(PurgeAges,FREE_KEY_URLSPEC);
- PurgeAges=old_PurgeAges;
- }
- /*++++++++++++++++++++++++++++++++++++++
- Remove the old values if the re-read succeeded.
- ++++++++++++++++++++++++++++++++++++++*/
- static void RemoveOldValues(void)
- {
- int i;
- if(old_SSLAllowPort)
- FreeKeyPairList(old_SSLAllowPort,0);
- for(i=0;i<3;i++)
- {
- if(old_AnchorModifyBegin[i])
- free(old_AnchorModifyBegin[i]);
- if(old_AnchorModifyEnd[i])
- free(old_AnchorModifyEnd[i]);
- }
- if(old_LocalHost)
- FreeKeyPairList(old_LocalHost,FREE_KEY_STRING);
- if(old_LocalNet)
- FreeKeyPairList(old_LocalNet,FREE_KEY_STRING);
- if(old_AllowedConnectHosts)
- FreeKeyPairList(old_AllowedConnectHosts,FREE_KEY_STRING);
- if(old_AllowedConnectUsers)
- FreeKeyPairList(old_AllowedConnectUsers,FREE_KEY_STRING);
- if(old_DontCache)
- FreeKeyPairList(old_DontCache,FREE_KEY_URLSPEC);
- if(old_DontGet)
- FreeKeyPairList(old_DontGet,FREE_KEY_URLSPEC|FREE_VALUE_STRING);
- if(old_DontGetReplacementURL)
- free(old_DontGetReplacementURL);
- if(old_DontGetRecursive)
- FreeKeyPairList(old_DontGetRecursive,FREE_KEY_URLSPEC);
- if(old_DontRequestOffline)
- FreeKeyPairList(old_DontRequestOffline,FREE_KEY_URLSPEC);
- if(old_CensorHeader)
- FreeKeyPairList(old_CensorHeader,FREE_KEY_STRING|FREE_VALUE_STRING);
- if(old_FTPUserName)
- free(old_FTPUserName);
- if(old_FTPPassWord)
- free(old_FTPPassWord);
- if(old_FTPAuthHost)
- FreeKeyPairList(old_FTPAuthHost,FREE_VALUE_STRING);
- if(old_FTPAuthUser)
- FreeKeyPairList(old_FTPAuthUser,FREE_VALUE_STRING);
- if(old_FTPAuthPass)
- FreeKeyPairList(old_FTPAuthPass,FREE_VALUE_STRING);
- if(old_DefaultMIMEType)
- free(old_DefaultMIMEType);
- if(old_MIMETypes)
- FreeKeyPairList(old_MIMETypes,FREE_KEY_STRING|FREE_VALUE_STRING);
- if(old_Proxies)
- FreeKeyPairList(old_Proxies,FREE_KEY_URLSPEC|FREE_VALUE_STRING);
- if(old_ProxyAuthHost)
- FreeKeyPairList(old_ProxyAuthHost,FREE_VALUE_STRING);
- if(old_ProxyAuthUser)
- FreeKeyPairList(old_ProxyAuthUser,FREE_VALUE_STRING);
- if(old_ProxyAuthPass)
- FreeKeyPairList(old_ProxyAuthPass,FREE_VALUE_STRING);
- if(old_SSLProxy)
- free(old_SSLProxy);
- if(old_DontIndexOutgoing)
- FreeKeyPairList(old_DontIndexOutgoing,FREE_VALUE_URLSPEC);
- if(old_DontIndexLatest)
- FreeKeyPairList(old_DontIndexLatest,FREE_VALUE_URLSPEC);
- if(old_DontIndexMonitor)
- FreeKeyPairList(old_DontIndexMonitor,FREE_VALUE_URLSPEC);
- if(old_DontIndexHost)
- FreeKeyPairList(old_DontIndexHost,FREE_VALUE_URLSPEC);
- if(old_DontIndex)
- FreeKeyPairList(old_DontIndex,FREE_KEY_URLSPEC);
- if(old_Aliases)
- FreeKeyPairList(old_Aliases,FREE_KEY_URLSPEC|FREE_VALUE_URLSPEC);
- if(old_PurgeAges)
- FreeKeyPairList(old_PurgeAges,FREE_KEY_URLSPEC);
- }
- /*++++++++++++++++++++++++++++++++++++++
- Free a KeyPair list.
- KeyPair **list The list to free.
- int freewhat A bitwise OR of FREE_KEY_STRING or FREE_KEY_URLSPEC and FREE_VALUE_STRING or FREE_VALUE_URLSPEC.
- ++++++++++++++++++++++++++++++++++++++*/
- static void FreeKeyPairList(KeyPair **list,int freewhat)
- {
- KeyPair **p;
- for(p=list;(*p)!=&KeyPairEnd;p++)
- {
- if(freewhat&FREE_KEY_STRING && (*p)->key.string)
- free((*p)->key.string);
- if(freewhat&FREE_KEY_URLSPEC && (*p)->key.urlspec)
- {
- if((*p)->key.urlspec->proto)
- free((*p)->key.urlspec->proto);
- if((*p)->key.urlspec->host)
- free((*p)->key.urlspec->host);
- if((*p)->key.urlspec->path)
- free((*p)->key.urlspec->path);
- if((*p)->key.urlspec->args && *(*p)->key.urlspec->args)
- free((*p)->key.urlspec->args);
- free((*p)->key.urlspec);
- }
- if(freewhat&FREE_VALUE_STRING && (*p)->value.string)
- free((*p)->value.string);
- if(freewhat&FREE_VALUE_URLSPEC && (*p)->value.urlspec)
- {
- if((*p)->value.urlspec->proto)
- free((*p)->value.urlspec->proto);
- if((*p)->value.urlspec->host)
- free((*p)->value.urlspec->host);
- if((*p)->value.urlspec->path)
- free((*p)->value.urlspec->path);
- if((*p)->value.urlspec->args && *(*p)->value.urlspec->args)
- free((*p)->value.urlspec->args);
- free((*p)->value.urlspec);
- }
- free(*p);
- }
- free(list);
- }