📄 gunixio.c
字号:
#endif /* __STDC__ */{ int n = 0, x = 0, flag = 0, rc = 0, ccn = 0; /* Local variables */ char c = NUL; int havelen = 0, pktlen = 0, lplen = 0;#ifdef USE_GETCHAR if (debug) fprintf(db,"ttinl getchar timo = %d\n",timo);#else if (debug) fprintf(db,"ttinl read timo = %d\n",timo);#endif /* USE_GETCHAR */ *dest = NUL; /* Clear destination buffer */ if (timo) { signal(SIGALRM,timerh); /* Enable timer interrupt */ alarm(timo); /* Set it. */ } if (setjmp(jbuf)) { /* Timer went off? */ if (debug) fprintf(db,"ttinl timeout\n"); rc = -1; /* Yes, set this return code. */ } else { /* Otherwise... */ while (1) { /* Read until we have a packet */#ifdef DUMBIO x = read(0,&c,1); /* Dumb blocking read byte loop */ if (x < 0) { logerr("ttinl XX read 1"); rc = -2; }#else#ifdef USE_GETCHAR errno = 0; x = getchar(); /* Buffered read with getchar() */ if (x == EOF) { if (errno == EINTR) continue; logerr("ttinl getchar"); rc = -2; } c = x;#else /* USE_GETCHAR */#ifdef O_NDELAY if (nonblock) { /* Buffered nonblocking read() */ int x; if (tincnt < 1) { /* Need to fill our buffer */ errno = 0; tincnt = read(0,tinbuf,TINBUFSIZ); if (tincnt > -1) tlast = tincnt; if (debug) fprintf(db,"ttinl nonblock tincnt=%d errno=%d\n", tincnt,errno); if (tincnt == 0 || errno == EWOULDBLOCK) {#ifdef F_SETFL /* Go back to blocking and wait for 1 char */ if (ttflags != -1) { errno = 0; x = fcntl(0, F_SETFL, ttflags & ~O_NDELAY); if (x == -1 || errno) logerr("ttinl fcntl O_NDELAY off"); errno = 0; tincnt = read(0,tinbuf,1); if (tincnt < 1 || errno) logerr("ttinl BL read"); errno = 0; fcntl(0, F_SETFL, ttflags | O_NDELAY); if (x == -1 || errno) logerr("ttinl fcntl O_NDELAY on"); } if (tincnt == 0) { /* Check results */ continue; } if (tincnt < 0) { /* I/O error */ rc = -2; goto xttinl; } if (debug) fprintf(db,"ttinl blocking read %d\n",tincnt);#else /* No other form of sleeping is portable */ sleep(1); continue;#endif /* F_SETFL */ } else if (tincnt < 0) { rc = -2; goto xttinl; } tinptr = tinbuf; } c = *tinptr++; tincnt--; } else {#endif /* O_NDELAY */ x = read(0,&c,1); /* Dumb read byte loop */ if (x < 0) { logerr("ttinl XX read 1"); rc = -2; }#ifdef O_NDELAY }#endif /* O_NDELAY */#endif /* USE_GETCHAR */#endif /* DUMBIO */ if (rc < 0) break; if (xparity) /* Strip parity */ c &= 0x7f;#ifdef COMMENT /* Only uncomment in emergencies */ if (debug) fprintf(db,"ttinl char=%c flag=%d tincnt=%d\n",c,flag,tincnt);#endif /* COMMENT */ if (c == '\03') { /* Got ^C, count it. */ if (++ccn > 2) { /* If more than 2, let them out */ fprintf(stderr,"^C..."); ttres(); if (debug) fprintf(db,"ttinl interrupted\n"); dest[n = 0] = NUL; rc = -9; goto xttinl; } } else /* Not ^C so reset counter*/ ccn = 0; if (!flag && (c != soh)) /* Look for SOH */ continue; /* Skip stuff between packets */ flag = 1; /* Have SOH */ if (n >= max) { if (debug) fprintf(db,"ttinl overflow\n"); rc = -2; goto xttinl; } dest[n++] = c; /* Store the character */#ifdef USE_EOL /* Use EOL to determine end of packet */ if (c == eol) { dest[n] = NUL; break; }#else /* Use length field for framing */ if (!havelen) { if (n == 2) { pktlen = xunchar(dest[1] & 0x7f); if (pktlen > 1) { if (debug) fprintf(db,"ttinl length = %d\n",pktlen); havelen = 1; } } else if (n == 5 && pktlen == 0) { lplen = xunchar(dest[4] & 0x7f); } else if (n == 6 && pktlen == 0) { pktlen = lplen * 95 + xunchar(dest[5] & 0x7f) + 5; if (debug) fprintf(db,"ttinl length = %d\n",pktlen); havelen = 1; } } if (havelen && (n > pktlen+1)) { if (turn && c != turn) /* Wait for turnaround char */ continue; dest[n] = NUL; /* Null-terminate whatever we got */ break; }#endif /* USE_EOL */ } } xttinl: /* Common exit point */ if (timo) { alarm(0); /* Turn off the alarm */ signal(SIGALRM,SIG_IGN); /* and associated interrupt */ } if (debug && n > 0) { /* Log packet */#ifndef FULLPACKETS if (n > DEBUGWRAP) { /* Truncate if it would wrap */ dest[n] = NUL; /* in case of interruption */ c = dest[DEBUGWRAP]; dest[DEBUGWRAP] = NUL; fprintf(db,"PKT<-[^A%s...](%d) rc=%d\n",&dest[1],n,rc); dest[DEBUGWRAP] = c; } else#endif /* FULLPACKETS */ fprintf(db,"PKT<-[^A%s](%d) rc=%d\n",&dest[1],n,rc); } if (rc == -9) /* Interrupted by user */ doexit(1); else if (rc > -1) rc = n; return(rc); /* Return length, or failure. */}intttol(s,len) int len; char *s; { /* Output string s of given length */ register int i = 0, n = 0, m = 0; int partial = 0; n = len; if (n < 0) { if (debug) fprintf(db,"ttol len = %d\n",n); return(-1); } if (xparity) { /* Add parity if requested */ for (i = 0; i < n; i++) s[i] = dopar(s[i]); } if (debug) { /* Log the packet if requested */ char c;#ifndef FULLPACKETS if (n > DEBUGWRAP) { c = s[DEBUGWRAP]; s[DEBUGWRAP] = NUL; fprintf(db,"PKT->[^A%s...](%d)\n",&s[1],n); s[DEBUGWRAP] = c; } else {#endif /* FULLPACKETS */ c = s[n-1]; s[n-1] = NUL; fprintf(db,"PKT->[^A%s](%d)\n",&s[1],n); s[n-1] = c;#ifndef FULLPACKETS }#endif /* FULLPACKETS */ }#ifdef USE_GETCHAR { /* Send the packet with putchar() */ register CHAR c; register int i; for (i = 0; i < n; i++) { c = *s++; if (putchar(c) == EOF) { logerr("ttol putchar"); return(-1); } } } fflush(stdout); /* Push it out */ return(n);#else while (n > 0) { /* Send the packet with write() */ i = write(1,&s[m],n); /* Allowing for partial results */ if (i < 0) { if (errno == EWOULDBLOCK) /* and even no results at all.. */ continue; logerr("ttol write"); return(-1); } if (i == n) break; partial++; m += i; if (debug) fprintf(db,"ttol partial write %d (%d/%d)\n",i,m,len); n -= i; } if (partial) { m += i; if (debug) fprintf(db,"ttol partial write %d (%d/%d)\n",i,m,len); if (m != len) { if (debug) fprintf(db,"ttol foulup %d != %d\n",m,len); return(-1); } } return(len);#endif /* USE_GETCHAR */}/* File Functions */char ofile[MAXPATHLEN]; /* Output filename */long filelength = -1L;longzchki(fn) char * fn; { /* Check if file is readable */ struct stat buf; if (!fn) return(-1); if (stat(fn,&buf) < 0) return(-1); errno = 0; if (access(fn,R_OK) < 0) { if (debug) fprintf(db,"zchki access %s errno = %d\n",fn,errno); return(-1); } if (!S_ISREG(buf.st_mode)) { if (debug) fprintf(db,"zchki %s is a directory",fn); return(-2); } return(buf.st_size);}intzchko(fn) char *fn; { /* Check write access */ int i, x; char * s; if (!fn) /* Defend against empty name */ fn = ""; if (!*fn) return(-1); if (!strcmp(fn,"/dev/null")) /* Null device is OK. */ return(0); if ((x = zchki(fn)) == -2) /* An existing directory? */ return(-1); s = fn; if (x < 0) { /* If file does not exist */ strncpy(work,fn,MAXPATHLEN); work[MAXPATHLEN] = NUL; s = work; for (i = (int)strlen(s); i > 0; i--) { /* Strip filename from right */ if (s[i-1] == '/') { /* and check its directory */ s[i-1] = NUL; break; } } if (i == 0) s = "."; } errno = 0; x = access(s,W_OK); /* Check access of path. */ if (debug) fprintf(db,"zchko(%s) x = %d errno = %d\n",s,x,errno); return((x < 0) ? -1 : 0); /* and return. */}intzopeni(name) char *name; { /* Open existing file for input */ ifp = fopen(name,"r"); if (debug) fprintf(db,"zopeni %s: %d\n",name, ifp ? 0 : errno); filelength = zchki(name); if (filelength < 0) return((int)filelength); zincnt = 0; zinptr = zinbuf; return((ifp == NULL) ? -1 : 0);}intzopeno(name) char *name; { /* Open new file for output */ errno = 0; ofp = fopen(name,"w"); if (debug) fprintf(db,"zopeno %s: %d\n",name, ofp ? 0 : errno); if (ofp) { strncpy(ofile,name,MAXPATHLEN); ofile[MAXPATHLEN-1] = NUL; return(0); } else return(-1);}VOID /* Local to remote file name */zltor(lclnam,pktnam,maxlen) char *lclnam, *pktnam; int maxlen; { char *p, *np = NULL, *cp, *pp, c; char *dotp = NULL; char *dirp = NULL; int n = 0; if (debug) fprintf(db,"zltor %s: maxlen = %d, literal = %d\n", lclnam,maxlen,literal); if (literal) { p = lclnam; dirp = p; while (*p) { if (*p == '/') dirp = p+1; p++; } strncpy(pktnam,dirp,maxlen); } else { for (p = lclnam; *p; p++) { /* Point to name part */ if (*p == '/') np = p; } if (np) { np++; if (!*np) np = lclnam; } else np = lclnam; if (debug) fprintf(db,"zltor np %s\n",np); pp = work; /* Output buffer */ for (cp = np, n = 0; *cp && n < maxlen; cp++,n++) { c = *cp; if (islower(c)) /* Uppercase letters */ *pp++ = toupper(c); /* Change tilde to hyphen */ else if (c == '~') *pp++ = '-'; else if (c == '#') /* Change number sign to 'X' */ *pp++ = 'X'; else if (c == '*' || c == '?') /* Change wildcard chars to 'X' */ *pp++ = 'X'; else if (c == ' ') /* Change space to underscore */ *pp++ = '_'; else if (c < ' ') /* Change space and controls to 'X' */ *pp++ = 'X'; else if (c == '.') { /* Change dot to underscore */ dotp = pp; /* Remember where we last did this */ *pp++ = '_'; } else { if (c == '/') dirp = pp; *pp++ = c; } } *pp = NUL; /* Tie it off. */ if (dotp > dirp) *dotp = '.'; /* Restore last dot in file name */ cp = pktnam; /* If nothing before dot, */ if (*work == '.') *cp++ = 'X'; /* insert 'X' */ strncpy(cp,work,maxlen); cp[maxlen-1] = NUL; } if (debug) fprintf(db,"zltor result: %s\n",pktnam);}intzbackup(fn) char * fn; { /* Back up existing file */ struct stat buf; int i, j, k, x, state, flag; char *p, newname[MAXPATHLEN+12]; if (!fn) /* Watch out for null pointers. */ return(-1); if (!*fn) /* And empty names. */ return(-1); if (stat(fn,&buf) < 0) /* If file doesn't exist */ return(0); /* no need to back it up. */ i = strlen(fn); /* Get length */ if (i > MAXPATHLEN) /* Guard buffer */ i = MAXPATHLEN; if (debug) fprintf(db,"zbackup A %s: %d\n", fn, i); strncpy(work,fn,MAXPATHLEN); /* Make pokeable copy of name */ work[MAXPATHLEN] = NUL; p = work; /* Strip any backup prefix */ i--; for (flag = state = 0; (!flag && (i > 0)); i--) { switch (state) { case 0: /* State 0 - final char */ if (p[i] == '~') /* Is tilde */ state = 1; /* Switch to next state */ else /* Otherwise */ flag = 1; /* Quit - no backup suffix. */ break; case 1: /* State 1 - digits */ if (p[i] == '~' && p[i-1] == '.') { /* Have suffix */ p[i-1] = NUL; /* Trim it */ flag = 1; /* done */ } else if (p[i] >= '0' && p[i] <= '9') { /* In number part */ continue; /* Keep going */ } else { /* Something else */ flag = 1; /* Not a backup suffix - quit. */ } break; } } if (debug) fprintf(db,"zbackup B %s\n", p); if (!p[0]) p = fn; j = strlen(p); strncpy(newname,p,MAXPATHLEN); for (i = 1; i < 1000; i++) { /* Search from 1 to 999 */ if (i < 10) /* Length of numeric part of suffix */ k = 1; else if (i < 100) k = 2; else k = 3; x = j; /* Where to write suffix */ if ((x + k + 3) > MAXPATHLEN) x = MAXPATHLEN - k - 3; sprintf(&newname[x],".~%d~",i); /* Make a backup name */ if (stat(newname,&buf) < 0) { /* If it doesn't exist */ errno = 0; if (link(fn,newname) < 0) { /* Rename old file to backup name */ if (debug) fprintf(db,"zbackup failed: link(%s): %d\n",newname,errno); return(-1); } else if (unlink(fn) < 0) { if (debug) fprintf(db,"zbackup failed: unlink(%s): %d\n",fn,errno); return(-1); } else { if (debug) fprintf(db,"zbackup %s: OK\n",newname); return(0); } } } if (debug) fprintf(db,"zbackup failed: all numbers used\n"); return(-1);}int /* Remote to local filename */zrtol(pktnam,lclnam,warn,maxlen) char *pktnam, *lclnam; int warn, maxlen; { int acase = 0, flag = 0, n = 0; char * p; if (literal) { strncpy(lclnam,pktnam,maxlen); } else { for (p = lclnam; *pktnam != '\0' && n < maxlen; pktnam++) { if (*pktnam > SP) flag = 1; /* Strip leading blanks and controls */ if (flag == 0 && *pktnam < '!') continue; if (isupper(*pktnam)) /* Check for mixed case */ acase |= 1; else if (islower(*pktnam)) acase |= 2; *p++ = *pktnam; n++; } *p-- = NUL; /* Terminate */ while (*p < '!' && p > lclnam) /* Strip trailing blanks & controls */ *p-- = '\0'; if (!*lclnam) { /* Nothing left? */ strncpy(lclnam,"NONAME",maxlen); /* do this... */ } else if (acase == 1) { /* All uppercase? */ p = lclnam; /* So convert all letters to lower */ while (*p) { if (isupper(*p)) *p = tolower(*p); p++; } } } if (warn) { if (zbackup(lclnam) < 0) return(-1); } return(0);}intzclosi() { /* Close input file */ int rc; rc = (fclose(ifp) == EOF) ? -1 : 0; ifp = NULL; return(rc);}intzcloso(cx) int cx; { /* Close output file */ int rc; rc = (fclose(ofp) == EOF) ? -1 : 0; if (debug) fprintf(db,"zcloso(%s) cx = %d keep = %d\n", ofile, cx, keep); if (cx && !keep ) unlink(ofile); /* Delete if incomplete */ ofp = NULL; return(rc);}intzfillbuf(text) int text; { /* Refill input file buffer */ if (zincnt < 1) { /* Nothing in buffer - must refill */ if (text) { /* Text mode needs LF/CRLF handling */ int c; /* Current character */ for (zincnt = 0; /* Read a line */ zincnt < MAXRECORD - 1 && (c = getc(ifp)) != EOF && c != '\n'; zincnt++ ) { zinbuf[zincnt] = c; } if (c == '\n') { /* Have newline. */ zinbuf[zincnt++] = '\r'; /* Substitute CRLF */ zinbuf[zincnt++] = c; } } else { /* Binary - just read raw buffers */ zincnt = fread(zinbuf, sizeof(char), MAXRECORD, ifp); } zinbuf[zincnt] = NUL; /* Terminate. */ if (zincnt == 0) /* Check for EOF */ return(-1); zinptr = zinbuf; /* Not EOF - reset pointer */ }#ifdef EXTRADEBUG /* Voluminous debugging */ if (debug) fprintf(db,"zfillbuf (%s) zincnt = %d\n", text ? "text" : "binary", zincnt );#endif /* EXTRADEBUG */ zincnt--; /* Return first byte. */ return(*zinptr++ & 0xff);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -