📄 ckcfn3.c
字号:
/* C K C F N 3 -- Packet buffer management for C-Kermit *//* (plus assorted functions tacked on at the end) *//* Author: Frank da Cruz <fdc@columbia.edu>, Columbia University Academic Information Systems, New York City. Copyright (C) 1985, 2000, Trustees of Columbia University in the City of New York. All rights reserved. See the C-Kermit COPYING.TXT file or the copyright text in the ckcmai.c module for disclaimer and permissions.*//* Note -- if you change this file, please amend the version number and date at the top of ckcfns.c accordingly.*/#include "ckcsym.h"#include "ckcdeb.h"#include "ckcasc.h"#include "ckcker.h"#include "ckcxla.h"/* C K M K D I R -- Create a directory *//* Call with: int fc = 0 to create, nonzero to remove, a directory. char * s = pointer to name of directory to create or remove. char ** r = address of pointer to return name or message. int m = 1 to print error messages, 0 to be silent. int cvt = 1 means convert s from standard format to local format; 0 means use s as is. Returns: 0 on success (directory was created or removed). -1 when attempt to create the directory failed. -2 on internal error (e.g. no code for creating directories). On success, the name is pointed to by p. On failure, the reason is pointed to by p.*/#ifdef CK_MKDIRstatic char ckmkdbuf[CKMAXPATH+1];#else#ifdef datageneralstatic char ckmkdbuf[CKMAXPATH+1];#endif /* datageneral */#endif /* CK_MKDIR */#ifdef CK_MKDIRintckmkdir(fc,s,r,m,cvt) int fc; char * s; char ** r; int m; int cvt; { int x, rc = -2; char tmpbuf[CKMAXPATH+1]; char buf2[CKMAXPATH+1]; if (!s) s = ""; debug(F110,"ckmkdir 1 fc",s,fc); if (!*s) { sprintf(ckmkdbuf,"%s: no name given", (fc == 0) ? "mkdir" : "rmdir"); *r = ckmkdbuf; return(-2); }#ifdef datageneral/* Come back and make this nicer later */ if (fc == 0) { /* mkdir */ rc = createdir(s,0); } else { /* rmdir */ sprintf(tmpbuf,"delete %s",s); /* AOS/VS rmdir() is a no-op. */ debug(F110,"ckmkdir 2",tmpbuf,0); rc = system(tmpbuf); } *r = NULL;#else /* not datageneral *//* First make sure the name has an acceptable directory-name format */#ifdef VMS { char *p = s; int lb = 0, rb = 0, sl = 0; while (*p) { if (*p == '[' || *p == '<') lb++; /* Count brackets */ else if (*p == ']' || *p == '>') rb++; else if (*p == '/') sl++; /* and slashes */ p++; } if (lb != 1 && rb != 1 && sl == 0 && p > s && *(p-1) != ':') { /* Probably just a word - convert to VMS format */ sprintf(buf2,"[%s%s]", (*s == '.') ? "" : ".", s); s = buf2; } else if (lb == 0 && rb == 0 && sl != 0 && p > s && *(p-1) != ':') { int flag = 0; /* Seems to be in UNIX format */ x = strlen(s); if (x > 0 && s[x-1] != '/') flag = 1; sprintf(buf2,"%s%s",s,flag ? "/" : ""); s = buf2; } if (s == buf2) { ckstrncpy(tmpbuf,s,CKMAXPATH+1); s = tmpbuf; } debug(F110,"ckmkdir 2+VMS",s,0); }#else#ifdef UNIXOROSK#ifdef DTILDE s = tilde_expand(s);#endif /* DTILDE */ ckstrncpy(tmpbuf,s,CKMAXPATH+1); s = tmpbuf; x = strlen(s); if (x > 0 && s[x-1] != '/') { /* Must end in "/" for zmkdir() */ s[x] = '/'; s[x+1] = NUL; debug(F110,"ckmkdir 2+UNIXOROSK",s,0); }#else /* UNIXOROSK */#ifdef OS2 ckstrncpy(tmpbuf,s,CKMAXPATH+1); s = tmpbuf; x = strlen(s); if (x > 0 && s[x-1] != '/') { /* Must end in "/" for zmkdir() */ s[x] = '/'; s[x+1] = NUL; debug(F110,"ckmkdir 2+OS2",s,0); }#endif /* OS2 */#endif /* UNIXOROSK */#endif /* VMS */#ifdef NZLTOR /* Server is calling us, so convert to local format if necessary */ if (cvt) { nzrtol(s,(char *)buf2,1,PATH_ABS,CKMAXPATH); s = buf2; debug(F110,"ckmkdir 3",s,0); }#endif /* NZLTOR */ debug(F110,"ckmkdir 4",s,0); if (fc == 0) { /* Making */#ifdef CK_MKDIR rc = zmkdir(s);#else#ifdef NT rc = _mkdir(s);#else rc = mkdir(s,0777);#endif /* NT */#endif /* CK_MKDIR */ } else { /* Removing */#ifdef ZRMDIR rc = zrmdir(s);#else#ifdef NT rc = _rmdir(s);#else#ifdef OSK rc = -2;#else rc = rmdir(s);#endif /* OSK */#endif /* NT */#endif /* ZRMDIR */ }#endif /* datageneral */ debug(F101,"ckmkdir rc","",rc); if (rc == -2) { sprintf(ckmkdbuf, "Directory %s not implemented in this version of C-Kermit", (fc == 0) ? "creation" : "removal" ); *r = ckmkdbuf; if (m) printf("%s\n",*r); } else if (rc < 0) { if (m) perror(s); sprintf(ckmkdbuf,"%s: %s",s,ck_errstr()); *r = ckmkdbuf; } else if (fc == 0 && zfnqfp(s,CKMAXPATH,ckmkdbuf)) { *r = ckmkdbuf; } else if (fc != 0) { sprintf(ckmkdbuf,"%s: removed",s); *r = ckmkdbuf; } return(rc);}#endif /* CK_MKDIR */#ifndef NOXFER /* Rest of this file... */#ifndef NODISPO#ifdef pdp11#define NODISPO#endif /* pdpd11 */#endif /* NODISPO */#ifdef PIPESENDint pipesend = 0;#endif /* PIPESEND */extern int unkcs, wmax, wcur, discard, bctu, bctl, local, fdispla, what, sendmode, opnerr, dest, epktrcvd, epktsent, filestatus, eofmethod;extern long sendstart, calibrate, fncnv, fnrpath;extern char * ofn2, * rfspec, * sfspec;extern char ofn1[];extern int ofn1x;extern char * ofperms;#ifdef VMSextern int batch;#elseextern int backgrd;#endif /* VMS */extern int xflg, remfile, remappd;extern CHAR *data;extern char filnam[];#ifndef NOFRILLSextern int rprintf, rmailf; /* REMOTE MAIL, PRINT */char optbuf[100]; /* Options for MAIL or REMOTE PRINT */#endif /* NOFRILLS */extern int wslots;extern int fblksiz, frecl, forg, frecfm, fncact, fncsav, fcctrl, lf_opts;extern CHAR * srvcmd;extern int binary, spsiz;extern int pktnum, cxseen, czseen, nfils, stdinf;extern int memstr, stdouf, keep, sndsrc, hcflg;extern int server, en_cwd, en_mai, en_pri;/* Attributes in/out enabled flags */extern int atenci, atenco, atdati, atdato, atleni, atleno, atblki, atblko, attypi, attypo, atsidi, atsido, atsysi, atsyso, atdisi, atdiso;#ifdef CK_PERMSextern int atlpri, atlpro, atgpri, atgpro;#endif /* CK_PERMS */#ifdef STRATUSextern int atfrmi, atfrmo, atcrei, atcreo, atacti, atacto;#endif /* STRATUS */#ifdef datageneralextern int quiet;#endif /* datageneral */extern long fsize, filcnt, ffc, tfc;#ifndef NOCSETS_PROTOTYP (VOID setxlate, (void));extern int tcharset, fcharset;extern int ntcsets, xlatype;extern struct csinfo tcsinfo[], fcsinfo[];#endif /* NOCSETS *//* Variables global to Kermit that are defined in this module */#ifdef CKXXCHAR /* DOUBLE / IGNORE char table */int dblflag = 0;int ignflag = 0;short dblt[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};#endif /* CKXXCHAR */int winlo; /* packet number at low window edge */int sbufnum; /* number of free buffers */int dum001 = 1234; /* protection... */int sbufuse[MAXWS]; /* buffer in-use flag */int dum003 = 1111;int rbufnum; /* number of free buffers */int dum002 = 4321; /* more protection */int rbufuse[MAXWS]; /* buffer in-use flag */int sseqtbl[64]; /* sequence # to buffer # table */int rseqtbl[64]; /* sequence # to buffer # table */int sacktbl[64]; /* sequence # ack table */int o_isopen = 0, i_isopen = 0; /* Input & output files are open */#ifdef DYNAMICstruct pktinfo *s_pkt = NULL; /* array of pktinfo structures */struct pktinfo *r_pkt = NULL; /* array of pktinfo structures */#elsestruct pktinfo s_pkt[MAXWS]; /* array of pktinfo structures */struct pktinfo r_pkt[MAXWS]; /* array of pktinfo structures */#endif /* DYNAMIC */#ifdef DEBUGchar xbuf[200]; /* For debug logging */#endif /* DEBUG */#ifdef DYNAMICCHAR *bigsbuf = NULL, *bigrbuf = NULL;#elsechar bigsbt[8]; /* Protection (shouldn't need this). */ /* BUT DON'T REMOVE IT! */CHAR bigsbuf[SBSIZ + 5]; /* Send-packet buffer area */char bigrbt[8]; /* Safety padding */CHAR bigrbuf[RBSIZ + 5]; /* Receive-packet area */#endifint bigsbsiz = SBSIZ; /* Sizes of big send & rcv buffers. */int bigrbsiz = RBSIZ;#ifdef VMSint zchkpath(char *s);#endif /* VMS *//* FUNCTIONS */VOIDdofast() { long maxbufsiz = RBSIZ; /* Configuration parameters */ int maxpktsiz = MAXSP; extern int spsizf, /* For bug in IRIX Telnet server */ rpsiz, urpsiz, spsizr, spmax, wslotr; extern struct ck_p ptab[]; if (maxpktsiz < 40) /* Long packet length */ maxpktsiz = 40; else if (maxpktsiz > 4000) maxpktsiz = 4000; wslotr = maxbufsiz / maxpktsiz; if (wslotr > MAXWS) /* Window slots */ wslotr = MAXWS; if (wslotr > 30) wslotr = 30; else if (wslotr < 1) wslotr = 1; urpsiz = adjpkl(maxpktsiz,wslotr,maxbufsiz); ptab[PROTO_K].rpktlen = urpsiz; rpsiz = (urpsiz > 94) ? 94 : urpsiz; /* Max non-long packet length */ debug(F111,"dofast","uprsiz",urpsiz);#ifdef IRIX#ifndef IRIX65 /* IRIX Telnet server chops off writes longer than 4K */ spsiz = spmax = spsizr = urpsiz; debug(F101,"doarg Q IRIX spsiz","",spsiz); spsizf = 1;#endif /* IRIX65 */#endif /* IRIX */#ifdef CK_SPEED setprefix(PX_CAU); /* Cautious unprefixing */#endif /* CK_SPEED */}/* For sanity, use "i" for buffer slots, "n" for packet numbers. *//* I N I B U F S *//* Allocates the big send and receive buffers. Call with size for big send buffer (s) and receive buffer (r). These sizes can be different. Attempts to allocate buffers of the requested size, but if it can't, it will allocate smaller ones. Sets global variables bigsbsiz and bigrbsiz to the actual sizes, and bigsbuf and bigrbuf pointing to the actual buffers. Designed to be called more than once. Returns 0 on success, -1 on failure.*/CHAR *bigbufp = NULL;intinibufs(s,r) int s, r; {#ifdef DYNAMIC unsigned int size;#ifdef OS2 unsigned /* Don't you wish everybody had unsigned long... */#endif /* OS2 */ long z; int x; debug(F101,"inibufs s","",s); debug(F101,"inibufs r","",r); if (s < 80 || r < 80) return(-1); /* Validate arguments. */ if (!s_pkt) { /* Allocate packet info structures */ if (!(s_pkt = (struct pktinfo *) malloc(sizeof(struct pktinfo)*MAXWS))) fatal("ini_pkts: no memory for s_pkt"); } for (x = 0; x < MAXWS; x++) s_pkt[x].pk_adr = NULL; /* Initialize addresses */ if (!r_pkt) { if (!(r_pkt = (struct pktinfo *) malloc(sizeof(struct pktinfo)*MAXWS))) fatal("ini_pkts: no memory for s_pkt"); } for (x = 0; x < MAXWS; x++) r_pkt[x].pk_adr = NULL; /* Initialize addresses */ if (!srvcmd) { /* Allocate srvcmd buffer */ srvcmd = (CHAR *) malloc(r + 100); if (!srvcmd) return(-1); *srvcmd = NUL; } if (bigbufp) { /* Free previous buffers, if any. */ free(bigbufp); bigbufp = NULL; } size = s + r + 40; /* Combined requested size + padding */ z = (unsigned) s + (unsigned) r + 40; debug(F101,"inibufs size 1","",size); debug(F101,"inibufs size z","",z); if ((long) size != z) { debug(F100,"inibufs overflow","",0); size = 65535; } /* Try to get the space. If malloc fails, try to get a little less. */ /* (Obviously, this algorithm can be refined.) */ while (!(bigbufp = (CHAR *) malloc(size))) { debug(F101,"inibufs bigbuf malloc failed","",size); size = (size * 2) / 3; /* Failed, cut size by 1/3. */ if (size < 200) /* Try again until too small. */ return(-1); } debug(F101,"inibufs size 2","",size); /* OK, we got some space. *//* Now divide the allocated space between the send and receive buffers in the requested proportion. The natural formula would be (s / (s + r)) * size (for the send buffer), but that doesn't work with integer arithmetic and we can't use floating point because some machines don't have it. This can be rearranged as (s * size) / (s + r). But (s * size) can be VERY large, too large for 32 bits. So let's do it this way. This arithmetic works for buffer sizes up to about 5,000,000.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -