int main(int argc, char *argv[], char *envp[]) { s_bforce_opts opts; int rc = 0; int ch = 0; opts.runmode = MODE_UNDEFINED; memset(&opts, '\0', sizeof(s_bforce_opts)); // parsing while( (ch=getopt(argc, argv, "hfI:p:n:l:a:u:oiC:S:dq")) != EOF ) { switch( ch ) { case 'h': usage(); exit(BFERR_NOERROR); case 'f': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM; if( opts.runmode != MODE_CALL_MODEM || opts.force ) { usage(); exit(BFERR_FATALERROR); } opts.force = 1; break; case 'I': if( opts.incname || !optarg ) { usage(); exit(BFERR_FATALERROR); } //free(opts.incname); opts.incname = (char *)xstrcpy(optarg); break; case 'p': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM; if( opts.runmode != MODE_CALL_MODEM || opts.device || !optarg ) { usage(); exit(BFERR_FATALERROR); } opts.device = (char *)xstrcpy(optarg); break; case 'n': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM; if( opts.runmode != MODE_CALL_MODEM || opts.phone || !optarg ) { usage(); exit(BFERR_FATALERROR); } //if( opts.phone ) free(opts.phone); opts.phone = (char *)xstrcpy(optarg); break; case 'l': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_MODEM; if( opts.runmode != MODE_CALL_MODEM || opts.hiddline || !optarg || ISDEC(optarg) ) { usage(); exit(BFERR_FATALERROR); } opts.hiddline = atoi(optarg); break; case 'a': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_IP; if( opts.runmode != MODE_CALL_IP || opts.iphost || !optarg ) { usage(); exit(BFERR_FATALERROR); } opts.iphost = (char *)xstrcpy(optarg); break; case 'u': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_IP; if( opts.runmode != MODE_CALL_IP || opts.ipproto || !optarg ) { usage(); exit(BFERR_FATALERROR); } opts.ipproto = (char *)xstrcpy(optarg); break; case 'o': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_STDIO; if( opts.runmode != MODE_CALL_STDIO || opts.usestdio ) { usage(); exit(BFERR_FATALERROR); } opts.usestdio = TRUE; break; case 'i': //if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; //if( opts.runmode != MODE_ANSWER || opts.inetd ) { usage(); exit(BFERR_FATALERROR); } opts.inetd = 1; break; case 'C': if( opts.confname || !optarg ) { usage(); exit(BFERR_FATALERROR); } opts.confname = (char *)xstrcpy(optarg); break; case 'S': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.connect || !optarg ) { usage(); exit(BFERR_FATALERROR); } opts.connect = (char *)xstrcpy(optarg); break; case 'd': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_DAEMON; if( opts.runmode != MODE_DAEMON || opts.daemon || opts.quit ) { usage(); exit(BFERR_FATALERROR); } opts.daemon = 1; break; case 'q': if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_DAEMON; if( opts.runmode != MODE_DAEMON || opts.quit ) { usage(); exit(BFERR_FATALERROR); } opts.quit = 1; opts.daemon = 1; break; default : usage(); exit(BFERR_FATALERROR); } } /* Expression checker use it, so init first */ init_state(&state); /* Set space available for process title */ #ifndef HAVE_SETPROCTITLE setargspace(argv, envp); #endif /* Initialise random number generation */ (void)srand((unsigned)time(NULL)); /* Initialise current locale */ (void)setlocale(LC_ALL, ""); /* Set secure process umask */ (void)umask(~(S_IRUSR|S_IWUSR)); /* Now process non-option arguments */ if( opts.daemon == FALSE ) { const char *p; s_faddr addr; s_falist **alist = &opts.addrlist; while( (optind < argc) && (p = argv[optind++]) ) { for( ; *p == '*'; p++ ); if( strcasecmp(p, "tsync") == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); } opts.stype = SESSION_FTSC; } else if( strcasecmp(p, "yoohoo") == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); } opts.stype = SESSION_YOOHOO; } else if( strcasecmp(p, "**EMSI_INQC816") == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); } opts.stype = SESSION_EMSI; } else if( strncasecmp(p, "emsi", 4) == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); } opts.stype = SESSION_EMSI; } else if( strcasecmp(p, "binkp") == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); } opts.stype = SESSION_BINKP; } else if( strcasecmp(p, "auto") == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_ANSWER; if( opts.runmode != MODE_ANSWER || opts.stype ) { usage(); exit(BFERR_FATALERROR); } opts.stype = SESSION_UNKNOWN; } else if( ftn_addrparse(&addr, p, FALSE) == 0 ) { if( opts.runmode == MODE_UNDEFINED ) opts.runmode = MODE_CALL_DEFAULT; if( opts.runmode != MODE_CALL_DEFAULT && opts.runmode != MODE_CALL_IP && opts.runmode != MODE_CALL_MODEM && opts.runmode != MODE_CALL_STDIO ) { usage(); exit(BFERR_FATALERROR); } (*alist) = (s_falist*)xmalloc(sizeof(s_falist)); memset(*alist, '\0', sizeof(s_falist)); (*alist)->addr = addr; alist = &(*alist)->next; } else { printf("invalid address \"%s\"", p); usage(); exit(BFERR_FATALERROR); } } } /* if( opts.inetd && opts.runmode != MODE_ANSWER && opts.runmode != MODE_CALL_STDIO ) { usage(); exit(BFERR_FATALERROR); } */ /* if( (rc = log_open(BFORCE_LOGFILE, NULL, NULL)) ) //compiled in { log("can't continue without logging"); gotoexit(BFERR_FATALERROR); }*/ /* Process primary config file */ if( opts.confname && *opts.confname ) rc = conf_readconf(opts.confname, 0); else rc = conf_readconf(conf_getconfname(), 0); if( rc ) gotoexit(BFERR_FATALERROR); /* Process additional config file, ignore errors */ if( opts.incname && *opts.incname ) (void)conf_readconf(opts.incname, 1); /* Reopen log file if it was defined in config */ if( log_reopen(log_getfilename(LOG_FILE_SESSION), NULL, NULL) ) { log("can't continue without logging"); gotoexit(BFERR_FATALERROR); } //char runmode_str[21]; //snprintf(runmode_str, 20, "Run mode: %d", opts.runmode); //log(runmode_str); switch( opts.runmode ) { case MODE_DAEMON: log("Daemon mode"); rc = bforce_daemon(&opts); break; case MODE_CALL_DEFAULT: case MODE_CALL_IP: case MODE_CALL_MODEM: case MODE_CALL_STDIO: log("Outgoing call"); rc = bforce_master(&opts); break; case MODE_ANSWER: log("Start answer"); rc = bforce_slave(&opts); break; default: log("Could not determine run mode"); } exit: deinit_conf(); deinit_opts(&opts); /* Shutdown logging services */ if( log_isopened() ) log_close(); DEB((D_FREE, "good exit")); #ifdef DEBUG if( debug_isopened() ) debug_close(); #endif exit(rc); }
int main(int argc,char **argv,char **envp) { int c,daemon=-1,rc,sesstype=SESSION_EMSI,line=0,call_flags=0; char *hostname=NULL,*str=NULL; FTNADDR_T(fa); #ifndef HAVE_SETPROCTITLE setargspace(argc,argv,envp); #endif #ifdef HAVE_SETLOCALE setlocale(LC_ALL, ""); #endif while((c=getopt(argc, argv, "hI:da:ni:c:tbv"))!=EOF) { switch(c) { case 'c': daemon=12; str=optarg; while(str&&*str) { switch(toupper(*str)) { case 'N': call_flags=0; break; case 'I': call_flags|=1; break; case 'A': call_flags|=2; break; default: write_log("unknown call option: %c", *optarg); exit(S_FAILURE); } str++; } break; case 'i': hostname=optarg; break; case 'I': configname=optarg; break; case 'd': daemon=1; break; case 'a': daemon=0; sesstype=SESSION_AUTO; if(!strncasecmp(optarg,"**emsi",6)|| !strncasecmp(optarg,"auto",4))sesstype=SESSION_EMSI; #ifdef WITH_BINKP if(strncasecmp(optarg,"binkp",5)&& (*optarg!=0x80||!optarg[1]||optarg[2]))break; sesstype=SESSION_BINKP; case 'b': bink=1; #endif break; case 'n': daemon=2; break; case 't': daemon=3; break; case 'v': u_vers(progname); default: usage(argv[0]); } } if(!hostname&&daemon<0)usage(argv[0]); getsysinfo();ssock=lins_sock=uis_sock=-1; if(!readconfig(configname)) { write_log("there was some errors parsing '%s', aborting",configname); exit(S_FAILURE); } if(!log_init(cfgs(CFG_MASTERLOG),NULL)) { write_log("can't open master log '%s'",ccs); exit(S_FAILURE); } #ifdef NEED_DEBUG parse_log_levels(); if(facilities_levels['C']>=1)dumpconfig(); #endif psubsts=parsesubsts(cfgfasl(CFG_SUBST)); #ifdef NEED_DEBUG if(facilities_levels['C']>=1) { subst_t *s; dialine_t *l; for(s=psubsts;s;s=s->next) { write_log("subst for %s [%d]",ftnaddrtoa(&s->addr),s->nhids); for(l=s->hiddens;l;l=l->next) write_log(" * %s,%s,%s,%d,%d",l->phone,l->host,l->timegaps,l->flags,l->num); } } #endif log_done(); if(daemon==3)exit(S_OK); if(hostname||daemon==12) { if(!parseftnaddr(argv[optind],&fa,&DEFADDR,0)) { write_log("can't parse address '%s'",argv[optind]); exit(S_FAILURE); } optind++; } if(hostname) { is_ip=1; rnode=xcalloc(1,sizeof(ninfo_t)); xstrcpy(ip_id,"ipline",10); rnode->tty=bink?"binkp":"tcpip"; if(!log_init(cfgs(CFG_LOG),rnode->tty)) { write_log("can't open log %s",ccs); exit(S_FAILURE); } signal(SIGINT,sigerr); signal(SIGTERM,sigerr); signal(SIGSEGV,sigerr); signal(SIGPIPE,SIG_IGN); IFPerl(perl_init(cfgs(CFG_PERLFILE),0)); log_callback=NULL;xsend_cb=NULL; ssock=cls_conn(CLS_LINE,cfgs(CFG_SERVER),NULL); if(ssock<0)write_log("can't connect to server: %s",strerror(errno)); else log_callback=vlogs; rc=aso_init(cfgs(CFG_ASOOUTBOUND),cfgs(CFG_BSOOUTBOUND),cfgs(CFG_QSTOUTBOUND),cfgal(CFG_ADDRESS)->addr.z); if(!rc) { write_log("No outbound defined"); stopit(S_FAILURE); } rc=do_call(&fa,hostname,NULL); aso_done(); stopit(rc); } if(daemon==12) { if(optind<argc) { if(1!=sscanf(argv[optind],"%d",&line)) { write_log("can't parse line number '%s'!\n",argv[optind]); exit(S_FAILURE); } } else line = 0; log_callback=NULL;xsend_cb=NULL; ssock=cls_conn(CLS_LINE,cfgs(CFG_SERVER),NULL); if(ssock<0)write_log("can't connect to server: %s",strerror(errno)); else log_callback=vlogs; rc=aso_init(cfgs(CFG_ASOOUTBOUND),cfgs(CFG_BSOOUTBOUND),cfgs(CFG_QSTOUTBOUND),cfgal(CFG_ADDRESS)->addr.z); if(!rc) { write_log("No outbound defined"); cls_close(ssock); exit(S_FAILURE); } if(aso_locknode(&fa,LCK_c)) { signal(SIGINT,sigerr); signal(SIGTERM,sigerr); signal(SIGSEGV,sigerr); signal(SIGPIPE,SIG_IGN); IFPerl(perl_init(cfgs(CFG_PERLFILE),0)); rc=force_call(&fa,line,call_flags); aso_unlocknode(&fa,LCK_x); } else rc=S_FAILURE; if(rc&S_MASK)write_log("can't call to %s",ftnaddrtoa(&fa)); aso_done(); stopit(rc); } switch(daemon) { case 1: daemon_mode(); break; case 0: answer_mode(sesstype); break; case 2: compile_nodelists(); break; } return S_OK; }