📄 ckufio.c
字号:
#ifndef R_OK#define R_OK 4 /* For access */#endif#ifndef W_OK#define W_OK 2#endif#ifndef O_RDONLY#define O_RDONLY 000#endif/* Declarations */int maxnam = MAXNAMLEN; /* Available to the outside */int maxpath = MAXPATH;FILE *fp[ZNFILS] = { /* File pointers */ NULL, NULL, NULL, NULL, NULL, NULL, NULL };#ifdef OS2int ispipe[ZNFILS]; /* Flag for file is a pipe */#endif /* OS2 *//* Buffers and pointers used in buffered file input and output. */#ifdef DYNAMICextern char *zinbuffer, *zoutbuffer;#elseextern char zinbuffer[], zoutbuffer[];#endif /* DYNAMIC */extern char *zinptr, *zoutptr;extern int zincnt, zoutcnt;extern int wildxpand;extern UID_T real_uid();static long iflen = -1L; /* Input file length */static PID_T pid = 0; /* pid of child fork */static int fcount; /* Number of files in wild group */static char nambuf[MAXNAMLEN+4]; /* Buffer for a filename */#ifndef NOFRILLSstatic char zmbuf[200]; /* For mail, remote print strings */#endif /* NOFRILLS *//* static */ /* Not static, must be global now. */char *mtchs[MAXWLD], /* Matches found for filename */ **mtchptr; /* Pointer to current match *//* Z K S E L F -- Kill Self: log out own job, if possible. *//* Note, should get current pid, but if your system doesn't have *//* getppid(), then just kill(0,9)... */#ifndef SVR3#ifndef POSIX/* Already declared in unistd.h for SVR3 and POSIX */#ifdef CK_ANSICextern PID_T getppid(void);#else#ifndef PS2AIX10extern PID_T getppid();#endif /* PS2AIX10 */#endif /* CK_ANSIC */#endif /* POSIX */#endif /* SVR3 */intzkself() { /* For "bye", but no guarantee! */#ifdef PROVX1 return(kill(0,9));#else#ifdef V7 return(kill(0,9));#else#ifdef TOWER1 return(kill(0,9));#else#ifdef FT18 return(kill(0,9));#else#ifdef aegis return(kill(0,9));#else#ifdef COHERENT return(kill((PID_T)getpid(),1));#else#ifdef OS2 exit(3);#else#ifdef PID_T exit(kill((PID_T)getppid(),1));#else exit(kill(getppid(),1));#endif#endif#endif#endif#endif#endif#endif#endif}/* Z O P E N I -- Open an existing file for input. */intzopeni(n,name) int n; char *name; { debug(F111," zopeni",name,n); debug(F101," fp","", fp[n]); if (chkfn(n) != 0) return(0); zincnt = 0; /* Reset input buffer */ if (n == ZSYSFN) { /* Input from a system function? *//*** Note, this function should not be called with ZSYSFN ***//*** Always call zxcmd() directly, and give it the real file number ***//*** you want to use. ***/ debug(F110,"zopeni called with ZSYSFN, failing!",name,0); *nambuf = '\0'; /* No filename. */ return(0); /* fail. */#ifdef COMMENT return(zxcmd(n,name)); /* Try to fork the command */#endif } if (n == ZSTDIO) { /* Standard input? */ if (isatty(0)) { fprintf(stderr,"Terminal input not allowed"); debug(F110,"zopeni: attempts input from unredirected stdin","",0); return(0); } fp[ZIFILE] = stdin;#ifdef OS2 setmode(fileno(stdin),O_BINARY);#endif /* OS2 */ return(1); }#ifdef OS2 if (n == ZIFILE || n == ZRFILE) fp[n] = fopen(name,"rb"); /* Binary mode */ else#endif /* OS2 */ fp[n] = fopen(name,"r"); /* Real file, open it. */ debug(F111," zopeni", name, fp[n]); if (fp[n] == NULL) perror("zopeni"); return((fp[n] != NULL) ? 1 : 0);}/* Z O P E N O -- Open a new file for output. */intzopeno(n,name,zz,fcb)/* zopeno */ int n; char *name; struct zattr *zz; struct filinfo *fcb; { char p[8]; /* (===OS2 change===) *//* As of Version 5A, the attribute structure and the file information *//* structure are included in the arglist. */#ifdef DEBUG debug(F111,"zopeno",name,n); if (fcb) { debug(F101,"zopeno fcb disp","",fcb->dsp); debug(F101,"zopeno fcb type","",fcb->typ); debug(F101,"zopeno fcb char","",fcb->cs); } else { debug(F100,"zopeno fcb is NULL","",0); } if (n != ZDFILE) debug(F111," zopeno",name,n);#endif /* DEBUG */ if (chkfn(n) != 0) return(0); if ((n == ZCTERM) || (n == ZSTDIO)) { /* Terminal or standard output */ fp[ZOFILE] = stdout;#ifdef DEBUG if (n != ZDFILE) debug(F101," fp[]=stdout", "", fp[n]);#endif /* DEBUG */ zoutcnt = 0; zoutptr = zoutbuffer; return(1); }/* A real file. Open it in desired mode (create or append). */ strcpy(p,"w"); /* Assume write/create mode */ if (fcb) { /* If called with an FCB... */ if (fcb->dsp == XYFZ_A) /* Does it say Append? */ strcpy(p,"a"); /* Yes. */ }#ifdef OS2 if (n == ZOFILE || n == ZSFILE) /* OS/2 binary mode */ strcat(p,"b");#endif /* OS2 */ fp[n] = fopen(name,p); /* Try to open the file */ if (fp[n] == NULL) { /* Failed */ debug(F101,"zopeno failed errno","",errno);#ifdef COMMENT /* Let upper levels print message. */ perror("Can't open output file");#endif /* COMMENT */ } else { /* Succeeded */ if (n == ZDFILE) /* If it's the debug log */ setbuf(fp[n],NULL); /* make it unbuffered */ else debug(F100, "zopeno ok", "", 0); } zoutcnt = 0; /* (PWP) reset output buffer */ zoutptr = zoutbuffer; return((fp[n] != NULL) ? 1 : 0);}/* Z C L O S E -- Close the given file. *//* Returns 0 if arg out of range, 1 if successful, -1 if close failed. */intzclose(n) int n; { int x, x2; if (chkfn(n) < 1) return(0); /* Check range of n */ if ((n == ZOFILE) && (zoutcnt > 0)) /* (PWP) output leftovers */ x2 = zoutdump(); else x2 = 0; x = 0; /* Initialize return code */ if (fp[ZSYSFN]) { /* If file is really pipe */ x = zclosf(n); /* do it specially */ } else { if ((fp[n] != stdout) && (fp[n] != stdin)) x = fclose(fp[n]); fp[n] = NULL; } iflen = -1L; /* Invalidate file length */ if (x == EOF) /* if we got a close error */ return(-1); else if (x2 < 0) /* or an error flushing the last buffer */ return(-1); /* then return an error */ else return(1);}/* Z C H I N -- Get a character from the input file. *//* Returns -1 if EOF, 0 otherwise with character returned in argument */intzchin(n,c) int n; int *c; { int a, x; /* (PWP) Just in case this gets called when it shouldn't. */ if (n == ZIFILE) { x = zminchar(); *c = x; return(x); } /* if (chkfn(n) < 1) return(-1); */ a = getc(fp[n]); if (a == EOF) return(-1);#ifdef OS2 if (!binary && a == 0x1A) /* Ctrl-Z marks EOF for text mode*/ return(-1);#endif *c = (CHAR) a & 0377; return(0);}/* Z S I N L -- Read a line from a file *//* Writes the line into the address provided by the caller. n is the Kermit "channel number". Writing terminates when newline is encountered, newline is not copied. Writing also terminates upon EOF or if length x is exhausted. Returns 0 on success, -1 on EOF or error.*/intzsinl(n,s,x) int n, x; char *s; { int a, z = 0; /* z is return code. */ if (chkfn(n) < 1) { /* Make sure file is open */ return(-1); } a = -1; /* Current character, none yet. */ while (x--) { /* Up to given length */#ifndef NLCHAR int old; old = a; /* Previous character */#endif if (zchin(n,&a) < 0) { /* Read a character from the file */ debug(F101,"zsinl","",a); z = -1; /* EOF or other error */ break; }#ifdef NLCHAR if (a == (char) NLCHAR) break; /* Single-character line terminator */#else /* CRLF line terminator */ if (a == '\015') continue; /* CR, get next character */ if (old == '\015') { /* Previous character was CR */ if (a == '\012') break; /* This one is LF, so we have a line */ else *s++ = '\015'; /* Not LF, deposit CR */ }#ifdef OS2/* I'm not sure I understand this one, so let's keep it only for OS/2 for now.*/ if (a == '\012') break; /* Break on single LF too */#endif /* OS2 */#endif /* NLCHAR */ *s = a; /* Deposit character */ s++; } *s = '\0'; /* Terminate the string */ return(z);}/* * (PWP) (re)fill the buffered input buffer with data. All file input * should go through this routine, usually by calling the zminchar() * macro (in ckcker.h). *//* * Suggestion: if fread() returns 0, call ferror to find out what the * problem was. If it was not EOF, then return -2 instead of -1. * Upper layers (getpkt function in ckcfns.c) should set cxseen flag * if it gets -2 return from zminchar macro. */intzinfill() { int x; errno = 0; zincnt = fread(zinbuffer, sizeof (char), INBUFSIZE, fp[ZIFILE]);#ifdef COMMENT debug(F101,"zinfill fp","",fp[ZIFILE]); debug(F101,"zinfill zincnt","",zincnt);#endif if (zincnt == 0) {#ifndef UTEK#ifdef ferror x = ferror(fp[ZIFILE]); debug(F101,"zinfill errno","",errno); debug(F101,"zinfill ferror","",x); if (x) return(-2);#endif /* ferror */#else x = feof(fp[ZIFILE]); debug(F101,"zinfill errno","",errno); debug(F101,"zinfill feof","",x); if (!x && ferror(fp[ZIFILE])) return(-2);#endif /* UTEK */ return(-1); } zinptr = zinbuffer; /* set pointer to beginning, (== &zinbuffer[0]) */ zincnt--; /* one less char in buffer */ return((int)(*zinptr++) & 0377); /* because we return the first */}/* Z S O U T -- Write a string out to the given file, buffered. */intzsout(n,s) int n; char *s; { if (chkfn(n) < 1) return(-1); /* Keep this here, prevents memory faults */#ifndef OS2 if (n == ZSFILE) return(write(fileno(fp[n]),s,(int)strlen(s))); else#endif /* OS2 */ return(fputs(s,fp[n]) == EOF ? -1 : 0);}/* Z S O U T L -- Write string to file, with line terminator, buffered */intzsoutl(n,s) int n; char *s; { /* if (chkfn(n) < 1) return(-1); */ if (fputs(s,fp[n]) == EOF) return(-1); if (fputs("\n",fp[n]) == EOF) return(-1); /* (===OS2 ? \r\n) */ return(0);}/* Z S O U T X -- Write x characters to file, unbuffered. */intzsoutx(n,s,x) int n, x; char *s; {#ifdef COMMENT if (chkfn(n) < 1) return(-1); return(write(fp[n]->_file,s,x));#endif return(write(fileno(fp[n]),s,x) == x ? x : -1);}/* Z C H O U T -- Add a character to the given file. *//* Should return 0 or greater on success, -1 on failure (e.g. disk full) */int#ifdef CK_ANSICzchout(register int n, char c)#elsezchout(n,c) register int n; char c;#endif /* CK_ANSIC *//* zchout() */ { /* if (chkfn(n) < 1) return(-1); */#ifndef OS2 if (n == ZSFILE) { /* Use unbuffered for session log */ return(write(fileno(fp[n]),&c,1) == 1 ? 0 : -1); } else { /* Buffered for everything else */#endif /* OS2 */ if (putc(c,fp[n]) == EOF) /* If true, maybe there was an error */ return(ferror(fp[n])?-1:0); /* Check to make sure */ else /* Otherwise... */ return(0); /* There was no error. */#ifndef OS2 }#endif /* OS2 */}/* (PWP) buffered character output routine to speed up file IO */intzoutdump() { int x; zoutptr = zoutbuffer; /* Reset buffer pointer in all cases */ debug(F101,"zoutdump chars","",zoutcnt); if (zoutcnt == 0) { /* Nothing to output */ return(0); } else if (zoutcnt < 0) { /* Unexpected negative argument */ zoutcnt = 0; /* Reset output buffer count */ return(-1); /* and fail. */ }/* Frank Prindle suggested that replacing this fwrite() by an fflush() *//* followed by a write() would improve the efficiency, especially when *//* writing to stdout. Subsequent tests showed a 5-fold improvement! *//* if (x = fwrite(zoutbuffer, 1, zoutcnt, fp[ZOFILE])) { */ fflush(fp[ZOFILE]); if ((x = write(fileno(fp[ZOFILE]),zoutbuffer,zoutcnt)) == zoutcnt) { debug(F101,"zoutdump write ok","",zoutcnt); zoutcnt = 0; /* Reset output buffer count */ return(0); /* write() worked OK */ } else { debug(F101,"zoutdump write error","",errno); debug(F101,"zoutdump write returns","",x); zoutcnt = 0; /* Reset output buffer count */ return(-1); /* write() failed */ }}/* C H K F N -- Internal function to verify file number is ok *//* Returns: -1: File number n is out of range 0: n is in range, but file is not open 1: n in range and file is open*/intchkfn(n) int n; {#ifdef COMMENT /* Save some stack space */ switch (n) { case ZCTERM: case ZSTDIO: case ZIFILE: case ZOFILE: case ZDFILE: case ZTFILE: case ZPFILE: case ZSFILE: case ZSYSFN: case ZRFILE: case ZWFILE: break; default: debug(F101,"chkfn: file number out of range","",n); fprintf(stderr,"?File number out of range - %d\n",n); return(-1); } return( (fp[n] == NULL) ? 0 : 1 );#else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -