ckuus7.c
资源名称:cku197.tar.Z [点击查看]
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:362k
源码类别:
通讯/手机编程
开发平台:
Windows_Unix
- /* negotiations change if necessary. */
- }
- } else { /* They just said "set host" */
- s = dftty; /* So go back to normal */
- _local = dfloc; /* default tty, location, */
- if (zz) {
- setflow(); /* Maybe change flow control */
- haveline = 1; /* (* is this right? *) */
- /* why aren't we calling clsconnx()? */
- #ifdef CKLOGDIAL
- dologend();
- #endif /* CKLOGDIAL */
- return(success = 1);
- }
- }
- #endif /* NETCONN */
- }
- /* Serial tty device, possibly modem, connection... */
- if (xx == XYLINE /* SET LINE or SET PORT */
- #ifdef CK_TAPI
- || xx == XYTAPI_LIN /* SET TAPI LINE */
- #endif /* CK_TAPI */
- ) {
- #ifdef OS2
- /*
- User can type:
- COM1..COM8 = Regular COM port
- 1..8 = Synonym for COM1..COM8, is translated to COM1..COM8
- _n = (n is a number) = open file handle
- string = any text string = name of some other kind of device,
- taken literally, as given.
- */
- s = "Communication device name";
- #ifdef CK_TAPI
- if (TAPIAvail)
- cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
- if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
- xx == XYTAPI_LIN ) {
- slmsg = "TAPI device not configured";
- printf("nNo TAPI Line Devices are configured for this systemn");
- return(-9);
- }
- if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
- s = "tapi"; /* (whatever it is) */
- } else { /* Query the user */
- #endif /* CK_TAPI */
- /* Now parse optional switches and then device name */
- confirmed = 0;
- cmfdbi(&sw,_CMKEY,"Device name, or switch",
- "","",npsltab,4,xxstring,psltab,&fl);
- cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
- while (1) {
- x = cmfdb(&sw);
- debug(F101,"setlin cmfdb","",x);
- if (x < 0)
- if (x != -3)
- return(x);
- if (x == -3) {
- if ((x = cmcfm()) < 0) {
- return(x);
- } else {
- confirmed = 1;
- break;
- }
- }
- if (cmresult.fcode == _CMFLD) {
- s = cmresult.sresult;
- break;
- } else if (cmresult.fcode == _CMKEY) {
- switch (cmresult.nresult) {
- case SL_CNX: /* /CONNECT */
- cx = 1;
- sx = 0;
- break;
- case SL_SRV: /* /SERVER */
- cx = 0;
- sx = 1;
- break;
- }
- }
- }
- #ifdef CK_TAPI
- }
- #endif /* CK_TAPI */
- debug(F110,"OS2 SET PORT s",s,0);
- y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
- debug(F101,"OS2 SET PORT x","",x);
- debug(F101,"OS2 SET PORT y","",y);
- if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
- s = os2devtab[x+8].kwd; /* Substitite its real name */
- #ifdef NT
- xxtapi = 0;
- #else /* NT */
- xxslip = xxppp = 0;
- #endif /* NT */
- debug(F110,"OS2 SET PORT subst s",s,"");
- #ifndef NT
- } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
- s = os2devtab[x-8].kwd; /* Substitite its real name */
- debug(F110,"OS2 SET PORT SLIP subst s",s,"");
- xxslip = 1;
- xxppp = 0;
- } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
- s = os2devtab[x-16].kwd; /* Substitite its real name */
- debug(F110,"OS2 SET PORT PPP subst s",s,"");
- xxppp = 1;
- xxslip = 0;
- if ((y = cmkey(os2ppptab,
- nos2ppp,
- "PPP driver interface",
- "ppp0",
- xxstring)
- ) < 0)
- return(y);
- debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
- xxppp = (y % 10) + 1;
- #endif /* NT */
- } else if (*s == '_') { /* User used "_" prefix */
- s++; /* Remove it */
- /* Rest must be numeric */
- debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
- if (!rdigits(s)) {
- slmsg = "Invalid file handle";
- printf("?Invalid format for file handlen");
- return(-9);
- }
- #ifdef NT
- xxtapi = 0;
- #else /* NT */
- xxslip = xxppp = 0;
- #endif /* NT */
- } else { /* A normal COMx port or a string */
- s = brstrip(s); /* Strip braces if any */
- #ifdef NT
- #ifdef CK_TAPI
- /* Windows TAPI support - Look up in keyword table */
- if (tapilinetab && _tapilinetab && ntapiline > 0) {
- if (!ckstrcmp(s,"tapi",4,0)) {
- /* Find out what the lowest numbered TAPI device is */
- /* and use it as the default. */
- int j = 9999, k = -1;
- for (i = 0; i < ntapiline; i++) {
- if (tapilinetab[i].kwval < j) {
- j = tapilinetab[i].kwval;
- k = i;
- }
- }
- if (k >= 0)
- s = _tapilinetab[k].kwd;
- else
- s = "";
- if ((y = cmkey(_tapilinetab,ntapiline,
- "TAPI device name",s,xxstring)) < 0)
- return(y);
- xxtapi = 1;
- /* Get the non Underscored string */
- for (i = 0; i < ntapiline; i++ ) {
- if (tapilinetab[i].kwval == y) {
- s = tapilinetab[i].kwd;
- break;
- }
- }
- } else
- xxtapi = 0;
- }
- #endif /* CK_TAPI */
- #else /* NT */
- /* not OS/2 SLIP or PPP */
- xxslip = xxppp = 0;
- #endif /* NT */
- }
- strcpy(tmpbuf,s); /* Copy to a safe place */
- s = tmpbuf;
- if ((x = cmcfm()) < 0)
- return(x);
- #else /* !OS2 */
- cmfdbi(&sw,_CMKEY,"Device name, or switch",
- "","",npsltab,4,xxstring,psltab,&tx);
- cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
- while (!confirmed) {
- x = cmfdb(&sw);
- debug(F101,"setlin cmfdb","",x);
- if (x < 0)
- if (x != -3)
- return(x);
- if (x == -3) {
- if ((x = cmcfm()) < 0) {
- return(x);
- } else {
- confirmed = 1;
- break;
- }
- }
- switch (cmresult.fcode) {
- case _CMTXT:
- strcpy(tmpbuf,cmresult.sresult);
- s = tmpbuf;
- debug(F110,"setlin CMTXT",tmpbuf,0);
- confirmed = 1;
- break;
- case _CMKEY: /* Switch */
- debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
- switch (cmresult.nresult) {
- case SL_CNX: /* /CONNECT */
- cx = 1;
- sx = 0;
- break;
- case SL_SRV: /* /SERVER */
- cx = 0;
- sx = 1;
- break;
- #ifdef VMS
- case SL_SHR: /* /SHARE */
- shr = 1;
- break;
- case SL_NSH: /* /NOSHARE */
- shr = 0;
- break;
- #endif /* VMS */
- }
- continue;
- default:
- debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
- slmsg = "Internal error";
- printf("?Internal parsing errorn");
- return(-9);
- }
- }
- #endif /* OS2 */
- if (!confirmed)
- if ((x = cmcfm()) < 0)
- return(x);
- debug(F101,"setlin confirmed mdmtyp","",mdmtyp);
- if (clsconnx(1) < 0) /* Close the connection */
- return(success = 0);
- if (*s) { /* They gave a device name */
- _local = -1; /* Let ttopen decide about it */
- } else { /* They just said "set line" */
- s = dftty; /* so go back to normal tty */
- _local = dfloc; /* and mode. */
- }
- #ifdef VMS
- {
- extern int ok_to_share;
- ok_to_share = shr;
- }
- #endif /* VMS */
- #ifdef OS2 /* Must wait until after ttclos() */
- #ifdef NT /* to change these settings */
- #ifdef CK_TAPI
- tttapi = xxtapi;
- #endif /* CK_TAPI */
- #else
- ttslip = xxslip;
- ttppp = xxppp;
- #endif /* NT */
- debug(F110,"OS2 SET PORT final s",s,"");
- #endif /* OS2 */
- }
- success = 0;
- if (mdmtyp > -1) { /* Serial connections... */
- /* Open the new line */
- if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
- cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
- #ifdef COMMENT
- flow = cxflow[cxtype]; /* Set connection type and flow */
- #else
- setflow(); /* Only if autoflow()! */
- #endif /* COMMENT */
- success = 1;
- #ifdef CK_TAPI
- /* if the line is a tapi device, then we need to auto-execute */
- /* SET MODEM TYPE TAPI - which we do the equivalent of here. */
- if (xxtapi) {
- extern int usermdm;
- usermdm = 0;
- initmdm(38); /* From ckudia.c n_TAPI == 38 */
- }
- #endif /* CK_TAPI */
- } else {
- #ifdef OS2ONLY
- if (!strcmp(s,dftty)) /* Do not generate an error with dftty */
- ;
- else if (y == -6 && ttslip) {
- slmsg = "Can't access SLIP driver";
- if (!quiet || cmdsrc() == 0)
- printf("?Unable to access SLIP driver.n");
- } else if (y == -6 && ttppp) {
- if (!quiet || cmdsrc() == 0)
- slmsg = "Can't access PPP driver";
- printf("?Unable to access PPP driver (wrong interface?)n");
- } else
- #endif /* OS2ONLY */
- if (y == -2) {
- slmsg = "Timed out - no carrier";
- if (!quiet || cmdsrc() == 0) {
- printf("?Timed out, no carrier.n");
- printf(
- "Try SET CARRIER OFF and SET LINE again, or elsen");
- printf("SET MODEM, SET LINE, and then DIAL.n");
- }
- } else if (y == -3) {
- slmsg = "Access to lock denied";
- if (!quiet || cmdsrc() == 0) {
- #ifdef UNIX
- printf(
- "Sorry, write access to UUCP lockfile directory denied.n");
- #ifndef NOHINTS
- if (hints) {
- printf("n*************************n");
- printf(
- "HINT (Use SET HINTS OFF to suppress future hints):n");
- printf(
- "Please read the installation instructions file, %sckuins.txt,n",
- k_info_dir ? k_info_dir : ""
- );
- printf(
- "or the UNIX appendix of the manual, "Using C-Kermit".n"
- );
- printf("*************************nn");
- }
- #endif /* NOHINTS */
- #else
- printf("Sorry, access to lock denied: %sn",s);
- #endif /* UNIX */
- }
- } else if (y == -4) {
- slmsg = "Access to device denied";
- if (!quiet || cmdsrc() == 0) {
- printf("Sorry, access to device denied: %sn",s);
- #ifdef UNIX
- #ifndef NOHINTS
- if (hints) {
- printf("n*************************n");
- printf(
- "HINT (Use SET HINTS OFF to suppress future hints):n");
- printf(
- "Please read the installation instructions file, %sckuins.txt,n",
- k_info_dir ? k_info_dir : ""
- );
- printf(
- "or the UNIX appendix of the manual, "Using C-Kermit".n"
- );
- printf("*************************nn");
- }
- #endif /* NOHINTS */
- #endif /* UNIX */
- }
- } else if (y == -5) {
- slmsg = "Device is in use or unavailable";
- if (!quiet || cmdsrc() == 0)
- #ifdef VMS
- printf(
- "Sorry, device is in use or otherwise unavailable: %sn",s);
- #else
- printf("Sorry, device is in use: %sn",s);
- #endif /* VMS */
- } else { /* Other error. */
- slmsg = "Device open failed";
- if (
- #ifdef VMS
- 1
- #else
- errno
- #endif /* VMS */
- ) {
- int x; /* Find a safe, long buffer */
- makestr(&tmpslmsg,ck_errstr());
- slmsg = tmpslmsg;
- #ifndef VMS
- debug(F111,"setlin serial errno",slmsg,errno);
- #endif /* VMS */
- if (!quiet || cmdsrc() == 0) {
- x = strlen(line) + 2; /* for the error message. */
- if (LINBUFSIZ - x > 100) { /* Room for 100 chars */
- tp = line + x;
- sprintf(tp,"Sorry, can't open connection: %s",s);
- perror(tp);
- } else
- printf("Sorry, can't open connection: %sn",s);
- }
- } else if (!quiet || cmdsrc() == 0)
- printf("Sorry, can't open connection: %sn",s);
- }
- }
- }
- #ifdef NETCONN
- else { /* mdmtyp < 0: Network connection */
- char *p;
- int i, n;
- #ifndef NODIAL
- debug(F101,"setlin mynet 3","",mynet);
- debug(F101,"setlin nhcount","",nhcount);
- if ((nhcount > 1) && !quiet && !backgrd) {
- int k;
- printf("%d entr%s found for "%s"%sn",
- nhcount,
- (nhcount == 1) ? "y" : "ies",
- s,
- (nhcount > 0) ? ":" : "."
- );
- for (i = 0; i < nhcount; i++) {
- printf("%3d. %-12s => %-9s %s",
- i+1,n_name,nh_p2[i],nh_p[i]);
- for (k = 0; k < 4; k++) { /* Also list net-specific items */
- if (nh_px[k][i]) /* free format... */
- printf(" %s",nh_px[k][i]);
- else
- break;
- }
- printf("n");
- }
- }
- if (nhcount == 0)
- n = 1;
- else
- n = nhcount;
- #else
- n = 1;
- nhcount = 0;
- #endif /* NODIAL */
- for (i = 0; i < n; i++) { /* Loop for each entry found */
- #ifndef NODIAL
- debug(F101,"setlin loop i","",i);
- if (nhcount > 0) { /* If we found at least one entry... */
- strcpy(line,nh_p[i]); /* Copy the current entry to line[] */
- if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
- mynet = netcmd[x].kwval;
- mdmtyp = 0 - mynet;
- debug(F101,"setlin mynet 4","",mynet);
- } else {
- slmsg = "Network type not supported";
- printf("Error - network type "%s" not supportedn",
- nh_p2[i]
- );
- continue;
- }
- switch (mynet) { /* Net-specific things */
- case NET_TCPB: { /* TCP/IP */
- #ifdef TCPSOCKET
- char *q;
- int flag = 0;
- /* Extract ":service", if any, from host string */
- debug(F110,"setlin service 1",line,0);
- for (q = line; (*q != ' ') && (*q != ':'); q++)
- ;
- if (*q == ':') { *q++ = NUL; flag = 1; }
- debug(F111,"setlin service 2",line,flag);
- /* Get service, if any, from directory entry */
- if (!*srvbuf) {
- if (nh_px[0][i]) {
- ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
- debug(F110,"setlin service 3",srvbuf,0);
- }
- if (flag) {
- ckstrncpy(srvbuf,q,SRVBUFSIZ);
- debug(F110,"setlin service 4",srvbuf,0);
- }
- }
- /* Save the hostname */
- strcpy(hostname,line);
- /* If we have a service, append to host name/address */
- if (*srvbuf) {
- strncat(line, ":", LINBUFSIZ);
- strncat(line, srvbuf, LINBUFSIZ);
- debug(F110,"setlin service 5",line,0);
- }
- #ifdef RLOGCODE
- /* If no service given but command was RLOGIN */
- else if (ttnproto == NP_RLOGIN) { /* add this... */
- strncat(line, ":login",LINBUFSIZ);
- debug(F110,"setlin service 6",line,0);
- }
- #ifdef CK_AUTHENTICATION
- #ifdef CK_KERBEROS
- else if (ttnproto == NP_K4LOGIN ||
- ttnproto == NP_K5LOGIN) { /* add this... */
- strncat(line, ":klogin",LINBUFSIZ);
- debug(F110,"setlin service 7",line,0);
- }
- else if (ttnproto == NP_EK4LOGIN ||
- ttnproto == NP_EK5LOGIN) { /* add this... */
- strncat(line, ":eklogin",LINBUFSIZ);
- debug(F110,"setlin service 8",line,0);
- }
- #endif /* CK_KERBEROS */
- #endif /* CK_AUTHENTICATION */
- #endif /* RLOGCODE */
- else { /* Otherwise, add ":telnet". */
- strncat(line, ":telnet", LINBUFSIZ);
- debug(F110,"setlin service 9",line,0);
- }
- if (tmpusrid) if (tmpusrid[0]) {
- ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
- makestr(&tmpusrid,NULL);
- uidflag = 1;
- }
- /* Fifth field, if any, is user ID (for rlogin) */
- if (nh_px[1][i] && !uidflag)
- ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
- #ifdef RLOGCODE
- if ((ttnproto == NP_RLOGIN
- #ifdef CK_AUTHENTICATION
- #ifdef CK_KERBEROS
- || ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN
- || ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN
- #endif /* CK_KERBEROS */
- #endif /* CK_AUTHENTICATION */
- ) && !uidbuf[0]) {
- slmsg = "Username required";
- printf("Username required for rloginn");
- return(-9);
- }
- #endif /* RLOGCODE */
- #endif /* TCPSOCKET */
- break;
- }
- case NET_PIPE:
- #ifdef NPIPE
- if (!pipename[0]) { /* User didn't give a pipename */
- if (nh_px[0][i]) { /* But directory entry has one */
- if (strcmp(pipename,"\pipe\")) {
- strcpy(pipename,"\pipe\");
- strncat(srvbuf,nh_px[0][i],PIPENAML-6);
- } else {
- ckstrncpy(pipename,nh_px[0][i],PIPENAML);
- }
- debug(F110,"setlin pipeneme",pipename,0);
- }
- }
- #endif /* NPIPE */
- break;
- case NET_SLAT:
- #ifdef SUPERLAT
- if (!slat_pwd[0]) { /* User didn't give a password */
- if (nh_px[0][i]) { /* But directory entry has one */
- ckstrncpy(slat_pwd,nh_px[0][i],18);
- debug(F110,"setlin SuperLAT password",slat_pwd,0);
- }
- }
- #endif /* SUPERLAT */
- break;
- case NET_SX25: /* X.25 keyword parameters */
- case NET_IX25:
- case NET_VX25: {
- #ifdef ANYX25
- int k; /* Cycle through the four fields */
- for (k = 0; k < 4; k++) {
- if (!nh_px[k][i]) /* Bail out if none left */
- break;
- if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
- closgr = atoi(nh_px[k][i]+4);
- debug(F101,"X25 CUG","",closgr);
- } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
- cudata = 1;
- ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
- debug(F110,"X25 CUD",cudata,0);
- } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
- revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
- debug(F101,"X25 REV","",revcall);
- #ifndef IBMX25
- } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
- int x3par, x3val;
- char *s1, *s2;
- s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
- while (*s2) { /* Pick them apart */
- if (*s2 == ':') {
- *s2 = NUL;
- x3par = atoi(s1);
- s1 = ++s2;
- continue;
- } else if (*s2 == ',') {
- *s2 = NUL;
- x3val = atoi(s1);
- s1 = ++s2;
- debug(F111,"X25 PAD",x3par,x3val);
- if (x3par > -1 &&
- x3par <= MAXPADPARMS)
- padparms[x3par] = x3val;
- continue;
- } else
- s2++;
- }
- #endif /* IBMX25 */
- }
- }
- #endif /* ANYX25 */
- break;
- }
- default: /* Nothing special for other nets */
- break;
- }
- } else { /* No directory entries found. */
- strcpy(line,tmpbuf); /* Put this back... */
- if (mynet == NET_TCPB) /* If the user gave a TCP service */
- strcpy(hostname,line);
- if (*srvbuf) { /* append it to host name/address */
- strncat(line, ":", LINBUFSIZ);
- strncat(line, srvbuf,LINBUFSIZ);
- }
- }
- #endif /* NODIAL */
- /*
- Get here with host name/address and all net-specific
- parameters set, ready to open the connection.
- */
- mdmtyp = -mynet; /* This should have been done */
- /* already but just in case ... */
- debug(F110,"setlin net line[] before ttopen",line,0);
- debug(F101,"setlin net mdmtyp before ttopen","",mdmtyp);
- debug(F101,"setlin net ttnproto","",ttnproto);
- #ifdef CK_AUTHENTICATION
- if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- a_type > -1) {
- if (!sl_auth_saved) {
- int x;
- for (x = 0; x < AUTHTYPLSTSZ; x++)
- sl_auth_type_user[x] = auth_type_user[x];
- sl_auth_saved = 1;
- }
- if (!sl_topt_a_s_saved) {
- sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
- sl_topt_a_s_saved = 1;
- }
- if (!sl_topt_a_c_saved) {
- sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
- sl_topt_a_c_saved = 1;
- }
- switch (a_type) {
- case AUTHTYPE_AUTO:
- auth_type_user[0] = AUTHTYPE_AUTO;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
- break;
- case AUTHTYPE_NULL:
- auth_type_user[0] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
- break;
- #ifdef CK_SRP
- case AUTHTYPE_SRP:
- auth_type_user[0] = AUTHTYPE_SRP;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
- #endif /* CK_SRP */
- #ifdef CK_SSL
- case AUTHTYPE_SSL:
- auth_type_user[0] = AUTHTYPE_SSL;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
- #endif /* CK_SSL */
- #ifdef NT
- case AUTHTYPE_NTLM:
- auth_type_user[0] = AUTHTYPE_NTLM;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
- #endif /* NT */
- #ifdef CK_KERBEROS
- case AUTHTYPE_KERBEROS_V4:
- auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
- case AUTHTYPE_KERBEROS_V5:
- auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
- auth_type_user[1] = AUTHTYPE_NULL;
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
- break;
- #endif /* CK_KERBEROS */
- }
- }
- /*
- If the user is going to require a Kerberos connection
- of a particular type, let's make sure we have a valid TGT.
- */
- slmsg = "Authentication failure";
- if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- (line[0] == '*' &&
- TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
- line[0] != '*' &&
- TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
- ) {
- #ifdef CK_KERBEROS
- if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
- extern int krb4_autoget;
- if (!ck_krb4_is_installed()) {
- printf(
- "?Required authentication method (Kerberos 4) is not installedn"
- );
- slrestor();
- return(success = 0);
- }
- #ifdef COMMENT
- /* This code results in false failures when using */
- /* kerberos to machines in realms other than the */
- /* default since we don't know the realm of the */
- /* other machine until perform the reverse DNS */
- /* lookup. */
- else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
- (!krb4_autoget ||
- krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
- printf(
- "?Kerberos 4: Ticket Getting Ticket not valid.n"
- );
- slrestor();
- return(success = 0);
- }
- #endif /* COMMENT */
- } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
- extern int krb5_autoget;
- if (!ck_krb5_is_installed()) {
- printf(
- "?Required authentication method (Kerberos 5) is not installedn"
- );
- slrestor();
- return(success = 0);
- }
- #ifdef COMMENT
- /* This code results in false failures when using */
- /* kerberos to machines in realms other than the */
- /* default since we don't know the realm of the */
- /* other machine until perform the reverse DNS */
- /* lookup. */
- else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
- (!krb5_autoget ||
- krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
- printf(
- "?Kerberos 5: Ticket Getting Ticket not valid.n"
- );
- slrestor();
- return(success = 0);
- }
- #endif /* COMMENT */
- }
- #endif /* CK_KERBEROS */
- #ifdef NT
- if (auth_type_user[0] == AUTHTYPE_NTLM) {
- if (!ck_ntlm_is_installed()) {
- printf(
- "?Required authentication method (NTLM) is not installedn"
- );
- slrestor();
- return(success = 0);
- } else if (line[0] != '*' && !ck_ntlm_is_valid()) {
- printf("?NTLM: Credentials are unavailable.n");
- slrestor();
- return(success = 0);
- }
- }
- #endif /* NT */
- #ifdef CK_SSL
- if (auth_type_user[0] == AUTHTYPE_SSL) {
- if (!ck_ssleay_is_installed()) {
- printf(
- "?Required authentication method (SSL) is not installedn"
- );
- slrestor();
- return(success = 0);
- }
- }
- #endif /* CK_SSL */
- #ifdef CK_SRP
- if (auth_type_user[0] == AUTHTYPE_SRP) {
- if (!ck_srp_is_installed()) {
- printf(
- "?Required authentication method (SRP) is not installedn"
- );
- slrestor();
- return(success = 0);
- }
- }
- #endif /* CK_SRP */
- }
- #endif /* CK_AUTHENTICATION */
- #ifdef CK_ENCRYPTION
- if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- e_type > -1) {
- if (!sl_cx_saved) {
- sl_cx_type = cx_type;
- sl_cx_saved = 1;
- }
- if (!sl_topt_e_s_saved) {
- sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_s_saved = 1;
- }
- if (!sl_topt_e_c_saved) {
- sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
- sl_topt_e_c_saved = 1;
- }
- cx_type = e_type;
- if (cx_type == CX_AUTO) {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
- } else if (cx_type == CX_NONE) {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
- } else {
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
- }
- }
- if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
- (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
- ((line[0] == '*' &&
- TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
- TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
- (line[0] != '*' &&
- TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
- TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
- ) {
- if (!ck_crypt_is_installed()) {
- slmsg = "Encryption failure";
- printf("?Required Encryption methods are not installedn");
- slrestor();
- return(success = 0);
- }
- }
- #endif /* CK_ENCRYPTION */
- #ifdef RLOGCODE
- #ifdef CK_KERBEROS
- #ifdef KRB4
- if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
- extern int krb4_autoget;
- char tgt[256];
- char * realm;
- /* this is fine except for one huge problem */
- /* we don't have the full hostname at this point */
- /* so we really need to perform a DNS lookup before */
- /* calling ttopen(). */
- realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
- sprintf(tgt,"krbtgt.%s@%s",realm,realm);
- if (!ck_krb4_is_installed()) {
- printf(
- "?Required authentication method (Kerberos 4) is not installedn"
- );
- slrestor();
- return(success = 0);
- } else {
- if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
- (!krb4_autoget ||
- krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
- printf(
- "?Kerberos 4: Ticket Getting Ticket not valid.n");
- slrestor();
- return(success = 0);
- }
- }
- }
- #endif /* KRB4 */
- #ifdef KRB5
- if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN) {
- extern int krb5_autoget;
- char tgt[256];
- char * realm;
- /* this is fine except for one huge problem */
- /* we don't have the full hostname at this point */
- /* so we really need to perform a DNS lookup before */
- /* calling ttopen(). */
- realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
- sprintf(tgt,"krbtgt/%s@%s",realm,realm);
- if (!ck_krb5_is_installed()) {
- printf(
- "?Required authentication method (Kerberos 5) is not installedn"
- );
- slrestor();
- return(success = 0);
- } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
- ck_krb5_is_tgt_valid()) &&
- (!krb5_autoget ||
- krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
- printf("?Kerberos 5: Ticket Getting Ticket not valid.n");
- slrestor();
- return(success = 0);
- }
- }
- #endif /* KRB5 */
- #endif /* CK_KERBEROS */
- #endif /* RLOGCODE */
- #ifdef NETCONN
- #ifndef NOSPL
- if (tmpstring) {
- if (tmpstring[0]) {
- ckstrncpy(pwbuf,tmpstring,PWBUFL+1);
- pwflg = 1;
- pwcrypt = 0;
- } else
- pwflg = 0;
- makestr(&tmpstring,NULL);
- }
- #ifdef RLOGCODE
- if (tmpusrid) if (tmpusrid[0]) {
- if (!sl_uid_saved) {
- ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
- sl_uid_saved = 1;
- }
- ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
- makestr(&tmpusrid,NULL);
- uidflag = 1;
- }
- #endif /* RLOGCODE */
- #endif /* NOSPL */
- #endif /* NETCONN */
- #ifdef TNCODE
- if (!sl_tn_saved) {
- sl_tn_wait = tn_wait_flg;
- sl_tn_saved = 1;
- }
- tn_wait_flg = wait;
- #endif /* TNCODE */
- /* Try to open */
- if ((y = ttopen(line, &_local, mdmtyp, 0 )) < 0) {
- slrestor();
- slmsg = "Network connection failure";
- #ifdef VMS
- if (hints && !cmdsrc() && ttnproto == NP_RLOGIN) {
- slmsg = "RLOGIN failure";
- printf("*************************n");
- printf("Hint: The RLOGIN port is privileged in VMS.n");
- printf("(Use SET HINTS OFF to suppress future hints.)n");
- printf("*************************n");
- }
- #else /* Not VMS... */
- if (errno) {
- int x;
- debug(F111,"set host line, errno","",errno);
- makestr(&tmpslmsg,ck_errstr());
- slmsg = tmpslmsg;
- x = strlen(line) + 2;
- if (LINBUFSIZ - x > 100) {
- tp = line + x;
- #ifdef OS2
- printf("Can't connect to %sn",line);
- #else /* OS2 */
- #ifdef COMMENT
- sprintf(tp,"Can't connect to %s",line);
- perror(tp);
- #endif /* COMMENT */
- #ifdef UNIX
- if (hints && !cmdsrc() && ttnproto == NP_RLOGIN) {
- slmsg = "RLOGIN failure";
- printf("*************************n");
- printf(
- "Hint: The RLOGIN port is privileged in UNIX.n");
- printf(
- "(Use SET HINTS OFF to suppress future hints.)n");
- printf("*************************n");
- }
- #endif /* UNIX */
- #endif /* OS2 */
- } else printf("Can't connect to %sn",line);
- } else
- #endif /* VMS */
- printf("Can't open connection to %sn",line);
- continue;
- } else {
- success = 1;
- switch (mynet) {
- case NET_TCPA:
- case NET_TCPB:
- cxtype = CXT_TCPIP;
- break;
- case NET_SLAT:
- cxtype = CXT_LAT;
- break;
- case NET_SX25:
- case NET_IX25:
- case NET_HX25:
- case NET_VX25:
- cxtype = CXT_X25;
- break;
- case NET_BIOS:
- cxtype = CXT_NETBIOS;
- break;
- case NET_FILE:
- case NET_PIPE:
- case NET_CMD:
- case NET_DLL:
- case NET_PTY:
- cxtype = CXT_PIPE;
- break;
- default:
- cxtype = CXT_PIPE;
- break;
- }
- break;
- }
- } /* for-loop */
- s = line;
- } /* network connection */
- #endif /* NETCONN */
- /*
- NOTE:
- The following will fail if Kermit is running as a daemon with no
- controlling tty. Needs research.
- */
- if (!success) {
- local = dfloc; /* Go back to normal */
- #ifndef MAC
- strcpy(ttname,dftty); /* Restore default tty name */
- #endif /* MAC */
- speed = ttgspd();
- network = 0; /* No network connection active */
- haveline = 0;
- if (mdmtyp < 0) { /* Switching from net to async? */
- if (mdmsav > -1) /* Restore modem type from last */
- mdmtyp = mdmsav; /* SET MODEM command, if any. */
- else
- mdmtyp = 0;
- mdmsav = -1;
- }
- return(0); /* Return failure */
- }
- if (_local > -1) local = _local; /* Opened ok, set local/remote. */
- slmsg = NULL;
- network = (mdmtyp < 0); /* Remember connection type. */
- strcpy(ttname,s); /* Copy name into real place. */
- debug(F110,"setlin ok",ttname,0);
- debug(F101,"setlin network","",network);
- if (!network)
- speed = ttgspd(); /* Get the current speed. */
- debug(F101,"setlin local","",local);
- #ifdef NETCONN
- if (network) {
- debug(F101,"setlin mynet","",mynet);
- #ifndef NOXFER
- /* Force prefixing of 255 on TCP/IP connections... */
- if (mynet == NET_TCPB) {
- debug(F101,"setlin reliable A","",reliable);
- #ifdef CK_SPEED
- ctlp[(unsigned)255] = 1;
- #endif /* CK_SPEED */
- if (reliable != SET_OFF || !setreliable)
- reliable = SET_ON; /* Transport is reliable end to end */
- debug(F101,"setlin reliable B","",reliable);
- } else if (mynet == NET_SX25 ||
- mynet == NET_VX25 ||
- mynet == NET_IX25 ||
- mynet == NET_HX25) {
- duplex = 1; /* Local echo for X.25 */
- if (reliable != SET_OFF || !setreliable)
- reliable = SET_ON; /* Transport is reliable end to end */
- }
- #endif /* NOXFER */
- }
- #endif /* NETCONN */
- #ifndef NOXFER
- debug(F101,"setlin reliable","",reliable);
- #endif /* NOXFER */
- #ifdef OS2
- if (mdmtyp <= 0) /* Network or Direct Connection */
- DialerSend(OPT_KERMIT_CONNECT, 0);
- #endif /* OS2 */
- setflow(); /* Set appropriate flow control */
- haveline = 1;
- #ifdef CKLOGDIAL
- #ifdef NETCONN
- if (network) /* Start connection log record */
- dolognet();
- else
- #endif /* NETCONN */
- dologline();
- #endif /* CKLOGDIAL */
- #ifndef NOSPL
- if (local) {
- if (nmac) { /* Any macros defined? */
- int k; /* Yes */
- k = mlook(mactab,"on_open",nmac); /* Look this up */
- if (k >= 0) { /* If found, */
- if (dodo(k,ttname,0) > -1) /* set it up, */
- parser(1); /* and execute it */
- }
- }
- }
- #endif /* NOSPL */
- if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
- extern int carrier;
- if (xx == XYLINE && carrier != CAR_OFF) { /* on serial connection... */
- /* Open() turns on DTR -- wait up to a second for CD to come up */
- int i, x;
- for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
- x = ttgmdm();
- if (x < 0 || x & BM_DCD)
- break;
- msleep(100);
- }
- }
- if (cx) { /* /CONNECT */
- success = doconect(0);
- #ifdef CKLOGDIAL
- if (ttchk() < 0)
- dologend();
- #endif /* CKLOGDIAL */
- return(success);
- #ifndef NOXFER
- } else if (sx) { /* /SERVER */
- sstate = 'x';
- #ifdef MAC
- what = W_RECV;
- scrcreate();
- #endif /* MAC */
- if (local) displa = 1;
- #ifdef AMIGA
- reqoff(); /* No DOS requestors while server */
- #endif /* AMIGA */
- #endif /* NOXFER */
- }
- }
- return(success = 1);
- }
- #endif /* NOLOCAL */
- #ifdef CKCHANNELIO
- /*
- C-Library based file-i/o package for scripts. This should be portable to
- all C-Kermit versions since it uses the same APIs we have always used for
- processing command files. The entire channel i/o package is contained
- herein, apart from some keyword table entries in the main keyword table
- and the help text in the HELP command module.
- On platforms like VMS and VOS, this package handles only UNIX-style
- stream files. If desired, it can be replaced for those platforms by
- <#>ifdef'ing out this code and adding the equivalent replacement routines
- to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
- */
- /* Define NOSTAT if the <#>include causes trouble. */
- #ifndef NOSTAT
- #ifdef VMS
- #ifdef VAXC /* As it does in VAX C */
- #define NOSTAT
- #endif /* VAXC */
- #endif /* VMS */
- #endif /* NOSTAT */
- #ifndef NOSTAT
- #include <sys/stat.h>
- #endif /* NOSTAT */
- #ifdef NLCHAR
- static int z_lt = 1; /* Length of line terminator */
- #else
- static int z_lt = 2;
- #endif /* NLCHAR */
- struct ckz_file { /* C-Kermit file struct */
- FILE * z_fp; /* Includes the C-Lib file struct */
- unsigned int z_flags; /* Plus C-Kermit mode flags, */
- long z_nline; /* current line number if known, */
- char z_name[CKMAXPATH+2]; /* and the file's name. */
- };
- static struct ckz_file * z_file = NULL; /* Array of C-Kermit file structs */
- static int z_inited = 0; /* Flag for array initialized */
- int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
- int z_openmax = CKMAXOPEN; /* Max number of open files overall */
- int z_nopen = 0; /* How many channels presently open */
- int z_error = 0; /* Most recent error */
- int z_filcount = -1; /* Most recent FILE COUNT result */
- #define RD_LINE 0 /* FILE READ options */
- #define RD_CHAR 1
- #define RD_SIZE 2
- #define WR_LINE RD_LINE /* FILE WRITE options */
- #define WR_CHAR RD_CHAR
- #define WR_SIZE RD_SIZE
- #define WR_STRI 3
- #define WR_LPAD 4
- #define WR_RPAD 5
- #ifdef UNIX
- extern int ckmaxfiles; /* Filled in by sysinit(). */
- #endif /* UNIX */
- /* See ckcker.h for error numbers */
- /* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
- /* NOTE: For VMS we might be able to fill in ckmaxfiles */
- /* from FILLM and CHANNELCNT -- find out about these... */
- static char * fopnargs[] = { /* Mode combinations for fopen() */
- #ifdef COMMENT
- /* All combinations of rwa */
- "", "r", "w", "rw", "a", "ra", "wa", "rwa", /* Text mode */
- "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
- #else
- /* Combinations and syntax permitted by C libraries... */
- "", "r", "w", "r+", "a", "", "a", "", /* Text mode */
- #ifdef OS2
- "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for K95 */
- #else
- #ifdef VMS
- "", "rb", "wb", "r+b", "ab", "", "ab", "" /* Binary modes for VMS */
- #else
- "", "r", "w", "r+", "a", "", "a", "" /* Binary modes for UNIX */
- #endif /* VMS */
- #endif /* OS2 */
- #endif /* COMMENT */
- };
- static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
- char * /* Error messages */
- ckferror(n) int n; {
- switch (n) {
- case FX_NER: return("No error");
- case FX_SYS: return(ck_errstr());
- case FX_EOF: return("End of file");
- case FX_NOP: return("File not open");
- case FX_CHN: return("Channel out of range");
- case FX_RNG: return("Parameter out of range");
- case FX_NMF: return("Too many files open");
- case FX_FOP: return("Operation conflicts with OPEN mode");
- case FX_NYI: return("OPEN mode not supported");
- case FX_BOM: return("Illegal combination of OPEN modes");
- case FX_ACC: return("Access denied");
- case FX_FNF: return("File not found");
- case FX_OFL: return("Buffer overflow");
- case FX_LNU: return("Current line number unknown");
- case FX_UNK: return("Operation fails - reason unknown");
- default: return("Error number out of range");
- }
- }
- /*
- Z _ O P E N -- Open a file for the requested type of access.
- Call with:
- name: Name of file to be opened.
- flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
- Returns:
- >= 0 on success: The assigned channel number
- < 0 on failure: A negative FX_xxx error code (ckcker.h).
- */
- int
- z_open(name, flags) char * name; int flags; {
- int i, n;
- FILE * t;
- char * mode;
- debug(F111,"z_open",name,flags);
- if (!name) name = ""; /* Check name argument */
- if (!name[0])
- return(z_error = FX_BFN);
- if (flags & FM_CMD) /* Opening pipes not implemented yet */
- return(z_error = FX_NYI); /* (and not portable either) */
- debug(F101,"z_open nfopnargs","",nfopnargs);
- if (flags < 0 || flags >= nfopnargs) /* Range check flags */
- return(z_error = FX_RNG);
- mode = fopnargs[flags]; /* Get fopen() arg */
- debug(F111,"z_open fopen args",mode,flags);
- if (!mode[0]) /* Check for illegal combinations */
- return(z_error = FX_BOM);
- if (!z_inited) { /* If file structs not inited */
- debug(F101,"z_open z_maxchan 1","",z_maxchan);
- #ifdef UNIX
- debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
- if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
- int x;
- x = ckmaxfiles - ZNFILS - 5;
- if (x > z_maxchan) /* sysconf() value greater than */
- z_maxchan = x; /* value from header files. */
- debug(F101,"z_open z_maxchan 2","",z_maxchan);
- }
- #endif /* UNIX */
- if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
- z_maxchan = Z_MINCHAN;
- debug(F101,"z_open z_maxchan 3","",z_maxchan);
- /* Note: This could be a pretty big chunk of memory */
- /* if z_maxchan is a big number. If this becomes a problem */
- /* we'll need to malloc and free each element at open/close time */
- if (!(z_file = (struct ckz_file *)
- malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
- return(z_error = FX_NMF);
- for (i = 0; i < z_maxchan; i++) {
- z_file[i].z_fp = NULL;
- z_file[i].z_flags = 0;
- z_file[i].z_nline = 0;
- *(z_file[i].z_name) = ' ';
- }
- z_inited = 1; /* Remember we did */
- }
- for (n = -1, i = 0; i < z_maxchan; i++) {
- if (!z_file[i].z_fp) {
- n = i;
- break;
- }
- }
- if (n < 0 || n >= z_maxchan) /* Any free channels? */
- return(z_error = FX_NMF); /* No, fail. */
- errno = 0;
- z_file[n].z_flags = 0; /* In case of failure... */
- t = fopen(name, mode); /* Try to open the file. */
- if (!t) { /* Failed... */
- debug(F111,"z_open error",name,errno);
- #ifdef EMFILE
- if (errno == EMFILE)
- return(z_error = FX_NMF);
- #endif /* EMFILE */
- return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error code */
- }
- #ifdef NT
- #ifdef O_SEQUENTIAL
- if (t) /* Caching hint for NT */
- _setmode(_fileno(t),O_SEQUENTIAL);
- #endif /* O_SEQUENTIAL */
- #endif /* NT */
- z_nopen++; /* Open, count it. */
- z_file[n].z_fp = t; /* Stash the file pointer */
- z_file[n].z_flags = flags; /* and the flags */
- z_error = 0;
- zfnqfp(name,CKMAXPATH,z_file[n].z_name); /* and the file's full name */
- return(n); /* Return the channel number */
- }
- int
- z_close(channel) int channel; { /* Close file on given channel */
- int x;
- FILE * t;
- if (!z_inited) /* Called before any files are open? */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan) /* Channel out of range? */
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp)) /* Channel wasn't open? */
- return(z_error = FX_NOP);
- errno = 0; /* Set errno 0 to get a good reading */
- x = fclose(t); /* Try to close */
- if (x == EOF) /* On failure */
- return(z_error = FX_SYS); /* indicate system error. */
- z_nopen--; /* Closed OK, decrement open count */
- z_file[channel].z_fp = NULL; /* Set file pointer to NULL */
- z_file[channel].z_nline = 0; /* Current line number is 0 */
- z_file[channel].z_flags = 0; /* Set flags to 0 */
- *(z_file[channel].z_name) = ' '; /* Clear name */
- return(z_error = 0);
- }
- /*
- Z _ O U T -- Output string to channel.
- Call with:
- channel: Channel number to write to.
- s: String to write.
- length > -1: How many characters of s to write.
- length < 0: Write entire NUL-terminated string.
- flags == 0: Supply line termination.
- flags > 0: Don't supply line termination.
- flags < 0: Write 'length' NUL characters.
- Special case:
- If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
- Returns:
- Number of characters written to channel on success, or
- negative FX_xxx error code on failure.
- */
- int
- z_out(channel,s,length,flags) int channel, flags, length; char * s; {
- FILE * t;
- int x, n;
- char c = ' ';
- if (!s) s = ""; /* Guard against null pointer */
- #ifdef DEBUG
- if (deblog) {
- debug(F111,"z_out",s,channel);
- debug(F101,"z_out length","",length);
- debug(F101,"z_out flags","",flags);
- }
- #endif /* DEBUG */
- if (!z_inited) /* File i/o inited? */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan) /* Channel in range? */
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp)) /* File open? */
- return(z_error = FX_NOP);
- if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
- return(z_error = FX_FOP);
- n = length; /* Length of string to write */
- if (n < 0) { /* Negative means get it ourselves */
- if (flags < 0) /* Except when told to write NULs in */
- return(z_error = FX_RNG); /* which case args are inconsistent */
- n = strlen(s); /* Get length of string arg */
- }
- errno = 0; /* Reset errno */
- debug(F101,"z_out n","",n);
- if (flags < 0) { /* Writing NULs... */
- int i;
- for (i = 0; i < n; i++) {
- x = fwrite(&c,1,1,t);
- if (x < 1)
- return(z_error = (errno ? FX_SYS : FX_UNK));
- }
- z_file[channel].z_nline = -1; /* Current line no longer known */
- z_error = 0;
- return(i);
- } else { /* Writing string arg */
- if (n == 1 && !s[0]) /* Writing one char but it's NUL */
- x = fwrite(&c,1,1,t);
- else /* Writing non-NUL char or string */
- x = fwrite(s,1,n,t);
- debug(F101,"z_out fwrite",ckitoa(x),errno);
- if (x < n) /* Failure to write requested amount */
- return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
- if (flags == 0) { /* If supplying line termination */
- if (fwrite("n",1,1,t)) /* do that */
- x += z_lt; /* count the terminator */
- if (z_file[channel].z_nline > -1) /* count this line */
- z_file[channel].z_nline++;
- } else {
- z_file[channel].z_nline = -1; /* Current line no longer known */
- }
- }
- z_error = 0;
- return(x);
- }
- #define Z_INBUFLEN 64
- /*
- Z _ I N -- Multichannel i/o file input function.
- Call with:
- channel number to read from.
- s = address of destination buffer.
- buflen = destination buffer length.
- length = Number of bytes to read, must be < buflen.
- flags: 0 = read a line; nonzero = read the given number of bytes.
- Returns:
- Number of bytes read into buffer or a negative error code.
- A terminating NUL is deposited after the last byte that was read.
- */
- int
- z_in(channel,s,buflen,length,flags)
- int channel, buflen, length, flags; char * s;
- /* z_in */ {
- int i, j, x;
- FILE * t;
- char * p;
- if (!z_inited) /* Check everything... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- if (!((z_file[channel].z_flags) & FM_REA))
- return(z_error = FX_FOP);
- if (!s) /* Check destination */
- return(z_error = FX_RNG);
- s[0] = NUL;
- if (length == 0) /* Read 0 bytes - easy. */
- return(z_error = 0);
- debug(F101,"z_in channel","",channel);
- debug(F101,"z_in buflen","",buflen);
- debug(F101,"z_in length","",length);
- debug(F101,"z_in flags","",flags);
- if (length < 0 || buflen < 0) /* Check length args */
- return(z_error = FX_RNG);
- if (buflen <= length)
- return(z_error = FX_RNG);
- errno = 0; /* Reset errno */
- if (flags) { /* Read block or byte */
- i = fread(s,1,length,t);
- #ifdef DEBUG
- if (deblog) {
- debug(F111,"z_in block",s,i);
- debug(F101,"z_in block errno","",errno);
- debug(F101,"z_in block ferror","",ferror(t));
- debug(F101,"z_in block feof","",feof(t));
- }
- #endif /* DEBUG */
- z_file[channel].z_nline = -1; /* Current line no longer known */
- } else { /* Read line */
- #ifndef COMMENT
- /* This method is used because it's simpler than the others */
- /* and also marginally faster. */
- for (i = 0; i < length; i++) {
- if ((x = getc(t)) == EOF)
- break;
- s[i] = x;
- if (s[i] == 'n') {
- s[i] = ' ';
- break;
- }
- }
- debug(F111,"z_in line byte loop",ckitoa(errno),i);
- if (z_file[channel].z_nline > -1)
- z_file[channel].z_nline++;
- #else
- #ifdef COMMENT2
- /* Straightforward but strlen() slows it down. */
- s[0] = ' ';
- i = 0;
- if (fgets(s,length,t)) {
- i = strlen(s);
- if (i > 0 && s[i-1] == 'n') i--;
- }
- debug(F111,"z_in line fgets",ckitoa(errno),i);
- if (z_file[channel].z_nline > -1)
- z_file[channel].z_nline++;
- #else
- /* This is a do-it-yourself fgets() with its own readahead and */
- /* putback. It's a bit faster than real fgets() but not enough */
- /* to justify the added complexity or the risk of the ftell() and */
- /* fseek() calls failing. */
- int k, flag = 0;
- long pos;
- for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
- k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
- if ((x = fread(s+i,1,k,t)) < 1)
- break;
- s[i+x] = ' ';
- for (j = 0; j < x; j++) {
- if (s[i+j] == 'n') {
- s[i+j] = ' ';
- flag ++;
- pos = ftell(t);
- if (pos > -1) {
- pos -= (x - j - 1);
- x = fseek(t, pos, 0);
- i += j;
- break;
- } else
- return(z_error = FX_SYS);
- }
- }
- }
- if (z_file[channel].z_nline > -1)
- z_file[channel].z_nline++;
- debug(F111,"z_in line chunk loop",ckitoa(errno),i);
- #endif /* COMMENT2 */
- #endif /* COMMENT */
- }
- debug(F111,"z_in i",ckitoa(errno),i);
- if (i < 0) i = 0; /* NUL-terminate result */
- s[i] = ' ';
- if (i > 0) {
- z_error = 0;
- return(i);
- }
- if (i == 0 && feof(t)) /* EOF on reading? */
- return(z_error = FX_EOF); /* Return EOF code */
- return(errno ? (z_error = -1) : i); /* Return length or system error */
- }
- int
- z_flush(channel) int channel; { /* Flush output channel */
- FILE * t;
- int x;
- if (!z_inited) /* Regular checks */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* Write access? */
- return(z_error = FX_FOP);
- errno = 0; /* Reset errno */
- x = fflush(t); /* Try to flush */
- return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
- }
- int
- #ifdef CK_ANSIC
- z_seek(int channel, long pos) /* Move file pointer to byte */
- #else
- z_seek(channel,pos) int channel; long pos; /* (seek to given position) */
- #endif /* CK_ANSIC */
- {
- int i, x = 0, rc;
- FILE * t;
- if (!z_inited) /* Check... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- if (pos < 0L) {
- x = 2;
- pos = (pos == -2) ? -1L : 0L;
- }
- errno = 0;
- rc = fseek(t,pos,x); /* Try to seek */
- debug(F111,"z_seek",ckitoa(errno),rc);
- if (rc < 0) /* OK? */
- return(z_error = FX_SYS); /* No. */
- z_file[channel].z_nline = ((pos || x) ? -1 : 0);
- return(z_error = 0);
- }
- int
- #ifdef CK_ANSIC
- z_line(int channel, long pos) /* Move file pointer to line */
- #else
- z_line(channel,pos) int channel; long pos; /* (seek to given position) */
- #endif /* CK_ANSIC */
- {
- int i, len, x = 0;
- long current = 0L, prev = -1L, old = -1L;
- FILE * t;
- char tmpbuf[256];
- if (!z_inited) /* Check... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- debug(F101,"z_line pos","",pos);
- if (pos < 0L) { /* EOF wanted */
- long n;
- n = z_file[channel].z_nline;
- if (n < 0) {
- rewind(t);
- n = 0;
- }
- while (1) { /* This could take a while... */
- if ((x = getc(t)) == EOF)
- break;
- if (x == 'n') {
- n++;
- if (pos == -2) {
- old = prev;
- prev = ftell(t);
- }
- }
- }
- if (pos == -2) {
- if ((x = z_seek(channel,old)) < 0)
- return(z_error = x);
- else
- n--;
- }
- z_file[channel].z_nline = n;
- return(z_error = 0);
- }
- if (pos == 0L) { /* Rewind wanted */
- z_file[channel].z_nline = 0L;
- rewind(t);
- debug(F100,"z_line rewind","",0);
- return(0L);
- }
- tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
- current = z_file[channel].z_nline; /* Current line */
- /*
- If necessary the following could be optimized, e.g. for positioning
- to a previous line in a large file without starting over.
- */
- if (current < 0 || pos < current) { /* Not known or behind us... */
- debug(F101,"z_line rewinding","",pos);
- if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
- return(z_error = x);
- if (pos == 0) /* If 0th line wanted we're done */
- return(z_error = 0);
- current = 0;
- }
- while (current < pos) { /* Search for specified line */
- if (fgets(tmpbuf,255,t)) {
- len = strlen(tmpbuf);
- if (len > 0 && tmpbuf[len-1] == 'n') {
- current++;
- debug(F111,"z_line read",ckitoa(len),current);
- } else if (len == 0) {
- return(z_error = FX_UNK);
- }
- } else {
- z_file[channel].z_nline = -1L;
- debug(F101,"z_line premature EOF","",current);
- return(z_error = FX_EOF);
- }
- }
- z_file[channel].z_nline = current;
- debug(F101,"z_line result","",current);
- z_error = 0;
- return(current);
- }
- char *
- z_getname(channel) int channel; { /* Return name of file on channel */
- FILE * t;
- if (!z_inited) {
- z_error = FX_NOP;
- return(NULL);
- }
- if (channel >= z_maxchan) {
- z_error = FX_CHN;
- return(NULL);
- }
- if (!(t = z_file[channel].z_fp)) {
- z_error = FX_NOP;
- return(NULL);
- }
- return((char *)(z_file[channel].z_name));
- }
- int
- z_getmode(channel) int channel; { /* Return OPEN modes of channel */
- FILE * t; /* 0 if file not open */
- #ifndef NOSTAT
- struct stat statbuf;
- #endif /* NOSTAT */
- int x;
- if (!z_inited)
- return(0);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(0);
- x = z_file[channel].z_flags;
- if (feof(t)) { /* This might not work for */
- x |= FM_EOF; /* output files */
- #ifndef NOSTAT
- /* But this does if we can use it. */
- } else if (stat(z_file[channel].z_name,&statbuf) > -1) {
- if (ftell(t) == statbuf.st_size)
- x |= FM_EOF;
- #endif /* NOSTAT */
- }
- return(x);
- }
- long
- z_getpos(channel) int channel; { /* Get file pointer position */
- FILE * t; /* on this channel */
- long x;
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- x = ftell(t);
- return((x < 0L) ? (z_error = FX_SYS) : x);
- }
- long
- z_getline(channel) int channel; { /* Get current line number */
- FILE * t; /* in file on this channel */
- long rc;
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- debug(F101,"z_getline","",z_file[channel].z_nline);
- rc = z_file[channel].z_nline;
- return((rc < 0) ? (z_error = FX_LNU) : rc);
- }
- int
- z_getfnum(channel) int channel; { /* Get file number / handle */
- FILE * t; /* for file on this channel */
- if (!z_inited)
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- z_error = 0;
- return(fileno(t));
- }
- /*
- Line-oriented counts and seeks are as dumb as they can be at the moment.
- Later we can speed them up by building little indexes.
- */
- long
- z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
- FILE * t;
- int i, x;
- long pos, count = 0L;
- if (!z_inited) /* Check stuff... */
- return(z_error = FX_NOP);
- if (channel >= z_maxchan)
- return(z_error = FX_CHN);
- if (!(t = z_file[channel].z_fp))
- return(z_error = FX_NOP);
- pos = ftell(t); /* Save current file pointer */
- errno = 0;
- z_error = 0;
- if (what == RD_CHAR) { /* Size in bytes requested */
- if (!fseek(t,0L,2)) { /* Seek to end */
- count = ftell(t); /* Get file pointer */
- fseek(t,pos,0); /* Restore file file pointer */
- return(count);
- } else /* Fallback in case seek fails */
- return(zgetfs(z_file[channel].z_name));
- }
- rewind(t); /* Line count requested - rewind. */
- while (1) { /* Count lines. */
- if ((x = getc(t)) == EOF) /* Stupid byte loop */
- break; /* but it works as well as anything */
- if (x == 'n') /* else... */
- count++;
- }
- x = fseek(t,pos,0); /* Restore file pointer */
- return(count);
- }
- /* User interface for generalized channel-oriented file i/o */
- struct keytab fctab[] = { /* FILE subcommands */
- "close", FIL_CLS, 0,
- "count", FIL_COU, 0,
- "flush", FIL_FLU, 0,
- "list", FIL_LIS, 0,
- "open", FIL_OPN, 0,
- "read", FIL_REA, 0,
- "rewind", FIL_REW, 0,
- "seek", FIL_SEE, 0,
- "status", FIL_STA, 0,
- "write", FIL_WRI, 0
- };
- int nfctab = (sizeof (fctab) / sizeof (struct keytab));
- static struct keytab fcswtab[] = { /* OPEN modes */
- "/append", FM_APP, 0,
- "/binary", FM_BIN, 0,
- #ifdef COMMENT
- "/command", FM_CMD, 0, /* Not implemented */
- #endif /* COMMENT */
- "/read", FM_REA, 0,
- "/write", FM_WRI, 0
- };
- static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
- static struct keytab fclkwtab[] = { /* CLOSE options */
- "all", 1, 0
- };
- static struct keytab fsekwtab[] = { /* SEEK symbols */
- "eof", 1, 0,
- "last", 2, 0
- };
- static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
- #define SEE_LINE RD_LINE /* SEEK options */
- #define SEE_CHAR RD_CHAR
- #define SEE_REL 3
- #define SEE_ABS 4
- static struct keytab fskswtab[] = {
- "/absolute", SEE_ABS, 0,
- "/byte", SEE_CHAR, 0,
- "/character", SEE_CHAR, CM_INV,
- "/line", SEE_LINE, 0,
- "/relative", SEE_REL, 0
- };
- static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
- #define COU_LINE RD_LINE /* COUNT options */
- #define COU_CHAR RD_CHAR
- #define COU_LIS 3
- #define COU_NOL 4
- static struct keytab fcoswtab[] = {
- "/bytes", COU_CHAR, 0,
- "/characters",COU_CHAR, CM_INV,
- "/lines", COU_LINE, 0,
- "/list", COU_LIS, 0,
- "/nolist", COU_NOL, 0,
- "/quiet", COU_NOL, CM_INV
- };
- static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
- static struct keytab frdtab[] = { /* READ types */
- "/block", RD_SIZE, CM_INV|CM_ARG,
- "/byte", RD_CHAR, CM_INV,
- "/character", RD_CHAR, 0,
- "/line", RD_LINE, 0,
- "/size", RD_SIZE, CM_ARG
- };
- static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
- static struct keytab fwrtab[] = { /* WRITE types */
- "/block", WR_SIZE, CM_INV|CM_ARG,
- "/byte", WR_CHAR, CM_INV,
- "/character", WR_CHAR, 0,
- "/line", WR_LINE, 0,
- "/lpad", WR_LPAD, CM_ARG,
- "/rpad", WR_RPAD, CM_ARG,
- "/size", WR_SIZE, CM_ARG,
- "/string", WR_STRI, 0
- };
- static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
- static char blanks[] = "