#include #include #include #include /* #include -- used only for getopt_long */ #include #include #include "config.h" void sig_handler(int par); void some_init(void) { users=NULL; areas=NULL; ticlist_list=NULL; ticlist_list_max=0; hatcher_areaname=NULL; hatcher_filename=NULL; hatcher_replaces=NULL; hatcher_desc=NULL; hatcher_copy=0; hatcher_koi8=0; hatcher_desc_stdin=0; crc32_ignore=0; } void usage(char *argv0) { fprintf(stderr,"\n" "gtic "VERSION" The GNU file forwarder (FSC-0087) for fidonet-like networks\n" "Copyright (c) 1998, Yuri Kuzmenko 2:463/169\n\n" #ifdef SECURE_CONFIG "Usage: gtic [-t|-m|-h] [options]\n\n" #else "Usage: gtic [-t|-m|-h] [-c config_file] [options]\n\n" #endif " -t - tosser, optional options\n" " -i - ignore CRC32 errors\n\n" " -m - area manager, no options\n\n" " -h - hatcher, options required\n" " -a areaname - name of area for hatching, required\n" " -f filename - full path to file for hatching, required\n" " -r replaces - \"replaces\" keyword, optional\n" " -d \"desc, one line\" - description for file, optional\n" " -s - read multiline desc (LDESC) from stdin (use with -d), optional\n" " -C - copy file to inbound instead of hardlink(copy), optional\n" " -k - use koi8-alt description recoding, optional\n\n" #ifndef SECURE_CONFIG "config_file can override CONFIG_define and \"%s.config\"\n" ,argv0 #endif ); exit(1); } #define RUNMODE_UNKNOWN 0 #define RUNMODE_TOSSER 1 #define RUNMODE_MANAGER 2 #define RUNMODE_HATCHER 3 int main(int argc,char *argv[]) { char *configname=NULL; #ifndef SECURE_CONFIG char *config_tmp=NULL; #endif int runmode=RUNMODE_UNKNOWN; int i; #ifndef NO_LOCK int res_fork,w; #endif /* tmp */ /* fprintf(stderr,"\n");*/ #ifndef NO_LOCK if(getuid()==0 || geteuid()==0 || getgid()==0 || getegid()==0) { fprintf(stderr,"gtic CAN NOT run from root user/group\n"); exit(-(0xdead)); } #endif srandom(time(NULL)); while((i=getopt(argc,argv,"t?m?h?c:a:f:r:d:C?k?s?i?"))!=-1) { switch(i) { #ifndef SECURE_CONFIG case 'c': config_tmp=optarg; break; #endif case 't': runmode=RUNMODE_TOSSER; break; case 'm': runmode=RUNMODE_MANAGER; break; case 'h': runmode=RUNMODE_HATCHER; break; case 'i': crc32_ignore=1; break; case 'a': hatcher_areaname=optarg; break; case 'f': hatcher_filename=optarg; break; case 'r': hatcher_replaces=optarg; break; case 'd': hatcher_desc=optarg; break; case 'C': hatcher_copy=1; break; case 'k': hatcher_koi8=1; break; case 's': hatcher_desc_stdin=1; break; default: usage(argv[0]); } } if(runmode==RUNMODE_UNKNOWN) usage(argv[0]); if(runmode==RUNMODE_HATCHER) if(hatcher_areaname==NULL || hatcher_filename==NULL) usage(argv[0]); #ifdef SECURE_CONFIG #ifndef CONFIG #error ${CONFIG} must be defined in Makefile #endif configname=CONFIG; #else if(config_tmp) { if(access_via_stat(config_tmp,F_OK)==0) configname=config_tmp; else e_printf("configname %s not exist",config_tmp); } if(configname==NULL) /* config_tmp failed */ { configname=xstrcpy(argv[0]); configname=xstrcat(configname,".config"); #ifdef CONFIG if(access_via_stat(configname,F_OK)) /* not exist */ configname=CONFIG; #endif } #endif readconfig(configname); l_init(log_file); l_printf("gtic version " VERSION " started"); l_printf("UID=%d, GID=%d, EUID=%d, EGID=%d", getuid(),getgid(),geteuid(),getegid()); #ifndef NO_LOCK if(check_lock()) { l_printf("Another gtic already running (LockPipe %s)",lock_file); return 1; } /* Now fork. Child process work as main process, parent process work as lock pipe handler */ res_fork=fork(); if(res_fork==-1) { e_printf("unable to fork"); abort2(); } if(res_fork!=0) { /* parent, lock handler */ touch_lock(); e_printf("Unable to touch lockpipe %s - lock ignored.",lock_file); while(1) { w=waitpid(res_fork,NULL,0); if(w==0 || w==-1) break; } exit(0); } #endif #ifndef NO_LOCK while(!check_lock()) { l_printf("Sucks! Our parent is brake. Sleep 1 second..."); sleep(1); } #endif /* child, main process */ read_domains_file(); readusers(); readareas(); if(runmode==RUNMODE_TOSSER) { readticlist(); read_tics_from_list(); toss(); freeticlist(); } if(runmode==RUNMODE_MANAGER) { area_manager(); writeusers(); writeareas(); } if(runmode==RUNMODE_HATCHER) { hatcher(); } exit(0); }