📄 gcomm.c
字号:
else if( strchr(arg, '\'') == NULL ) /* can we just quote it all? */ { gstrcat(programArgs, "'", MAXARGS) ; gstrcat(programArgs, arg, MAXARGS) ; gstrcat(programArgs, "'", MAXARGS) ; } else if( strchr(arg, '"') == NULL ) /* try double quotes */ { gstrcat(programArgs, "\"", MAXARGS) ; gstrcat(programArgs, arg, MAXARGS) ; gstrcat(programArgs, "\"", MAXARGS) ; } else /* cripes, do it char-by-char */ { char *optr = programArgs + strlen(programArgs) ; while( *arg != '\0' ) { if( isspace(*arg) || *arg == '\'' || *arg == '"' || *arg == '\\' ) *optr++ = '\\' ; *optr++ = *arg++ ; } }}static voidaddProgArgs(int *argc, char ***argv){ int argc2 = *argc ; char **argv2 = *argv ; programArgs = malloc(MAXARGS) ; *programArgs = '\0' ; addProgArg(*argv2) ; while( --argc2 > 0 && !streq(*++argv2,";") ) addProgArg(*argv2) ; connectionType = ConnectionPipe ; haveHost = 1 ; *argc = argc2 ; *argv = argv2 ;} /* parse -net argument */static voidnetworkArg(char *host){ char *ptr ; hostName = strdup(host) ; if( (ptr = strrchr(hostName, ':')) != NULL ) { *ptr++ = '\0' ; hostPort = ptr ; } connectionType = ConnectionNet ; if( hostPort == NULL || PortLookup(hostPort) != -1 ) haveHost = 1 ;}intPortLookup(char *portname){ struct servent *svc ; while( isspace(*portname) ) ++portname ; if( *portname == '\0' ) return TelnetPort ; if( isdigit(*portname) ) return atoi(portname) ; if( (svc = getservbyname(portname, "tcp")) != NULL ) return ntohs(svc->s_port) ; return -1 ;} /* PARSE /etc/remote ENTRIES */ /* utility, open $HOME/file */static FILE *fopenHome(char *file, char *type){ char filename[MAXPATHLEN] ; char *env = getenv("HOME") ; if( env == NULL ) return NULL ; sprintf(filename, "%s/%s", env, file) ; return fopen(filename, type) ;} /* lookup an entry in $REMOTE, $HOME/.remote, /etc/remote */#define CAPMATCH(s,c) (s[0]==c[0] && s[1]==c[1])static void getStr() ;static int getNum() ;static voidremoteParse(char *target){ FILE *ifile ; char line[RemoteMax] ; char *env ; char *ptr ; /* search for target in all locations */ if( ( (env = getenv("REMOTE")) != NULL && (ifile = fopen(env, "r")) != NULL && remoteLookup(target, ifile, line) ) || ( (ifile = fopenHome(".remote", "r")) != NULL && remoteLookup(target, ifile, line) ) || ( (ifile = fopenU(EtcRemote, "r")) != NULL && remoteLookup(target, ifile, line) ) ) { /* parse the line */ for(ptr=line; ptr != NULL; ) { /* skip to ':' */ if( (ptr = strchr(ptr, ':')) != NULL ) { /* skip ':' and leading blanks */ for(++ptr; isspace(*ptr); ++ptr) ; if( CAPMATCH(ptr, "at") ) getStr(modemType, ptr, sizeof(modemType)) ; if( CAPMATCH(ptr, "br") ) { baudRate = getNum(ptr) ; if( baudRate < 300 ) stopBits = 2 ; else stopBits = 1 ; } else if( CAPMATCH(ptr, "cm") ) getStr(connectMsg, ptr, sizeof(connectMsg)) ; else if( CAPMATCH(ptr, "cu") || CAPMATCH(ptr, "dv") ) { getStr(serialPortName, ptr, sizeof(serialPortName)) ; if( lineTxt != NULL ) setSerialPort( serialPortName ) ; haveHost = 1 ; } else if( CAPMATCH(ptr, "di") ) getStr(disconnectMsg, ptr, sizeof(disconnectMsg)) ; else if( CAPMATCH(ptr, "hd") ) localEcho = 1 ; else if( CAPMATCH(ptr, "hf") ) flowControl = FlowRtsCts ; else if( CAPMATCH(ptr, "nt") ) flowControl = FlowNone ; else if( CAPMATCH(ptr, "pa") ) { char parity[10] ; getStr(parity, ptr, sizeof(parity)) ; parityArg(parity) ; if( parityType == ParityNone ) { byteSize = 8 ; inputStrip = 0 ; } else { byteSize = 7 ; inputStrip = 1 ; } } else if( CAPMATCH(ptr, "pn") ) { getStr(phoneNo, ptr, sizeof(phoneNo)) ; } else if( CAPMATCH(ptr, "tc") ) { char newtarget[RemoteMax] ; getStr(newtarget, ptr, sizeof(newtarget)) ; remoteParse(newtarget) ; } } } } else { fprintf(stderr,"remote host \"%s\" not found in $REMOTE, $HOME/.remote or /etc/remote\n", target) ; }} /* scan a capability string from a /etc/remote entry */static voidgetStr(char *dst, char *src, int len){ src += 2 ; /* skip capability name */ if( *src != '=' ) return ; for(++src; *src != '\0' && *src != ':' && *src != '\n' && --len > 0; *dst++ = *src++ ) ; *dst = '\0' ;} /* scan a capability number from a /etc/remote entry */static intgetNum(char *src){ src += 2 ; /* skip capability name */ if( *src != '#' ) return 0 ; return atoi(++src) ;} /* search input file for a line starting with given target. If * found, read line and all continuations, then return True * * TODO: audit for buffer overflow problems. */static intremoteMatch(char *target, int len, char *line){ while( line != NULL ) { if( strncmp(line, target, len) == 0 && strchr("|:\\", line[len]) != NULL ) return 1 ; if( (line = strchr(line, '|')) != NULL ) ++line ; } return 0 ;}static intremoteLookup(char *target, FILE *file, char *line){ int tlen = strlen(target) ; int len ; int remain = RemoteMax ; enum {START, CONTIN, READING} State = START ; /* look for a label at the start of a line */ while( remain > 2 && fgets(line, remain, file) != NULL ) { if( *line != '#' ) { len = strlen(line) ; switch( State ) { case START: if( !remoteMatch(target, tlen, line) ) { State = ( line[len-1] != '\n' || line[len-2] == '\\' ) ? CONTIN : START ; break ; } State = READING ; /* fall through ... */ case READING: if( line[len-1] == '\n' && line[len-2] != '\\' ) { fclose(file) ; return 1 ; } if( line[len-2] == '\\' ) len -= 2 ; line += len ; remain -= len ; break ; case CONTIN: State = ( line[len-1] != '\n' || line[len-2] == '\\' ) ? CONTIN : START ; break ; } } } fclose(file) ; return 0 ;} /* Make Connection based on various global variables */voidMakeConnection(){ connecting = 1 ; connectAbort = 0 ; switch( connectionType ) { case ConnectionSerial: SerialConnect() ; break ; case ConnectionNet: NetConnect() ; break ; case ConnectionPipe: PipeConnect(gtk_entry_get_text(GTK_ENTRY(programEnt))) ; break ; } connecting = 0 ; connectAbort = 0 ; clear_buffers() ; if( connectionActive ) { TermInit() ; WindowConnected() ; if( inputHandler == -1 ) inputHandler = gdk_input_add( ifd, GDK_INPUT_READ, inputCB, NULL ) ; if( timeHandler == -1 ) timeHandler = gtk_timeout_add( 1000, WindowClock, NULL ) ; (void) WindowClock(NULL) ; if( connectionType == ConnectionSerial && modemLightsHandler == -1 ) modemLightsHandler = gtk_timeout_add( 250, SerialWatch, NULL ) ; }} /* Break the connection. For network and pipe connections, we * simply close the fd. For serial connections, there may be * an active modem connection. If the phone number has been * specified, we want to start a "hang up and reset" dialog and * not disconnect yet. */voidBreakConnection(){ if( transferActive ) XferCancel() ; switch( connectionType ) { case ConnectionSerial: SerialDisConnect() ; break ; case ConnectionNet: NetDisConnect() ; break ; case ConnectionPipe: PipeDisConnect() ; break ; }} /* Now we disconnect. */voidConnectionDone(){ if( inputHandler != -1 ) { gdk_input_remove( inputHandler ) ; inputHandler = -1 ; } if( connectionActive ) TermTerm() ; if( timeHandler != -1 ) { gtk_timeout_remove( timeHandler ) ; timeHandler = -1 ; } if( modemLightsHandler != -1 ) { gtk_timeout_remove( modemLightsHandler ) ; modemLightsHandler = -1 ; } WindowStatus("Disconnected") ; connectionActive = False ; WindowConnected() ; SerialLogFlush() ;}voidInstallDialogTimeout(int ms, int (*callback)(void *)){ /* *Sigh*. Gtk doesn't understand a 0 timeout, so we install * an idle proc instead. */ if( ms > 0 ) { if( dialogHandler == -1 ) dialogHandler = gtk_timeout_add( ms, callback, NULL ) ; } else { if( dialogIdleHandler == -1 ) dialogIdleHandler = gtk_idle_add( callback, NULL ) ; }}voidRemoveDialogTimeout(){ if( dialogHandler != -1 ) { gtk_timeout_remove( dialogHandler ) ; dialogHandler = -1 ; } if( dialogIdleHandler != -1 ) { gtk_idle_remove( dialogIdleHandler ) ; dialogIdleHandler = -1 ; }}voidSelectTermBuf(){ if( outputType == OutputVerbatim && !dialogActive && !transferActive ) terminalBuffer = &inputBuf ; else terminalBuffer = &termBuf ;} /* put characters to terminal, translating if required */voidPutTerm(char *buf, int len){ char c ; int reverse = 0 ; if( outputType == OutputVerbatim ) { append_buffer(&termBuf, buf, len, 1) ; return ; } /* for now, the only option is OutputDebug */ while( --len >= 0 ) { c = *buf++ ; if( c & 0200 ) { if( !reverse ) { append_buffer(&termBuf, setInverse, strlen(setInverse), 1) ; reverse = 1 ; } c &= 0177 ; } else if( reverse ) { append_buffer(&termBuf, setNormal, strlen(setNormal), 1) ; reverse = 0 ; } if( !iscntrl(c) || c == '\r' || c == '\n' ) append_buffer1(&termBuf, c, 1) ; else if( c == 0177 ) append_buffer(&termBuf, "^?",2, 1) ; else { append_buffer(&termBuf, "^",1, 1) ; append_buffer1(&termBuf, c+0100, 1) ; } } if( reverse ) append_buffer(&termBuf, setNormal, strlen(setNormal), 1) ;}voidPutTerm1(int c){ char ch = c ; PutTerm(&ch, 1) ;} /* here if translation required */voidTranslateOutput(){ int i ; while( (i = inputBuf.cnt) > 0 ) { i = min(i, BufLen - inputBuf.ptr) ; PutTerm(inputBuf.buffer+inputBuf.ptr, i) ; inputBuf.cnt -= i ; inputBuf.ptr += i ; if( inputBuf.ptr >= BufLen ) inputBuf.ptr -= BufLen ; }} /* fopen(3) interface for suid-X programs. First tries to * open file as user, then as X */FILE *fopenU(char *name, char *type){ FILE *rval ; rval = fopen(name, type) ; /* try again as alternate uid */ if( rval == NULL && uid != euid ) { if( seteuid(euid) != -1 ) { rval = fopen(name, type) ; (void) seteuid(uid) ; } } if( rval == NULL && gid != egid ) { if( setegid(egid) != -1 ) { rval = fopen(name, type) ; (void) setegid(gid) ; } } return rval ;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -