Newer
Older

rswindell
committed
close(in_pipe[1]); /* close write-end of pipe */
dup2(in_pipe[0],0); /* redirect stdin */
close(in_pipe[0]); /* close excess file descriptor */
}

rswindell
committed
if(mode&EX_OUTR) {

rswindell
committed
close(out_pipe[0]); /* close read-end of pipe */
dup2(out_pipe[1],1); /* stdout */
dup2(out_pipe[1],2); /* stderr */
close(out_pipe[1]); /* close excess file descriptor */

rswindell
committed
}
sprintf(str,"!ERROR %d executing %s",errno,argv[0]);
errorlog(str);
exit(-1); /* should never get here */

rswindell
committed
if(mode&EX_OUTR) {
close(out_pipe[1]); /* close write-end of pipe */
while(!terminated) {

rswindell
committed
if(waitpid(pid, &i, WNOHANG)!=0) /* child exited */
break;
if(mode&EX_CHKTIME)
gettimeleft();

rswindell
committed
if(!online && !(mode&EX_OFFLINE)) {
sprintf(str,"%s hung-up in external program",useron.alias);
logline("X!",str);
break;
}

rswindell
committed
/* Input */
if(mode&EX_INR && RingBufFull(&inbuf)) {
if((wr=RingBufRead(&inbuf,buf,sizeof(buf)))!=0)
write(in_pipe[1],buf,wr);
}
/* Output */
ioctl(out_pipe[0],FIONREAD,&rd); /* peek at input */
if(!rd) {
mswait(1);
continue;
}
avail=RingBufFree(&outbuf);
if(avail==0) {
lprintf("Node %d !output buffer full (%u bytes)"
,cfg.node_num,RingBufFull(&outbuf));
mswait(1);
continue;
}
if(rd>avail)
rd=avail;
rd=sizeof(buf);
if((rd=read(out_pipe[0],buf,rd))<1) {

rswindell
committed
mswait(1);
continue;
}
if(mode&EX_BIN) /* telnet IAC expansion */
bp=telnet_expand(buf, rd, output_buf, output_len);

rswindell
committed
else /* LF to CRLF expansion */
bp=lf_expand(buf, rd, output_buf, output_len);
/* Does expanded size fit? */
if(output_len>RingBufFree(&outbuf)) {
lprintf("Node %d !output buffer overflow (%u bytes)"
,cfg.node_num,output_len);
mswait(1);
continue;
}

rswindell
committed
RingBufWrite(&outbuf, bp, output_len);
sem_post(&output_sem);
}
if(waitpid(pid, &i, WNOHANG)==0) { // Child still running?
kill(pid, SIGHUP); // Tell child user has hung up
time_t start=time(NULL); // Wait up to 10 seconds
while(time(NULL)-start<10) { // for child to terminate
if(waitpid(pid, &i, WNOHANG)!=0)
break;
mswait(500);
}
if(waitpid(pid, &i, WNOHANG)==0) // Child still running?
kill(pid, SIGKILL); // terminate child process
}
/* close unneeded descriptors */
if(mode&EX_INR)
close(in_pipe[1]);
close(out_pipe[0]);

rswindell
committed
}

rswindell
committed
if(!(mode&EX_BG)) /* !background execution, wait for child to terminate */
waitpid(pid, &i, 0);
pthread_mutex_unlock(&input_thread_mutex);
return(WEXITSTATUS(i));
}
#endif /* !WIN32 */
uint fakeriobp=0xffff;
/*****************************************************************************/
/* Returns command line generated from instr with %c replacments */
/*****************************************************************************/
char * sbbs_t::cmdstr(char *instr, char *fpath, char *fspec, char *outstr)
{
char str[256],*cmd;
int i,j,len;
if(outstr==NULL)
cmd=cmdstr_output;
else
cmd=outstr;
len=strlen(instr);
for(i=j=0;i<len && j<sizeof(cmdstr_output);i++) {
if(instr[i]=='%') {
i++;
cmd[j]=0;
char ch=instr[i];
if(isalpha(ch))
ch=toupper(ch);
switch(ch) {
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
case 'A': /* User alias */
strcat(cmd,useron.alias);
break;
case 'B': /* Baud (DTE) Rate */
strcat(cmd,ultoa(dte_rate,str,10));
break;
case 'C': /* Connect Description */
strcat(cmd,connection);
break;
case 'D': /* Connect (DCE) Rate */
strcat(cmd,ultoa((ulong)cur_rate,str,10));
break;
case 'E': /* Estimated Rate */
strcat(cmd,ultoa((ulong)cur_cps*10,str,10));
break;
case 'F': /* File path */
strcat(cmd,fpath);
break;
case 'G': /* Temp directory */
strcat(cmd,cfg.temp_dir);
break;
case 'H': /* Port Handle or Hardware Flow Control */
#if defined(__unix__)
strcat(cmd,ultoa(client_socket,str,10));
#else
strcat(cmd,ultoa(client_socket_dup,str,10));
#endif
break;
case 'I': /* UART IRQ Line */
strcat(cmd,ultoa(cfg.com_irq,str,10));
break;
case 'J':
strcat(cmd,cfg.data_dir);
break;
case 'K':
strcat(cmd,cfg.ctrl_dir);
break;
case 'L': /* Lines per message */
strcat(cmd,ultoa(cfg.level_linespermsg[useron.level],str,10));
break;
case 'M': /* Minutes (credits) for user */
strcat(cmd,ultoa(useron.min,str,10));
break;
case 'N': /* Node Directory (same as SBBSNODE environment var) */
strcat(cmd,cfg.node_dir);
break;
case 'O': /* SysOp */
strcat(cmd,cfg.sys_op);
break;
case 'P': /* COM Port */
strcat(cmd,ultoa(online==ON_LOCAL ? 0:cfg.com_port,str,10));
break;
case 'Q': /* QWK ID */
strcat(cmd,cfg.sys_id);
break;
case 'R': /* Rows */
break;
case 'S': /* File Spec */
strcat(cmd,fspec);
break;
case 'T': /* Time left in seconds */
gettimeleft();
strcat(cmd,ultoa(timeleft,str,10));
break;
case 'U': /* UART I/O Address (in hex) */
strcat(cmd,ultoa(cfg.com_base,str,16));
break;
case 'V': /* Synchronet Version */
sprintf(str,"%s%c",VERSION,REVISION);
break;
case 'W': /* Time-slice API type (mswtype) */
#if 0 //ndef __FLAT__
#endif
break;
case 'X':
strcat(cmd,cfg.shell[useron.shell]->code);
break;
case '&': /* Address of msr */
sprintf(str,"%lu",&fakeriobp);
strcat(cmd,str);
break;
case 'Y':
strcat(cmd,comspec);
break;
case 'Z':
strcat(cmd,cfg.text_dir);
break;
case '~': /* DOS-compatible (8.3) filename */
#ifdef _WIN32
char sfpath[MAX_PATH+1];
SAFECOPY(sfpath,fpath);
GetShortPathName(fpath,sfpath,sizeof(sfpath));
strcat(cmd,sfpath);
#else
strcat(cmd,fpath);
#endif
break;
case '!': /* EXEC Directory */
strcat(cmd,cfg.exec_dir);
break;
case '#': /* Node number (same as SBBSNNUM environment var) */
sprintf(str,"%d",cfg.node_num);
strcat(cmd,str);
break;
case '*':
sprintf(str,"%03d",cfg.node_num);
strcat(cmd,str);
break;
case '$': /* Credits */
strcat(cmd,ultoa(useron.cdt+useron.freecdt,str,10));
break;
case '%': /* %% for percent sign */
strcat(cmd,"%");
break;
case '.': /* .exe for DOS/OS2/Win32, blank for Unix */
#ifndef __unix__
strcat(cmd,".exe");
#endif
break;
case '?': /* Platform */
#ifdef __OS2__
strcpy(str,"OS2");
#else
strcpy(str,PLATFORM_DESC);
#endif
strlwr(str);
strcat(cmd,str);
break;
default: /* unknown specification */
if(isdigit(instr[i])) {
sprintf(str,"%0*d",instr[i]&0xf,useron.number);
strcat(cmd,str); }
break; }
j=strlen(cmd); }
else
cmd[j++]=instr[i]; }
cmd[j]=0;
return(cmd);
}