Esempio n. 1
0
File: main.c Progetto: sisoftrg/qico
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;
}
Esempio n. 2
0
int emsisession(int mode,ftnaddr_t *calladdr,int speed)
{
	int rc,emsi_lo=0,proto;
	unsigned long nfiles;
	unsigned char *mydat;
	char *t,pr[3],s[MAX_STRING];
	falist_t *pp=NULL;
	qitem_t *q=NULL;
	was_req=0;got_req=0;
	receive_callback=receivecb;
	totaln=0;totalf=0;totalm=0;emsi_lo=0;
	if(mode) {
		write_log("starting outbound EMSI session");
		q=q_find(calladdr);
		if(q) {
			totalm=q->pkts;
			totalf=q_sum(q)+q->reqs;
		}
		mydat=(unsigned char*)emsi_makedat(calladdr,totalm,totalf,O_PUA,cfgs(CFG_PROTORDER),NULL,1);
		rc=emsi_send(mode,mydat);xfree(mydat);
		if(rc<0)return S_REDIAL|S_ADDTRY;
		rc=emsi_recv(mode,rnode);
		if(rc<0)return S_REDIAL|S_ADDTRY;
		title("Outbound session %s",ftnaddrtoa(&rnode->addrs->addr));
	    } else {
		rc=emsi_recv(mode,rnode);
		if(rc<0) {
			write_log("unable to establish EMSI session");
			return S_REDIAL|S_ADDTRY;
		}
		write_log("starting inbound EMSI session");
		if((t=getenv("CALLER_ID"))&&strcasecmp(t,"none")&&strlen(t)>3)
		    title("Inbound session %s (CID %s)",ftnaddrtoa(&rnode->addrs->addr),t);
		else title("Inbound session %s",ftnaddrtoa(&rnode->addrs->addr));
	}
	log_rinfo(rnode);
	for(pp=rnode->addrs;pp;pp=pp->next)aso_locknode(&pp->addr,LCK_s);
	if(mode) {
		if(!has_addr(calladdr,rnode->addrs)) {
			write_log("remote isn't %s",ftnaddrtoa(calladdr));
			return S_FAILURE;
		}
		flkill(&fl,0);totalf=0;totalm=0;
		for(pp=rnode->addrs;pp;pp=pp->next)makeflist(&fl,&pp->addr,mode);
		if(strlen(rnode->pwd))rnode->options|=O_PWD;
		if(is_listed(rnode->addrs,cfgs(CFG_NLPATH),cfgi(CFG_NEEDALLLISTED)))rnode->options|=O_LST;
	} else {
		for(pp=cfgal(CFG_ADDRESS);pp;pp=pp->next)
		    if(has_addr(&pp->addr,rnode->addrs)) {
			write_log("remote also has %s",ftnaddrtoa(&pp->addr));
			return S_FAILURE;
		}
		nfiles=0;rc=0;
		for(pp=rnode->addrs;pp;pp=pp->next) {
			t=findpwd(&pp->addr);
			if(!t||!strcasecmp(rnode->pwd,t)) {
				makeflist(&fl,&pp->addr,mode);
				if(t)rnode->options|=O_PWD;
			} else {
				write_log("password not matched for %s",ftnaddrtoa(&pp->addr));
				write_log("  (got '%s' instead of '%s')",rnode->pwd,t);
				rc=1;
			}
		}
		if(!rc&&!(rnode->options&O_PWD))write_log("remote has been password for us");
		if(is_listed(rnode->addrs,cfgs(CFG_NLPATH),cfgi(CFG_NEEDALLLISTED)))rnode->options|=O_LST;
		if(rc) {
			emsi_lo|=O_BAD;
			rnode->options|=O_BAD;
		}
		if(!cfgs(CFG_FREQTIME)||rc)emsi_lo|=O_NRQ;
		if(ccs&&!checktimegaps(ccs))emsi_lo|=O_HRQ;
		if(checktimegaps(cfgs(CFG_MAILONLY))||
		   checktimegaps(cfgs(CFG_ZMH))||rc)emsi_lo|=O_HXT|O_HRQ;
		if(cfgi(CFG_SENDONLY))emsi_lo|=O_HAT;
		pr[2]=0;pr[1]=0;pr[0]=0;
		for(t=cfgs(CFG_PROTORDER);*t;t++) {
#ifdef HYDRA8K16K
			if(*t=='4'&&rnode->options&P_HYDRA4) {
				*pr='4';emsi_lo|=P_HYDRA4;break;}
			if(*t=='8'&&rnode->options&P_HYDRA8) {
				*pr='8';emsi_lo|=P_HYDRA8;break;}
			if(*t=='6'&&rnode->options&P_HYDRA16) {
				*pr='6';emsi_lo|=P_HYDRA16;break;}
#endif/*HYDRA8K16K*/
			if(*t=='H'&&rnode->options&P_HYDRA) {
				*pr='H';emsi_lo|=P_HYDRA;break;}
			if(*t=='J'&&rnode->options&P_JANUS) {
				*pr='J';emsi_lo|=P_JANUS;break;}
			if(*t=='D'&&rnode->options&P_DIRZAP) {
				*pr='D';emsi_lo|=P_DIRZAP;break;}
			if(*t=='Z'&&rnode->options&P_ZEDZAP) {
				*pr='Z';emsi_lo|=P_ZEDZAP;break;}
			if(*t=='1'&&rnode->options&P_ZMODEM) {
				*pr='1';emsi_lo|=P_ZMODEM;break;}
		}
		if(strchr(cfgs(CFG_PROTORDER),'C'))pr[1]='C';
		    else rnode->opt&=~MO_CHAT;
		if(!*pr)emsi_lo|=P_NCP;
		mydat=(unsigned char*)emsi_makedat(&rnode->addrs->addr,totalm,totalf,emsi_lo,pr,NULL,!(emsi_lo&O_BAD));
		rc=emsi_send(0,mydat);xfree(mydat);
		if(rc<0) {
			flkill(&fl,0);
			return S_REDIAL|S_ADDTRY;
		}
	}
	if(cfgs(CFG_RUNONEMSI)&&*ccs) {
		write_log("starting %s %s",ccs,rnode->addrs?ftnaddrtoa(&rnode->addrs->addr):(calladdr?ftnaddrtoa(calladdr):"unknown"));
		execnowait(ccs,rnode->addrs?ftnaddrtoa(&rnode->addrs->addr):(calladdr?ftnaddrtoa(calladdr):"unknown"),NULL,NULL);
	}
	write_log("we have: %d%c mail; %d%c files",SIZES(totalm),SIZEC(totalm),SIZES(totalf),SIZEC(totalf));
	rnode->starttime=time(NULL);
	if(cfgi(CFG_MAXSESSION))alarm(cci*60);
	DEBUG(('S',1,"Maxsession: %d",cci));
	proto=(mode?rnode->options:emsi_lo)&P_MASK;
	switch(proto) {
	    case P_NCP:
		write_log("no compatible protocols");
		flkill(&fl,0);
		return S_FAILURE;
	    case P_ZMODEM:
		t="ZModem-1k";break;
	    case P_ZEDZAP:
		t="ZedZap";break;
	    case P_DIRZAP:
		t="DirZap";break;
#ifdef HYDRA8K16K
	    case P_HYDRA4:
		t="Hydra-4k";break;
	    case P_HYDRA8:
		t="Hydra-8k";break;
	    case P_HYDRA16:
		t="Hydra-16k";break;
#endif/*HYDRA8K16K*/
	    case P_HYDRA:
		t="Hydra";break;
	    case P_JANUS:
		t="Janus";break;
	    default:
		t="Unknown";
	}
	DEBUG(('S',1,"emsopts: %s %x %x %x %x",t,rnode->options&P_MASK,rnode->options,emsi_lo,rnode->opt));
	snprintf(s,MAX_STRING-1,"%s%s%s%s%s%s%s%s%s%s",t,
		(rnode->options&O_LST)?"/LST":"",
		(rnode->options&O_PWD)?"/PWD":"",
		(rnode->options&O_HXT)?"/MO":"",
		(rnode->options&O_HAT)?"/HAT":"",
		(rnode->options&O_HRQ)?"/HRQ":"",
		(rnode->options&O_NRQ)?"/NRQ":"",
		(rnode->options&O_FNC)?"/FNC":"",
		(rnode->options&O_BAD)?"/BAD":"",
		(rnode->opt&MO_CHAT)?"/CHT":"");
	write_log("options: %s",s);
	chatinit(proto);
	IFPerl(rc=perl_on_session(s);
	    if(rc!=S_OK){flkill(&fl,0);return rc;});