📄 ckcfns.c
字号:
tlog(F110," error - directory exists:",ofn1,0); discard = opnerr = 1;#ifdef COMMENT /* Don't send an error packet, just refuse the file */ return(0);#endif /* COMMENT */ } break; /* Not here, we don't have */ /* the attribute packet yet. */ default: debug(F101,"rcvfil bad collision action","",fncact); break; } } debug(F110,"rcvfil ofn1",ofn1,0); debug(F110,"rcvfil ofn2",ofn2,0); if (fncact == XYFX_R && ofn1x && ofn2) { /* Renaming incoming file? */ screen(SCR_AN,0,0l,ofn2); /* Display renamed name */ strcpy(n, ofn2); /* Return it */ } else { /* No */ screen(SCR_AN,0,0l,ofn1); /* Display regular name */ strcpy(n, ofn1); /* and return it. */ }#ifdef CK_MKDIR/* Create directory(s) if necessary. */ if (!discard && !fnrpath) { /* RECEIVE PATHAMES ON? */ debug(F110,"rcvfil calling zmkdir",ofn1,0); /* Yes */ if (zmkdir(ofn1) < 0) { debug(F100,"zmkdir fails","",0); tlog(F110," error - directory creation failure:",ofn1,0); rf_err = "Directory creation failure."; discard = 1; return(0); } }#else debug(F110,"sfile CK_MKDIR not defined",ofn1,0);#endif /* CK_MKDIR */#ifndef NOICP/* #ifndef MAC *//* Why not Mac? */ strcpy(fspec,ofn1); /* Here too for \v(filespec) *//* #endif */ #endif /* NOICP */ debug(F110,"rcvfil: n",n,0); ffc = 0L; /* Init per-file counters */ cps = oldcps = 0L; rs_len = 0L; rejection = -1; fsecs = gtimer(); /* Time this file started */ filcnt++; intmsg(filcnt); return(1); /* Successful return */}/* R E O F -- Receive End Of File packet for incoming file *//* Closes the received file. Returns: 0 on success. -1 if file could not be closed. 2 if disposition was mail, mail was sent, but temp file not deleted. 3 if disposition was print, file was printed, but not deleted. -2 if disposition was mail and mail could not be sent -3 if disposition was print and file could not be printed*/intreof(f,yy) char *f; struct zattr *yy; { int x; char *p; char c; debug(F111,"reof fncact",f,fncact); debug(F101,"reof discard","",discard); success = 1; /* Assume status is OK */ lsstate = 0; /* Cancel locking-shift state */ if (discard) { /* Handle attribute refusals, etc. */ debug(F101,"reof discarding","",0); success = 0; /* Status = failed. */ if (rejection == '#' || /* Unless rejection reason is */ rejection == 1 || /* date or name (SET FILE COLLISION */ rejection == '?') /* UPDATE or DISCARD) */ success = 1; debug(F101,"reof success","",success); filrej++; /* Count this rejection. */ discard = 0; /* We never opened the file, */ return(0); /* so we don't close it. */ }#ifdef DEBUG if (deblog) { debug(F101,"reof cxseen","",cxseen); debug(F101,"reof czseen","",czseen); debug(F110,"reof rdatap",rdatap,0); }#endif /* DEBUG */ if (cxseen == 0) cxseen = (*rdatap == 'D'); /* Got cancel directive? */ success = (cxseen || czseen) ? 0 : 1; /* Set SUCCESS flag appropriately */ if (!success) filrej++; /* "Uncount" this file */ debug(F101,"reof success","",czseen); x = clsof(cxseen || czseen); /* Close the file (resets cxseen) */ if (x < 0) { /* If failure to close, FAIL */ if (success) filrej++; success = 0; } if (success && atcapu) zstime(f,yy,0); /* Set file creation date */#ifdef OS2#ifdef __32BIT__#ifdef CK_LABELED if (success && yy->longname.len) os2setlongname(f, yy->longname.val);#endif /* CK_LABELED */#endif /* __32BIT__ */#endif /* OS2 */ if (success == 0) xitsta |= W_RECV; /* And program return code *//* Handle dispositions from attribute packet... */#ifndef NOFRILLS if (yy->disp.len != 0) { p = yy->disp.val; c = *p++; if (c == 'M') { /* Mail to user. */ x = zmail(p,filnam); /* Do the system's mail command */ if (x < 0) success = 0; /* Remember status */ tlog(F110,"mailed",filnam,0L); tlog(F110," to",p,0L); zdelet(filnam); /* Delete the file */ } else if (c == 'P') { /* Print the file. */ x = zprint(p,filnam); /* Do the system's print command */ if (x < 0) success = 0; /* Remember status */ tlog(F110,"printed",filnam,0L); tlog(F110," with options",p,0L);#ifndef VMS#ifndef STRATUS /* spooler will delete file after print complete in VOS & VMS */ if (zdelet(filnam) && x == 0) x = 3; /* Delete the file */#endif /* STRATUS */#endif /* VMS */ } }#endif /* NOFRILLS */ debug(F101,"reof returns","",x); *filnam = '\0'; return(x);}/* R E O T -- Receive End Of Transaction */VOIDreot() { cxseen = czseen = discard = 0; /* Reset interruption flags */ tstats();}/* S F I L E -- Send File header or teXt header packet *//* Call with x nonzero for X packet, zero for F packet *//* Returns 1 on success, 0 on failure */intsfile(x) int x; {#ifdef pdp11#define PKTNL 64#else#define PKTNL 256#endif /* pdp11 */ char pktnam[PKTNL+1]; /* Local copy of name */ char *s; /* cmarg2 or filnam (with that precedence) have the file's name */ lsstate = 0; /* Cancel locking-shift state */ if (nxtpkt() < 0) return(0); /* Bump packet number, get buffer */ if (x == 0) { /* F-Packet setup */ if (cmarg2 && *cmarg2) { /* If we have a send-as name, */ debug(F111,"sfile cmarg2",cmarg2,cmarg2); strncpy(pktnam,cmarg2,PKTNL); /* copy it literally, */ cmarg2 = ""; /* and blank it out for next time. */ } else { /* Otherwise... */ debug(F101,"sfile fnspath","",fnspath); if (fnspath) { /* Stripping path names? */ char *t; /* Yes. */ zstrip(filnam,&t); /* Strip off the path. */ debug(F110,"sfile zstrip",t,0); if (!t) t = "UNKNOWN"; /* Be cautious... */ else if (*t == '\0') t = "UNKNOWN"; strncpy(pktnam,t,PKTNL); /* Copy stripped name literally. */ } else { /* No stripping. */ strcpy(pktnam,filnam); /* Copy whole name. */ } /* pktnam[] has the packet name, filnam[] has the original name. */ /* But we still need to convert pktnam if FILE NAMES CONVERTED. */ debug(F101,"SATURDAY fncnv","",fncnv); if (fncnv) { /* If converting names, */ zltor(pktnam,(char *)srvcmd); /* convert it to common form, */ strcpy(pktnam,(char *)srvcmd); /* with srvcmd as temp buffer */ *srvcmd = NUL; } } debug(F110,"sfile",filnam,0); /* Log debugging info */ debug(F110," pktnam",pktnam,0); if (openi(filnam) == 0) /* Try to open the input file */ return(0); #ifdef CK_RESEND if (sendmode == SM_PSEND) /* PSENDing? */ if (sendstart > 0L) /* Starting position */ if (zfseek(sendstart) < 0) /* seek to it... */ return(0);#endif /* CK_RESEND */ s = pktnam; /* Name for packet data field */#ifdef OS2 /* Never send a disk letter. */ if (isalpha(*s) && (*(s+1) == ':')) s += 2;#endif /* OS2 */ } else { /* X-packet setup, not F-packet. */ debug(F110,"sxpack",cmdstr,0); /* Log debugging info */ s = cmdstr; /* Name for data field */ } /* Now s points to the string that goes in the packet data field. */ encstr((CHAR *)s); /* Encode the name. */ /* Send the F or X packet */ /* If the encoded string did not fit into the packet, it was truncated. */ #ifdef COMMENT spack((char) (x ? 'X' : 'F'), pktnum, size, encbuf+7);#else spack((char) (x ? 'X' : 'F'), pktnum, size, data);#endif /* COMMENT */ if (x == 0) { /* Display for F packet */ if (displa) { /* Screen */ screen(SCR_FN,'F',(long)pktnum,filnam); screen(SCR_AN,0,0l,pktnam); screen(SCR_FS,0,fsize,""); }#ifdef pdp11 tlog(F110,"Sending",filnam,0L); /* Transaction log entry */#else#ifndef ZFNQFP tlog(F110,"Sending",filnam,0L);#else { /* Log fully qualified filename */ char *p = NULL, *q = filnam; if ((p = malloc(CKMAXPATH+1))) if (zfnqfp(filnam, CKMAXPATH, p)) q = p; tlog(F110,"Sending",q,0L); if (p) free(p); }#endif /* ZFNQFP */#endif /* pdp11 */ tlog(F110," as",pktnam,0L); if (binary) { /* Log file mode in transaction log */ tlog(F101," mode: binary","",(long) binary); } else { /* If text mode, check character set */ tlog(F100," mode: text","",0L);#ifndef NOCSETS tlog(F110," file character set",fcsinfo[fcharset].name,0L); if (tcharset == TC_TRANSP) tlog(F110," xfer character set","transparent",0L); else tlog(F110," xfer character set",tcsinfo[tcharset].name,0L);#endif /* NOCSETS */ } } else { /* Display for X-packet */ screen(SCR_XD,'X',(long)pktnum,cmdstr); /* Screen */ tlog(F110,"Sending from:",cmdstr,0L); /* Transaction log */ } intmsg(++filcnt); /* Count file, give interrupt msg */ first = 1; /* Init file character lookahead. */ ffc = 0L; /* Init file character counter. */ cps = oldcps = 0L; /* Init cps statistics */ rejection = -1; fsecs = gtimer(); /* Time this file started */ debug(F101,"SFILE fsecs","",fsecs); return(1);}/* S D A T A -- Send a data packet *//* Returns -1 if no data to send (end of file), -2 if connection is broken. If there is data, a data packet is sent, and sdata() returns 1. For window size greater than 1, we keep sending data packets until window is full or characters start to appear from the other Kermit, whichever happens first. In the windowing case, when there is no more data left to send (or when sending has been interrupted), sdata() does nothing and returns 0 each time it is called until the current packet number catches up to the last data packet that was sent.*/intsdata() { int i, x, len; debug(F101,"sdata entry, first","",first); debug(F101," drain","",drain);/* The "drain" flag is used with window size > 1. It means we have sent *//* our last data packet. If called and drain is not zero, then we return *//* 0 as if we had sent an empty data packet, until all data packets have *//* been ACK'd, then then we can finally return -1 indicating EOF, so that *//* the protocol can switch to seof state. This is a kludge, but at least *//* it's localized... */ if (first == 1) drain = 0; /* Start of file, init drain flag. */ if (drain) { /* If draining... */ debug(F101,"sdata draining, winlo","",winlo); if (winlo == pktnum) /* If all data packets are ACK'd */ return(-1); /* return EOF indication */ else /* otherwise */ return(0); /* pretend we sent a data packet. */ } debug(F101,"sdata sbufnum","",sbufnum); for (i = sbufnum; i > 0; i--) { debug(F101,"sdata countdown","",i); x = nxtpkt(); /* Get next pkt number and buffer */ debug(F101,"sdata packet","",pktnum); if (x < 0) return(0); if (cxseen || czseen) { /* If interrupted, done. */ if (wslots > 1) { drain = 1; debug(F101,"sdata cx/zseen, drain","",cxseen); return(0); } else { return(-1); } } debug(F101,"sdata spsiz","",spsiz); len = getpkt(spsiz,1); if (len == 0) { /* Done if no data. */ if (pktnum == winlo) return(-1); drain = 1; /* But can't return -1 until all */ debug(F101,"sdata eof, drain","",drain); return(0); /* ACKs are drained. */ } spack('D',pktnum,len,data); /* Send the data packet. *//* We should also want to call chkint() here to catch keyboard interruptions. But its return codes don't tell us whether we should return from here or keep going.*/ x = ttchk(); /* Peek at input buffer. */ debug(F101,"sdata ttchk","",x); /* ACKs waiting, maybe? */ if (x < 0) /* Or connection broken? */ return(-2);/* Here we check to see if any ACKs or NAKs have arrived, in which case we break out of the D-packet-sending loop and return to the state switcher to process them. This is what makes our windows slide instead of lurch.*/ if (#ifdef GEMDOS/* In the Atari ST version, ttchk() can only return 0 or 1. But note: x will probably always be > 0, since the as-yet-unread packet terminator from the last packet is probably still in the buffer, so sliding windows will probably never happen when the Atari ST is the file sender. The alternative is to say "if (0)", in which case the ST will always send a window full of packets before reading any ACKs or NAKs.*/ x > 0 #else /* !GEMDOS *//* In most other versions, ttchk() returns the actual count. It can't be a Kermit packet if it's less than five bytes long.*/ x > 4 + bctu #endif /* GEMDOS */ ) return(1); /* Yes, stop sending data packets */ } /* and go try to read the ACKs. */ return(1);}/* S E O F -- Send an End-Of-File packet *//* Call with a string pointer to character to put in the data field, *//* or else a null pointer or "" for no data. *//* There are two "send-eof" functions. seof() is used to send the normal eof packet at the end of a file's data (even if the file has no data), or when a file transfer is interrupted. sxeof() is used to send an EOF pa
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -