void chatlog_done() { FILE *chatlog=NULL; time_t tt;struct tm *t; char str[MAX_STRING]={0}; write_log("Chat closed"); if(rcpos)chatlog_write("\n",1); if(mcpos)chatlog_write("\n",0); if(cfgs(CFG_CHATLOG))chatlog=fopen(ccs,"at"); tt=time(NULL);t=localtime(&tt); strftime(str,MAX_STRING-1,"\n[--- Chat closed at %d %b %y %H:%M:%S ---]\n\n",t); if(chatlog){fwrite(str,strlen(str),1,chatlog);fclose(chatlog);} if(lemail)fwrite(str,strlen(str),1,lemail); if(cpkt) { if(cfgi(CFG_RECODEPKTS))recode_to_remote(str); strtr(str,'\n','\r'); fwrite(str,strlen(str)-1,1,cpkt); closeqpkt(cpkt,adr); snprintf(str,MAX_STRING-1,"%s/%s",cfgs(CFG_INBOUND),basename(pktname)); if(rename(pktname,str))write_log("can't rename %s to %s: %s",pktname,str,strerror(errno)); else chmod(str,cfgi(CFG_DEFPERM)); } if(lemail) { fclose(lemail); snprintf(str,MAX_STRING-1,"mail -s chatlog %s < /tmp/qlemail.%04lx",cfgs(CFG_CHATTOEMAIL),(long)getpid()); execsh(str); lunlink(strrchr(str,'<')+1); } }
int chatlog_init(char *remname,ftnaddr_t *ra,int side) { FILE *chatlog=NULL; time_t tt;struct tm *t; char str[MAX_STRING]={0}; write_log("Chat opened%s",side?" by remote side":""); adr=&cfgal(CFG_ADDRESS)->addr; if(cfgs(CFG_RUNONCHAT)&&side)execnowait("/bin/sh","-c",ccs,ftnaddrtoa(adr)); if(cfgi(CFG_CHATLOGNETMAIL)) { snprintf(pktname,MAX_PATH-1,"%s/tmp/%08lx.pkt",cfgs(CFG_INBOUND),sequencer()); cpkt=openpktmsg(adr,adr,"qico chat-log poster",xstrdup(cfgs(CFG_SYSOP)),"log of chat",NULL,pktname,137); if(!cpkt)write_log("can't open '%s' for writing",pktname); } if(cfgs(CFG_CHATTOEMAIL)) { snprintf(str,MAX_PATH,"/tmp/qlemail.%04lx",(long)getpid()); lemail=fopen(str,"wt"); if(!lemail)write_log("can't crearte temporary email-log file"); } if(cfgs(CFG_CHATLOG))chatlog=fopen(ccs,"at"); if(ccs&&!chatlog)write_log("can't open chat log %s",ccs); tt=time(NULL);t=localtime(&tt); snprintf(str,MAX_STRING,"[Chat with: %s (%u:%u/%u.%u) open by %s at ",remname,ra->z,ra->n,ra->f,ra->p,side?"remote":"my"); strftime(str+strlen(str),MAX_STRING-1,"%d %b %y %H:%M:%S]\n",t); if(chatlog){fwrite(str,strlen(str),1,chatlog);fclose(chatlog);} if(lemail)fwrite(str,strlen(str),1,lemail); if(cpkt) { if(cfgi(CFG_RECODEPKTS))recode_to_remote(str); strtr(str,'\n','\r'); fwrite(str,strlen(str),1,cpkt); runtoss=1; } mcpos=rcpos=0;*rchat=0;*mchat=0; return(cpkt!=NULL||chatlog!=NULL||lemail!=NULL); }
int mdm_dial(char *phone,char *port) { int rc; char s[MAX_STRING],conn[MAX_STRING]; if((rc=tty_openport(port))) { write_log("can't open port: %s",tty_errs[rc]); return MC_BAD; } reset(); xstrcpy(s,cfgs(CFG_DIALPREFIX),MAX_STRING); xstrcat(s,phone,MAX_STRING); xstrcat(s,cfgs(CFG_DIALSUFFIX),MAX_STRING); tty_local(1); sline("Dialing %s",s);vidle(); rc=modem_chat(s,cfgsl(CFG_MODEMCONNECT),cfgsl(CFG_MODEMNODIAL),cfgsl(CFG_MODEMERROR), cfgsl(CFG_MODEMBUSY),cfgs(CFG_MODEMRINGING),cfgi(CFG_MAXRINGS), cfgi(CFG_WAITCARRIER),conn,MAX_STRING); sline("Modem said: %s",conn); xfree(connstr);connstr=xstrdup(conn); if(rc!=MC_OK) { write_log("got %s",conn); if(rc==MC_FAIL)hangup(); tty_close(); if(rc==MC_RING) { sline("RING found.."); sleep(2); execsh("killall -USR1 mgetty vgetty >/dev/null 2>&1"); } else sline("Call failed (%s)",mcs[rc]); return rc; } write_log("*** %s",conn); tty_local(0); return rc; }
/* Checks if our system can process FREQs Returns: -1 - FREQs are not handled at all 0 - FREQs are handled but not at this time 1 - Remote can do FREQs */ int is_freq_available( void ) { if ( !cfgs( CFG_EXTRP ) && !cfgs( CFG_SRIFRP )) return FR_NOTHANDLED; return (( cfgs( CFG_EXTRP ) || cfgs( CFG_SRIFRP )) && checktimegaps( cfgs( CFG_FREQTIME ))); }
int receivecb(char *fn) { char *p=strrchr(fn,'.'); if(!p)return 0; else p++; if(!strcasecmp(p,"pkt")&&cfgi(CFG_SHOWPKT))return(showpkt(fn)); if(!strcasecmp(p,"req")&&(cfgs(CFG_EXTRP)||cfgs(CFG_SRIFRP)))return(freq_recv(fn)); return 0; }
int alive() { char *ac; int rc=MC_OK; ac=cfgs(CFG_MODEMALIVE); DEBUG(('M',4,"alive: checking modem...")); rc=modem_chat(ac,cfgsl(CFG_MODEMOK),cfgsl(CFG_MODEMERROR),cfgsl(CFG_MODEMNODIAL), cfgsl(CFG_MODEMBUSY),cfgs(CFG_MODEMRINGING), cfgi(CFG_MAXRINGS),2,NULL,0); #ifdef NEED_DEBUG if(rc!=MC_OK)DEBUG(('M',3,"alive: failed, rc=%d [%s]",rc,mcs[rc])); #endif return rc; }
static int boxflist(flist_t **fl,char *path) { DIR *d; struct dirent *de; struct stat sb; char mn[MAX_PATH],*p; int len; DEBUG(('S',2,"Add filebox '%s'",path)); if(!(d=opendir(path)))return 0; else { while((de=readdir(d))) { len=strlen(path)+2+strlen(de->d_name); p=xmalloc(len); snprintf(p,len,"%s/%s",path,de->d_name); if(!stat(p,&sb)&&(S_ISREG(sb.st_mode)||S_ISLNK(sb.st_mode))) { xstrcpy(mn,de->d_name,MAX_PATH); mapname(mn,cfgs(CFG_MAPOUT),MAX_PATH); addflist(fl,p,xstrdup(mn),'^',0,NULL,0); totalf+=sb.st_size;totaln++; } else xfree(p); } closedir(d); } return 1; }
static int wazoorecv(int zap) { int rc; write_log("wazoo receive"); rc=zmodem_receive(cfgs(CFG_INBOUND),zap); qpreset(0); return(rc==RCDO||rc==ERROR); }
int tty_lock(char *port) { int rc=-1; char lckname[MAX_PATH],*p; DEBUG(('M',4,"tty_lock")); if(!(p=strrchr(port,'/')))p=port; else p++; snprintf(lckname,MAX_PATH,"%s/LCK..%s",cfgs(CFG_LOCKDIR),p); rc=lockpid(lckname); return rc?0:-1; }
void parse_log_levels() { char *w,c,*levels=xstrdup(cfgs(CFG_LOGLEVELS)); memset(facilities_levels,0,sizeof(facilities_levels)); for(w=strtok(levels,",;");w;w=strtok(NULL,",;")) { c=*w++; if(*w)facilities_levels[(unsigned char)c]=atoi(w); } xfree(levels); }
void makeflist(flist_t **fl,ftnaddr_t *fa,int mode) { faslist_t *j; char str[MAX_PATH],*flv="hdicf"; DEBUG(('S',1,"Make filelist for %s",ftnaddrtoa(fa))); asoflist(fl,fa,mode); for(j=cfgfasl(CFG_FILEBOX);j;j=j->next) if(addr_cmp(fa,&j->addr)) { if(!boxflist(fl,j->str))write_log("can't open filebox '%s'",j->str); break; } if(cfgs(CFG_LONGBOXPATH)) { while(*flv) { snprintf(str,MAX_STRING,"%s/%d.%d.%d.%d.%c",cfgs(CFG_LONGBOXPATH),fa->z,fa->n,fa->f,fa->p,*flv); boxflist(fl,str); flv++; } snprintf(str,MAX_STRING,"%s/%d.%d.%d.%d",cfgs(CFG_LONGBOXPATH),fa->z,fa->n,fa->f,fa->p); boxflist(fl,str); } }
void addflist(flist_t **fl,char *loc,char *rem,char kill,off_t off,FILE *lo,int fromlo) { flist_t **t,*q; int type; slist_t *i; DEBUG(('S',2,"Add file: '%s', sendas: '%s', kill: '%c', fromLO: %s, offset: %d", loc,rem?rem:"(null)",kill,lo?"yes":"no",off)); type=whattype(rem); if(type==IS_PKT&&fromlo)type=IS_FILE; if((checktimegaps(cfgs(CFG_MAILONLY))|| checktimegaps(cfgs(CFG_ZMH)))&&type!=IS_PKT)return; for(i=cfgsl(CFG_AUTOHOLD);i;i=i->next) if(!xfnmatch(i->str,loc,FNM_PATHNAME))return; switch(type) { case IS_REQ: if(rnode&&rnode->options&O_HRQ)return; if(rnode&&rnode->options&O_NRQ&&!cfgi(CFG_IGNORENRQ))return; break; case IS_PKT: if(rnode&&rnode->options&O_HAT)return; break; default: if(rnode&&rnode->options&(O_HXT|O_HAT)&&rem)return; break; } for(t=fl;*t&&((*t)->type<=type);t=&((*t)->next)); q=(flist_t*)xmalloc(sizeof(flist_t)); q->next=*t;*t=q; if(fromlo&&kill=='#'&&cfgi(CFG_ALWAYSKILLFILES))q->kill='^'; else q->kill=kill; q->loff=off; if(rnode&&(rnode->options&O_FNC)&&rem) { q->sendas=xstrdup(fnc(rem)); xfree(rem); } else q->sendas=rem; q->lo=lo;q->tosend=loc; q->type=type; }
void parse_log_levels(void) { char *w, *levels = xstrdup( cfgs( CFG_LOGLEVELS )), *lvrun; int c; memset( facilities_levels, 0, sizeof( facilities_levels )); lvrun = levels; while(( w = strsep( &lvrun, ",;" ))) { c = *w++; if ( *w ) facilities_levels[c] = atoi( w ); } xfree( levels ); }
void tty_unlock(char *port) { int pid; FILE *f; char *p,lckname[MAX_PATH]; DEBUG(('M',4,"tty_unlock")); if(!(p=strrchr(port,'/')))p=port; else p++; snprintf(lckname,MAX_PATH,"%s/LCK..%s",cfgs(CFG_LOCKDIR),p); if((f=fopen(lckname,"r"))) { fscanf(f,"%d",&pid); fclose(f); } if(pid==getpid())lunlink(lckname); }
static int reset() { slist_t *hc; int rc=MC_OK; if(!cfgsl(CFG_MODEMRESET)) return MC_OK; write_log("resetting modem..."); for(hc=ccsl;hc && rc==MC_OK;hc=hc->next) rc=modem_chat(hc->str,cfgsl(CFG_MODEMOK),cfgsl(CFG_MODEMNODIAL), cfgsl(CFG_MODEMERROR),cfgsl(CFG_MODEMBUSY), cfgs(CFG_MODEMRINGING),cfgi(CFG_MAXRINGS), cfgi(CFG_WAITRESET),NULL,0); if(rc!=MC_OK) write_log("modem reset failed, rc=%d [%s]",rc,mcs[rc]); return rc; }
int tty_isfree(char *port,char *nodial) { int pid; FILE *f; struct stat s; char lckname[MAX_PATH]; snprintf(lckname,MAX_PATH,"%s.%s",nodial,port); if(!stat(lckname,&s)) return 0; snprintf(lckname,MAX_PATH,"%s/LCK..%s",cfgs(CFG_LOCKDIR),port); if((f=fopen(lckname,"r"))) { fscanf(f,"%d",&pid); fclose(f); if(kill(pid,0)&&(errno==ESRCH)) { lunlink(lckname); return 1; } return 0; } return 1; }
void chatlog_write(char *text,int side) { FILE *chatlog=NULL; long i,n,m; char quot[2]={0},*tmp,*cbuf=side?rchat:mchat,tm; if(side)*quot='>'; else *quot=' '; if(text&&*text) { xstrcpy(cbuf+(side?rcpos:mcpos),text,CHATLOG_BUF-(side?rcpos:mcpos)-1); if(side)rcpos+=strlen(text); else mcpos+=strlen(text); while((side?rcpos:mcpos)&&(tmp=strchr(cbuf,'\n'))) { i=n=m=0; while(i<(tmp-cbuf+1))if(cbuf[i]=='\b'){i++;m+=2;if((--n)<0){n=0;m--;}} else cbuf[n++]=cbuf[i++]; if(n&&cfgs(CFG_CHATLOG)) { chatlog=fopen(ccs,"at"); fwrite(quot,1,1,chatlog); fwrite(cbuf,1,n,chatlog); fclose(chatlog); } if(n&&lemail) { fwrite(quot,1,1,lemail); fwrite(cbuf,1,n,lemail); } if(n&&cpkt) { for(i=0;i<n;i++) { if(cbuf[i]=='\n')cbuf[i]='\r'; if(cbuf[i]==7)cbuf[i]='*'; } tm=cbuf[i];cbuf[i]=0; if(cfgi(CFG_RECODEPKTS))recode_to_remote(cbuf); cbuf[i]=tm; fwrite(quot,1,1,cpkt); fwrite(cbuf,1,n,cpkt); } if(cbuf[n])xstrcpy(cbuf,cbuf+n,CHATLOG_BUF-6); if(side)rcpos-=(n+m); else mcpos-=(n+m); } } }
int hangup() { slist_t *hc; int rc=MC_FAIL,to=t_set(cfgi(CFG_WAITRESET)); if(!cfgsl(CFG_MODEMHANGUP))return MC_OK; write_log("hanging up..."); while(rc!=MC_OK&&!t_exp(to)) { for(hc=cfgsl(CFG_MODEMHANGUP);hc;hc=hc->next) { rc=modem_chat(hc->str,cfgsl(CFG_MODEMOK),cfgsl(CFG_MODEMNODIAL), cfgsl(CFG_MODEMERROR),cfgsl(CFG_MODEMBUSY), cfgs(CFG_MODEMRINGING),cfgi(CFG_MAXRINGS), t_rest(to),NULL,0); } if(rc!=MC_OK)sleep(1); tty_purge(); rc=alive(); tty_purge(); } #ifdef NEED_DEBUG if(rc!=MC_OK)DEBUG(('M',3,"hangup: failed, rc=%d [%s]",rc,mcs[rc])); #endif return rc; }
RETSIGTYPE sigerr(int sig) { signal(sig,SIG_DFL); aso_done(); write_log("got SIG%s signal",sigs[sig]); if(cfgs(CFG_PIDFILE))if(getpid()==islocked(ccs))lunlink(ccs); IFPerl(perl_done(1)); log_done(); tty_close(); qqreset();sline("");title(""); cls_close(ssock); cls_shutd(lins_sock); cls_shutd(uis_sock); switch(sig) { case SIGSEGV: case SIGFPE: case SIGBUS: case SIGABRT: abort(); default: exit(1); } }
/* * Open connection via socks. Returns TRUE if OK, FALSE if fail. */ static int tcp_connect_socks(char *name) { int rc, i, port; char *n, *p = NULL, *auth = NULL; char buf[MAX_STRING + 5]; struct in_addr da; struct hostent *he; if ( cfgs( CFG_SOCKS ) && ( p = strchr( ccs, ' ' ))) *p++ = 0; if ( !( n = strchr( name, ':' ))) port = bink ? 24554 : 60179; else port = atoi( n + 1 ); if ( p ) { auth = xstrdup( p ); *buf = 5; buf[2] = '\0'; n = strchr( auth, ' ' ); if ( *auth == '*' ) { buf[1] = 1; PUTBLK( (unsigned char*) buf, 3 ); } else { buf[1] = 2; buf[3]= n ? 2 : 1; PUTBLK( (unsigned char*) buf, 4 ); } rc = GETCHAR( 60 ); if ( rc > 0 ) { *buf = rc; rc = GETCHAR( 10 ); buf[1] = rc; } IFOFFLINE if ( buf[1] && buf[1] != 1 && buf[1] != 2 ) { write_log("Auth. method is not supported by server"); xfree( auth ); return (FALSE); } DEBUG(('I',2,"socks5 auth=%d", buf[1])); if ( buf[1] == 2) { *buf = 1; if ( !n ) i = strlen( auth ); else i = n - auth; buf[1] = i; memcpy( buf + 2, auth, i ); i += 2; if ( !n ) buf[i++] = '\0'; else { n++; buf[i] = strlen( n ); xstrcpy( buf + i + 1, n, buf[i] ); i += buf[i] + 1; } PUTBLK( (unsigned char*) buf, i ); rc = GETCHAR( 40 ); if( rc > 0) { *buf = rc; rc = GETCHAR( 10 ); buf[1] = rc; } IFOFFLINE if ( buf[1] ) { write_log("Auth. failed (socks5 returns %02x%02x)", (unsigned char) buf[0], (unsigned char) buf[1] ); xfree( auth ); return (FALSE); } } }
/* * Open connection via proxy. Returns TRUE if OK, FALSE if fail. */ static int tcp_connect_proxy(char *name) { int rc, i; time_t t1; char buf[H_BUF]; char *n, *p = NULL, *dp = ""; if ( cfgs( CFG_PROXY ) && ( p = strchr( ccs, ' ' ))) *p++ = 0; if ( !strchr( name, ':' )) dp = bink ? ":24554" : ":60179"; i = snprintf( buf, H_BUF, "CONNECT %s%s HTTP/1.0\r\n", name, dp ); if ( p ) { if (( n = strchr( p,' ' ))) *n = ':'; i += snprintf( buf + i, H_BUF - i, "Proxy-Authorization: basic " ); i += base64( p, strlen( p ), buf + i ); buf[i++] = '\r'; buf[i++] = '\n'; } buf[i++] = '\r'; buf[i++] = '\n'; PUTBLK( (unsigned char*) buf, i ); t1 = timer_set( cfgi( CFG_HSTIMEOUT )); for( i = 0; i < H_BUF; i++ ) { while(( rc = GETCHAR(1)) == TIMEOUT && !timer_expired( t1 )) getevt(); if ( rc == RCDO || tty_gothup ) { write_log( "got hangup" ); return (FALSE); } if ( rc == TIMEOUT ) { write_log( "proxy timeout" ); return (FALSE); } else if ( rc < 0 ) { write_log("connection is closed by proxy"); return (FALSE); } buf[i] = rc; buf[i + 1] = '\0'; if (( i >= H_BUF ) || (( p = strstr( buf, "\r\n\r\n" )))) { if (( p = strchr( buf, '\n' ))) { *p-- = '\0'; if ( *p == '\r' ) *p = '\0'; } p = buf; if ( strstr( buf, " 200 " )) break; if ( !strncasecmp( buf, "HTTP", 4 )) p = strchr( buf, ' ' ) + 1; write_log( "connect rejected by proxy (%s)", p ); return (FALSE); } } return (TRUE); }
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;});
int freq_ifextrp(slist_t *reqs) { FILE *f, *g, *r; char s[MAX_PATH], fn[MAX_PATH], sfn[MAX_PATH], *ss; char priv = 'a', *p, *sprt = "UNPROTEC", *slst = "UNLIS"; int got = 0, wz = cfgs( CFG_EXTRP ) ? 1 : 0, kil; long tpid = (long) getpid(); ftnaddr_t *ma = akamatch( &rnode->addrs->addr, cfgal( CFG_ADDRESS )); DEBUG(('R',1,"Freq received")); if ( rnode->options & O_LST ) { priv = 'l'; slst += 2; } if( rnode->options & O_PWD ) { priv = 'p'; sprt += 2; } snprintf( fn, MAX_PATH, "/tmp/qreq.%04lx", tpid ); if( !( f = fopen( fn, "wt" ))) { write_log( "can't open '%s' for writing: %s", fn, strerror( errno )); return 0; } while( reqs ) { if ( cfgs( CFG_MAPIN ) && strchr( ccs, 'r' )) recode_to_local( reqs->str ); DEBUG(('R',1,"requested '%s'", reqs->str)); fprintf( f, "%s\n", reqs->str ); reqs = reqs->next; } fclose( f ); if(!wz) { falist_t *ra; snprintf(sfn,MAX_PATH,"/tmp/qsrif.%04lx",tpid); if(!(r=fopen(sfn,"wt"))){write_log("can't open '%s' for writing: %s",sfn,strerror(errno));return 0;} fprintf(r,"SessionType %s\n",bink?"OTHER":"EMSI"); fprintf(r,"Sysop %s\n",rnode->sysop); for(ra=rnode->addrs;ra;ra=ra->next)fprintf(r,"AKA %s\n",ftnaddrtoa(&ra->addr)); if(!is_ip)fprintf(r,"Baud %d\n",rnode->realspeed); fprintf(r,"Time -1\n"); fprintf(r,"RemoteStatus %sTED\n",sprt); fprintf(r,"SystemStatus %sTED\n",slst); fprintf(r,"RequestList /tmp/qreq.%04lx\n",tpid); fprintf(r,"ResponseList /tmp/qfls.%04lx\n",tpid); fprintf(r,"Location %s\n",rnode->place); if(rnode->phone&&*rnode->phone)fprintf(r,"Phone %s\n",rnode->phone); if(rnode->options&O_PWD)fprintf(r,"Password %s\n",rnode->pwd); fprintf(r,"Mailer %s\n",rnode->mailer); fprintf(r,"Site %s\n",rnode->name); if(!is_ip&&(ss=getenv("CALLER_ID"))&&strcasecmp(ss,"none")&&strlen(ss)>3)fprintf(r,"CallerID %s\n",ss); fprintf(r,"OurAKA %s\n",ftnaddrtoa(ma)); fprintf(r,"TRANX %08lu\n",time(NULL)); fclose(r); snprintf(s,MAX_PATH,"%s %s",cfgs(CFG_SRIFRP),sfn); } else snprintf(s,MAX_PATH,"%s -wazoo -%c -s%d %s /tmp/qreq.%04lx /tmp/qfls.%04lx /tmp/qrep.%04lx", cfgs(CFG_EXTRP),priv,rnode->realspeed,ftnaddrtoa(&rnode->addrs->addr),tpid,tpid,tpid); write_log("exec '%s' returned rc=%d",s,execsh(s)); lunlink(fn);lunlink(sfn); snprintf(fn,MAX_PATH,"/tmp/qfls.%04lx",tpid); if(!(f=fopen(fn,"rt"))) { snprintf(fn,MAX_PATH,"/tmp/qrep.%04lx",tpid); lunlink(fn); snprintf(fn,MAX_PATH,"/tmp/qfls.%04lx",tpid); lunlink(fn); write_log("can't open '%s' for reading",fn); return 0; } while(fgets(s,MAX_PATH-1,f)) { if(*s=='\n'||*s=='\r'||*s==' '||!*s)continue; ss=s;kil=0;got=1; if(*s=='='||*s=='-'){ss++;kil=1;} else if(*s=='+')ss++; p=ss+strlen(ss)-1; while(*p=='\r'||*p=='\n')*p--=0; p=strrchr(ss,' '); if(p)*p++=0;else p=ss; DEBUG(('R',1,"sending '%s' as '%s'%s",ss,qbasename((p!=ss)?p:ss),kil?" and kill":"")); addflist(&fl,xstrdup(ss),xstrdup(qbasename((p!=ss)?p:ss)),kil?'^':' ',0,NULL,0); } fclose(f);lunlink(fn); snprintf(fn,MAX_PATH,"/tmp/qrep.%04lx",tpid); if(!(f=fopen(fn,"rt"))&&wz)write_log("can't open '%s' for reading",fn); snprintf(fn,MAX_PATH,"/tmp/qpkt.%04lx%02x",tpid,++freq_pktcount); g=openpktmsg(ma,&rnode->addrs->addr,cfgs(CFG_FREQFROM),rnode->sysop,cfgs(CFG_FREQSUBJ),NULL,fn,1); if(!g) { write_log("can't open '%s' for writing: %s",fn,strerror(errno)); if(f)fclose(f); freq_pktcount--; } if(f&&g) { while(fgets(s,MAX_PATH-1,f)) { p=s+strlen(s)-1; while(*p=='\r'||*p=='\n')*p--=0; if(cfgi(CFG_RECODEPKTS))recode_to_remote(s); fputs(s,g);fputc('\r',g); } fclose(f); closeqpkt(g,ma); snprintf(s,MAX_PATH,"/tmp/qpkt.%04lx%02x",tpid,freq_pktcount); p=xstrdup(s); snprintf(s,MAX_PATH,"%08lx.pkt",sequencer()); addflist(&fl,p,xstrdup(s),'^',0,NULL,1); } snprintf(fn,MAX_PATH,"/tmp/qrep.%04lx",tpid); lunlink(fn); return got; }
GLXPixmap GLXLibrary::CreatePixmap(gfxASurface* aSurface) { if (!SupportsTextureFromPixmap(aSurface)) { return None; } gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(aSurface); const XRenderPictFormat *format = xs->XRenderFormat(); if (!format || format->type != PictTypeDirect) { return None; } const XRenderDirectFormat& direct = format->direct; int alphaSize = FloorLog2(direct.alphaMask + 1); NS_ASSERTION((1 << alphaSize) - 1 == direct.alphaMask, "Unexpected render format with non-adjacent alpha bits"); int attribs[] = { LOCAL_GLX_DOUBLEBUFFER, False, LOCAL_GLX_DRAWABLE_TYPE, LOCAL_GLX_PIXMAP_BIT, LOCAL_GLX_ALPHA_SIZE, alphaSize, (alphaSize ? LOCAL_GLX_BIND_TO_TEXTURE_RGBA_EXT : LOCAL_GLX_BIND_TO_TEXTURE_RGB_EXT), True, LOCAL_GLX_RENDER_TYPE, LOCAL_GLX_RGBA_BIT, None }; int numConfigs = 0; Display *display = xs->XDisplay(); int xscreen = DefaultScreen(display); ScopedXFree<GLXFBConfig> cfgs(xChooseFBConfig(display, xscreen, attribs, &numConfigs)); // Find an fbconfig that matches the pixel format used on the Pixmap. int matchIndex = -1; unsigned long redMask = static_cast<unsigned long>(direct.redMask) << direct.red; unsigned long greenMask = static_cast<unsigned long>(direct.greenMask) << direct.green; unsigned long blueMask = static_cast<unsigned long>(direct.blueMask) << direct.blue; // This is true if the Pixmap has bits for alpha or unused bits. bool haveNonColorBits = ~(redMask | greenMask | blueMask) != -1UL << format->depth; for (int i = 0; i < numConfigs; i++) { int id = None; sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_VISUAL_ID, &id); Visual *visual; int depth; FindVisualAndDepth(display, id, &visual, &depth); if (!visual || visual->c_class != TrueColor || visual->red_mask != redMask || visual->green_mask != greenMask || visual->blue_mask != blueMask ) { continue; } // Historically Xlib Visuals did not try to represent an alpha channel // and there was no means to use an alpha channel on a Pixmap. The // Xlib Visual from the fbconfig was not intended to have any // information about alpha bits. // // Since then, RENDER has added formats for 32 bit depth Pixmaps. // Some of these formats have bits for alpha and some have unused // bits. // // Then the Composite extension added a 32 bit depth Visual intended // for Windows with an alpha channel, so bits not in the visual color // masks were expected to be treated as alpha bits. // // Usually GLX counts only color bits in the Visual depth, but the // depth of Composite's ARGB Visual includes alpha bits. However, // bits not in the color masks are not necessarily alpha bits because // sometimes (NVIDIA) 32 bit Visuals are added for fbconfigs with 32 // bit BUFFER_SIZE but zero alpha bits and 24 color bits (NVIDIA // again). // // This checks that the depth matches in one of the two ways. // NVIDIA now forces format->depth == depth so only the first way // is checked for NVIDIA if (depth != format->depth && (mIsNVIDIA || depth != format->depth - alphaSize) ) { continue; } // If all bits of the Pixmap are color bits and the Pixmap depth // matches the depth of the fbconfig visual, then we can assume that // the driver will do whatever is necessary to ensure that any // GLXPixmap alpha bits are treated as set. We can skip the // ALPHA_SIZE check in this situation. We need to skip this check for // situations (ATI) where there are no fbconfigs without alpha bits. // // glXChooseFBConfig should prefer configs with smaller // LOCAL_GLX_BUFFER_SIZE, so we should still get zero alpha bits if // available, except perhaps with NVIDIA drivers where buffer size is // not the specified sum of the component sizes. if (haveNonColorBits) { // There are bits in the Pixmap format that haven't been matched // against the fbconfig visual. These bits could either represent // alpha or be unused, so just check that the number of alpha bits // matches. int size = 0; sGLXLibrary[mLibType].xGetFBConfigAttrib(display, cfgs[i], LOCAL_GLX_ALPHA_SIZE, &size); if (size != alphaSize) { continue; } } matchIndex = i; break; } if (matchIndex == -1) { // GLX can't handle A8 surfaces, so this is not really unexpected. The // caller should deal with this situation. NS_WARN_IF_FALSE(format->depth == 8, "[GLX] Couldn't find a FBConfig matching Pixmap format"); return None; } int pixmapAttribs[] = { LOCAL_GLX_TEXTURE_TARGET_EXT, LOCAL_GLX_TEXTURE_2D_EXT, LOCAL_GLX_TEXTURE_FORMAT_EXT, (alphaSize ? LOCAL_GLX_TEXTURE_FORMAT_RGBA_EXT : LOCAL_GLX_TEXTURE_FORMAT_RGB_EXT), None}; GLXPixmap glxpixmap = xCreatePixmap(display, cfgs[matchIndex], xs->XDrawable(), pixmapAttribs); return glxpixmap; }
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; }
static void answer_mode(int type) { int rc, spd;char *cs; struct sockaddr_in sa; socklen_t ss=sizeof(sa); sts_t sts; if(cfgs(CFG_ROOTDIR)&&ccs[0])chdir(ccs); rnode=xcalloc(1,sizeof(ninfo_t)); is_ip=!isatty(0); xstrcpy(ip_id,"ipline",10); rnode->tty=xstrdup(is_ip?(bink?"binkp":"tcpip"):basename(ttyname(0))); rnode->options|=O_INB; if(!log_init(cfgs(CFG_LOG),rnode->tty)) { printf("can't open log %s!\n",ccs); exit(S_FAILURE); } signal(SIGINT,SIG_IGN); signal(SIGTERM,sigerr); signal(SIGSEGV,sigerr); signal(SIGFPE,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); } write_log("answering incoming call");vidle(); if(is_ip&&!getpeername(0,(struct sockaddr*)&sa,&ss)) { write_log("remote is %s",inet_ntoa(sa.sin_addr)); spd=TCP_SPEED; } else { cs=getenv("CONNECT");spd=cs?atoi(cs):0; xfree(connstr);connstr=xstrdup(cs); if(cs&&spd)write_log("*** CONNECT %s",cs); else { write_log("*** CONNECT Unknown"); spd=DEFAULT_SPEED; } } if((cs=getenv("CALLER_ID"))&&strcasecmp(cs,"none")&&strlen(cs)>3)write_log("caller-id: %s",cs); tty_setattr(0); tty_local(0); rc=session(0,type,NULL,spd); tty_local(1); if(!is_ip) { hangup(); stat_collect(); } tty_cooked(); if((S_OK==(rc&S_MASK))&&cfgi(CFG_HOLDONSUCCESS)) { log_done(); log_init(cfgs(CFG_MASTERLOG),NULL); aso_getstatus(&rnode->addrs->addr, &sts); sts.flags|=(Q_WAITA|Q_WAITR|Q_WAITX); sts.htime=MAX(t_set(cci*60),sts.htime); write_log("calls to %s delayed for %d min after successful incoming session", ftnaddrtoa(&rnode->addrs->addr),cci); aso_setstatus(&rnode->addrs->addr,&sts); log_done(); log_init(cfgs(CFG_LOG),rnode->tty); } title("Waiting..."); vidle();sline(""); aso_done(); stopit(rc); }
bool EGLInteropResource::ensureD3D9EGL(int w, int h) { if (surface9 && res[0].w == w && res[0].h == h) return true; #if QTAV_HAVE(GUI_PRIVATE) QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); egl->dpy = static_cast<EGLDisplay>(nativeInterface->nativeResourceForContext("eglDisplay", QOpenGLContext::currentContext())); EGLConfig egl_cfg = static_cast<EGLConfig>(nativeInterface->nativeResourceForContext("eglConfig", QOpenGLContext::currentContext())); #else #ifdef Q_OS_WIN #if QT_VERSION < QT_VERSION_CHECK(5, 5, 0) #ifdef _MSC_VER #pragma message("ANGLE version in Qt<5.5 does not support eglQueryContext. You must upgrade your runtime ANGLE libraries") #else #warning "ANGLE version in Qt<5.5 does not support eglQueryContext. You must upgrade your runtime ANGLE libraries" #endif //_MSC_VER #endif #endif //Q_OS_WIN // eglQueryContext() added (Feb 2015): https://github.com/google/angle/commit/8310797003c44005da4143774293ea69671b0e2a egl->dpy = eglGetCurrentDisplay(); qDebug("EGL version: %s, client api: %s", eglQueryString(egl->dpy, EGL_VERSION), eglQueryString(egl->dpy, EGL_CLIENT_APIS)); // TODO: check runtime egl>=1.4 for eglGetCurrentContext() EGLint cfg_id = 0; EGL_ENSURE(eglQueryContext(egl->dpy, eglGetCurrentContext(), EGL_CONFIG_ID , &cfg_id) == EGL_TRUE, false); qDebug("egl config id: %d", cfg_id); EGLint nb_cfg = 0; EGL_ENSURE(eglGetConfigs(egl->dpy, NULL, 0, &nb_cfg) == EGL_TRUE, false); qDebug("eglGetConfigs number: %d", nb_cfg); QVector<EGLConfig> cfgs(nb_cfg); //check > 0 EGL_ENSURE(eglGetConfigs(egl->dpy, cfgs.data(), cfgs.size(), &nb_cfg) == EGL_TRUE, false); EGLConfig egl_cfg = NULL; for (int i = 0; i < nb_cfg; ++i) { EGLint id = 0; eglGetConfigAttrib(egl->dpy, cfgs[i], EGL_CONFIG_ID, &id); if (id == cfg_id) { egl_cfg = cfgs[i]; break; } } #endif qDebug("egl display:%p config: %p", egl->dpy, egl_cfg); // check extensions QList<QByteArray> extensions = QByteArray(eglQueryString(egl->dpy, EGL_EXTENSIONS)).split(' '); // ANGLE_d3d_share_handle_client_buffer will be used if possible const bool kEGL_ANGLE_d3d_share_handle_client_buffer = extensions.contains("EGL_ANGLE_d3d_share_handle_client_buffer"); const bool kEGL_ANGLE_query_surface_pointer = extensions.contains("EGL_ANGLE_query_surface_pointer"); if (!kEGL_ANGLE_d3d_share_handle_client_buffer && !kEGL_ANGLE_query_surface_pointer) { qWarning("EGL extension 'kEGL_ANGLE_query_surface_pointer' or 'ANGLE_d3d_share_handle_client_buffer' is required!"); return false; } GLint has_alpha = 1; //QOpenGLContext::currentContext()->format().hasAlpha() eglGetConfigAttrib(egl->dpy, egl_cfg, EGL_BIND_TO_TEXTURE_RGBA, &has_alpha); //EGL_ALPHA_SIZE EGLint attribs[] = { EGL_WIDTH, w, EGL_HEIGHT, h, EGL_TEXTURE_FORMAT, has_alpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB, EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, EGL_NONE }; HANDLE share_handle = NULL; if (!kEGL_ANGLE_d3d_share_handle_client_buffer && kEGL_ANGLE_query_surface_pointer) { EGL_ENSURE((egl->surface = eglCreatePbufferSurface(egl->dpy, egl_cfg, attribs)) != EGL_NO_SURFACE, false); qDebug("pbuffer surface: %p", egl->surface); PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE = reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>(eglGetProcAddress("eglQuerySurfacePointerANGLE")); if (!eglQuerySurfacePointerANGLE) { qWarning("EGL_ANGLE_query_surface_pointer is not supported"); return false; } EGL_ENSURE(eglQuerySurfacePointerANGLE(egl->dpy, egl->surface, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle), false); } SafeRelease(&surface9); SafeRelease(&texture9); // _A8 for a yuv plane /* * d3d resource share requires windows >= vista: https://msdn.microsoft.com/en-us/library/windows/desktop/bb219800(v=vs.85).aspx * from extension files: * d3d9: level must be 1, dimensions must match EGL surface's * d3d9ex or d3d10: */ DX_ENSURE(device9->CreateTexture(w, h, 1, D3DUSAGE_RENDERTARGET, has_alpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8, D3DPOOL_DEFAULT, &texture9, &share_handle) , false); DX_ENSURE(texture9->GetSurfaceLevel(0, &surface9), false); if (kEGL_ANGLE_d3d_share_handle_client_buffer) { // requires extension EGL_ANGLE_d3d_share_handle_client_buffer // egl surface size must match d3d texture's // d3d9ex or d3d10 is required EGL_ENSURE((egl->surface = eglCreatePbufferFromClientBuffer(egl->dpy, EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, share_handle, egl_cfg, attribs)), false); qDebug("pbuffer surface from client buffer: %p", egl->surface); } return true; }