📄 ckufio.c
字号:
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. */ debug(F100,"zopeno append","",0); append = 1; } } if (xferlog#ifdef CKSYSLOG || ckxsyslog >= SYSLG_FC && ckxlogging#endif /* CKSYSLOG */ ) { getfullname(name); debug(F110,"zopeno fullname",fullname,0); } debug(F110,"zopeno fopen arg",p,0); fp[n] = fopen(name,p); /* Try to open the file */ ispipe[ZIFILE] = 0;#ifdef ZDEBUG printf("ZOPENO fp[%d]=%ld\n",n,fp[n]);#endif /* ZDEBUG */ if (fp[n] == NULL) { /* Failed */ debug(F101,"zopeno failed errno","",errno);#ifdef CKSYSLOG if (ckxsyslog >= SYSLG_FC && ckxlogging) syslog(LOG_INFO, "file[%d] %s: %s failed (%m)", n, fullname, append ? "append" : "create" );#endif /* CKSYSLOG */#ifdef COMMENT /* Let upper levels print message. */ perror("Can't open output file");#endif /* COMMENT */ } else { /* Succeeded */ extern int zofbuffer, zofblock, zobufsize; debug(F101, "zopeno zobufsize", "", zobufsize); if (n == ZDFILE || n == ZTFILE) { /* If debug or transaction log */ setbuf(fp[n],NULL); /* make it unbuffered. */#ifdef DONDELAY } else if (n == ZOFILE && !zofblock) { /* blocking or nonblocking */ int flags; if ((flags = fcntl(fileno(fp[n]),F_GETFL,0)) > -1) fcntl(fileno(fp[n]),F_SETFL, flags |#ifdef QNX O_NONBLOCK#else O_NDELAY#endif /* QNX */ ); debug(F100,"zopeno ZOFILE nonblocking","",0);#endif /* DONDELAY */ } else if (n == ZOFILE && !zofbuffer) { /* buffered or unbuffered */ setbuf(fp[n],NULL); debug(F100,"zopeno ZOFILE unbuffered","",0); }#ifdef CK_LOGIN /* Enforce anonymous file-creation permission */ if (isguest) if (n == ZWFILE || n == ZMFILE || n == ZOFILE || n == ZDFILE || n == ZTFILE || n == ZPFILE || n == ZSFILE) chmod(name,ckxperms);#endif /* CK_LOGIN */#ifdef CKSYSLOG if (ckxsyslog >= SYSLG_FC && ckxlogging) syslog(LOG_INFO, "file[%d] %s: %s ok", n, fullname, append ? "append" : "create" );#endif /* CKSYSLOG */ 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 = 0, x2 = 0; extern long ffc; debug(F101,"zclose","",n); if (chkfn(n) < 1) return(0); /* Check range of n */ if ((n == ZOFILE) && (zoutcnt > 0)) /* (PWP) output leftovers */ x2 = zoutdump(); if (fp[ZSYSFN] || ispipe[n]) { /* If file is really pipe */#ifndef NOPUSH x = zclosf(n); /* do it specially */#else x = EOF;#endif /* NOPUSH */ debug(F101,"zclose zclosf","",x); debug(F101,"zclose zclosf fp[n]","",fp[n]); } else { if ((fp[n] != stdout) && (fp[n] != stdin)) x = fclose(fp[n]); fp[n] = NULL;#ifdef COMMENT if (n == ZCTERM || n == ZSTDIO) /* See zopeno() */ if (fp[ZOFILE] == stdout) fp[ZOFILE] = NULL;#endif /* COMMENT */ } iflen = -1L; /* Invalidate file length */ if (x == EOF) { /* if we got a close error */ debug(F101,"zclose fclose fails","",x); return(-1); } else if (x2 < 0) { /* or error flushing last buffer */ debug(F101,"zclose error flushing last buffer","",x2); return(-1); /* then return an error */ } else { /* Print log record compatible with wu-ftpd */ if (xferlog && (n == ZIFILE || n == ZOFILE)) { char * s, *p; extern char ttname[]; if (!iklogopen) (VOID) doiklog(); /* Open log if necessary */ debug(F101,"zclose iklogopen","",iklogopen); if (iklogopen) { timenow = time(NULL);#ifdef CK_LOGIN if (logged_in) s = clienthost; else#endif /* CK_LOGIN */ s = (char *)ttname; if (!s) s = ""; if (!*s) s = "*";#ifdef CK_LOGIN if (logged_in) { p = guestpass; if (!*p) p = "*"; } else#endif /* CK_LOGIN */ p = whoami(); sprintf(iksdmsg, "%.24s %d %s %ld %s %c %s %c %c %s %s %d %s\n", ctime(&timenow), /* date/time */ gtimer(), /* elapsed secs */ s, /* peer name */ ffc, /* byte count */ fullname, /* full pathname of file */ (binary ? 'b' : 'a'), /* binary or ascii */ "_", /* options = none */ n == ZIFILE ? 'o' : 'i', /* in/out */#ifdef CK_LOGIN (isguest ? 'a' : 'r'), /* User type */#else 'r',#endif /* CK_LOGIN */ p, /* Username or guest passwd */#ifdef CK_LOGIN logged_in ? "iks" : "kermit", /* Record ID */#else "kermit",#endif /* CK_LOGIN */ 0, /* User ID on client system unknown */ "*" /* Ditto */ ); debug(F110,"zclose iksdmsg",iksdmsg,0); write(xferlog, iksdmsg, (int)strlen(iksdmsg)); } } debug(F101,"zclose returns","",1); 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;#ifdef IKSD /* I'm not sure how this would ever happen but... */ if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) { *c = coninc(0); if (*c < 0) return(-1); return(0); }#endif /* IKSD */ /* (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 CK_CTRLZ /* If SET FILE EOF CTRL-Z, first Ctrl-Z marks EOF */ if (!binary && a == 0x1A && eofmethod == XYEOF_Z) return(-1);#endif /* CK_CTRLZ */ *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. */ int count = 0; int len = 0; char *buf; extern CHAR feol; /* Line terminator */ if (!s || chkfn(n) < 1) /* Make sure file is open, etc */ return(-1); buf = s; s[0] = '\0'; /* Don't return junk */ a = -1; /* Current character, none yet. */ while (x--) { /* Up to given length */ int old = 0; if (feol) /* Previous character */ old = a; if (zchin(n,&a) < 0) { /* Read a character from the file */ debug(F101,"zsinl zchin fail","",count); if (count == 0) z = -1; /* EOF or other error */ break; } else count++; if (feol) { /* Single-character line terminator */ if (a == feol) break; } else { /* CRLF line terminator */ if (a == '\015') /* CR, get next character */ continue; if (old == '\015') { /* Previous character was CR */ if (a == '\012') { /* This one is LF, so we have a line */ break; } else { /* Not LF, deposit CR */ *s++ = '\015'; x--; len++; } } } *s = a; /* Deposit character */ s++; len++; } *s = '\0'; /* Terminate the string */ debug(F111,"zsinl",buf,len); return(z);}/* Z X I N -- Read x bytes from a file *//* Reads x bytes (or less) from channel n and writes them to the address provided by the caller. Returns number of bytes read on success, 0 on EOF or error.*/intzxin(n,s,x) int n, x; char *s; {#ifdef IKSD if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) { int a, i; a = ttchk(); if (a < 1) return(0); for (i = 0; i < a && i < x; i++) s[i] = coninc(0); return(i); }#endif /* IKSD */ return(fread(s, sizeof (char), x, fp[n]));}/* Z I N F I L L -- Buffered file input. (re)fill the file input buffer with data. All file input should go through this routine, usually by calling the zminchar() macro defined in ckcker.h. Returns: Value 0..255 on success, the character that was read. -1 on end of file. -2 on any kind of error other than end of file. -3 timeout when reading from pipe (Kermit packet mode only).*/intzinfill() { int x; extern int kactive, srvping; errno = 0;#ifdef ZDEBUG printf("ZINFILL fp[%d]=%ld\n",ZIFILE,fp[ZIFILE]);#endif /* ZDEBUG */#ifdef IKSD if (inserver && !local && fp[ZIFILE] == stdin) { int a, i; a = ttchk(); if (a < 0) return(-2); for (i = 0; i < a && i < INBUFSIZE; i++) { zinbuffer[i] = coninc(0); } zincnt = i; /* set pointer to beginning, (== &zinbuffer[0]) */ zinptr = zinbuffer; if (zincnt == 0) return(-1); zincnt--; /* One less char in buffer */ return((int)(*zinptr++) & 0377); /* because we return the first */ }#endif /* IKSD */ debug(F101,"zinfill kactive","",kactive); if (!(kactive && ispipe[ZIFILE])) { if (feof(fp[ZIFILE])) { debug(F100,"ZINFILL feof","",0);#ifdef ZDEBUG printf("ZINFILL EOF\n");#endif /* ZDEBUG */ return(-1); } } clearerr(fp[ZIFILE]);#ifdef SELECT /* Here we can call select() to get a timeout... */ if (kactive && ispipe[ZIFILE]) { int secs, z = 0;#ifndef NOXFER if (srvping) { secs = 1; debug(F101,"zinfill calling ttwait","",secs); z = ttwait(fileno(fp[ZIFILE]),secs); debug(F101,"zinfill ttwait","",z); }#endif /* NOXFER */ if (z == 0) return(-3); }#endif /* SELECT *//* Note: The following read MUST be nonblocking when reading from a pipe and we want timeouts to work. See zxcmd().*/ zincnt = fread(zinbuffer, sizeof (char), INBUFSIZE, fp[ZIFILE]);#ifdef COMMENT#ifdef DEBUG if (deblog) { debug(F011,"ZINFILL fread",zinbuffer,zincnt); /* Much too big */ }#endif /* DEBUG */#else /* COMMENT */ debug(F101,"ZINFILL fread","",zincnt); /* Just the size */#endif /* COMMENT */#ifdef ZDEBUG printf("FREAD=%d\n",zincnt);#endif /* ZDEBUG */ if (zincnt == 0) { /* Got nothing? */ if (ferror(fp[ZIFILE])) { debug(F100,"ZINFILL ferror","",0); debug(F101,"ZINFILL errno","",errno);#ifdef ZDEBUG printf("ZINFILL errno=%d\n",errno);#endif /* ZDEBUG */#ifdef EWOULDBLOCK return((errno == EWOULDBLOCK) ? -3 : -2);#else return(-2);#endif /* EWOULDBLOCK */ } /* In case feof() didn't work just above -- sometimes it doesn't... */ if (feof(fp[ZIFILE]) ) { debug(F100,"ZINFILL count 0 EOF return -1","",0); return (-1); } else { debug(F100,"ZINFILL count 0 not EOF return -2","",0); return(-2); } } 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; { int rc = 0; rc = chkfn(n); if (rc < 1) return(-1); /* Keep this, prevents memory faults */ if (!s) return(0); /* Null pointer, do nothing, succeed */ if (!*s) return(0); /* empty string, ditto */#ifdef IKSD /* This happens with client-side Kermit server when a REMOTE command was sent from the server to the client and the server is supposed to display the text, but of course there is no place to display it since it is in remote mode executing Kermit protocol. */ if (inserver && !local && (n == ZCTERM || n == ZSTDIO)) {#ifdef COMMENT return(ttol(s,((int)strlen(s)) < 0) ? -1 : 0);#else return(0);#endif /* COMMENT */ }#endif /* IKSD */ if (n == ZSFILE) return(write(fileno(fp[n]),s,(int)strlen(s))); rc = fputs(s,fp[n]) == EOF ? -1 : 0; if (n == ZWFILE) fflush(fp[n]); return(rc);}/* Z S O U T L -- Write string to file, with line terminator, buffered */intzsoutl(n,s) int n; char *s; { if (zsout(n,s) < 0) return(-1);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -