ckuus7.c
上传用户:dufan58
上传日期:2007-01-05
资源大小:3407k
文件大小:362k
源码类别:

通讯/手机编程

开发平台:

Windows_Unix

  1.                         /* negotiations change if necessary. */
  2.     }
  3. } else { /* They just said "set host" */
  4.     s = dftty; /* So go back to normal */
  5.     _local = dfloc; /* default tty, location, */
  6.     if (zz) {
  7. setflow(); /* Maybe change flow control */
  8. haveline = 1; /* (* is this right? *) */
  9. /* why aren't we calling clsconnx()? */
  10. #ifdef CKLOGDIAL
  11. dologend();
  12. #endif /* CKLOGDIAL */
  13. return(success = 1);
  14.     }
  15. }
  16. #endif /* NETCONN */
  17.     }
  18. /* Serial tty device, possibly modem, connection... */
  19.     if (xx == XYLINE /* SET LINE or SET PORT */
  20. #ifdef CK_TAPI
  21. || xx == XYTAPI_LIN /* SET TAPI LINE */
  22. #endif /* CK_TAPI */
  23. ) {
  24. #ifdef OS2
  25. /*
  26.   User can type:
  27.     COM1..COM8 = Regular COM port
  28.     1..8       = Synonym for COM1..COM8, is translated to COM1..COM8
  29.     _n         = (n is a number) = open file handle
  30.     string     = any text string = name of some other kind of device,
  31.                  taken literally, as given.
  32. */
  33. s = "Communication device name";
  34. #ifdef CK_TAPI
  35. if (TAPIAvail)
  36.           cktapiBuildLineTable(&tapilinetab, &_tapilinetab, &ntapiline);
  37. if (!(tapilinetab && _tapilinetab && ntapiline > 0) &&
  38.     xx == XYTAPI_LIN ) {
  39.     slmsg = "TAPI device not configured";
  40.     printf("nNo TAPI Line Devices are configured for this systemn");
  41.     return(-9);
  42. }
  43. if (xx == XYTAPI_LIN) { /* Default (first) TAPI line */
  44.     s = "tapi"; /* (whatever it is) */
  45. } else { /* Query the user */
  46. #endif /* CK_TAPI */
  47. /* Now parse optional switches and then device name */
  48.     confirmed = 0;
  49.     cmfdbi(&sw,_CMKEY,"Device name, or switch",
  50.    "","",npsltab,4,xxstring,psltab,&fl);
  51.     cmfdbi(&fl,_CMFLD,"",dftty,"",0,0,xxstring,NULL,NULL);
  52.     while (1) {
  53. x = cmfdb(&sw);
  54. debug(F101,"setlin cmfdb","",x);
  55. if (x < 0)
  56.   if (x != -3)
  57.     return(x);
  58. if (x == -3) {
  59.     if ((x = cmcfm()) < 0) {
  60. return(x);
  61.     } else {
  62. confirmed = 1;
  63. break;
  64.     }
  65. }
  66. if (cmresult.fcode == _CMFLD) {
  67.     s = cmresult.sresult;
  68.     break;
  69. } else if (cmresult.fcode == _CMKEY) {
  70.     switch (cmresult.nresult) {
  71.       case SL_CNX: /* /CONNECT */
  72. cx = 1;
  73. sx = 0;
  74. break;
  75.       case SL_SRV: /* /SERVER */
  76. cx = 0;
  77. sx = 1;
  78. break;
  79.     }
  80. }
  81.     }
  82. #ifdef CK_TAPI
  83. }
  84. #endif /* CK_TAPI */
  85. debug(F110,"OS2 SET PORT s",s,0);
  86. y = lookup(os2devtab,s,nos2dev,&x); /* Look up in keyword table */
  87. debug(F101,"OS2 SET PORT x","",x);
  88. debug(F101,"OS2 SET PORT y","",y);
  89. if ((y > -1) && (x >= 0 && x < 8)) { /* User typed a digit 1..8 */
  90.     s = os2devtab[x+8].kwd; /* Substitite its real name */
  91. #ifdef NT
  92.     xxtapi = 0;
  93. #else /* NT */
  94.     xxslip = xxppp = 0;
  95. #endif /* NT */
  96.     debug(F110,"OS2 SET PORT subst s",s,"");
  97. #ifndef NT
  98. } else if ((y >-1) && (x >= 16 && x < 24)) { /* SLIP access */
  99.     s = os2devtab[x-8].kwd; /* Substitite its real name */
  100.     debug(F110,"OS2 SET PORT SLIP subst s",s,"");
  101.     xxslip = 1;
  102.     xxppp  = 0;
  103. } else if ((y >-1) && (x >= 24 && x < 32)) { /* PPP access */
  104.     s = os2devtab[x-16].kwd; /* Substitite its real name */
  105.     debug(F110,"OS2 SET PORT PPP subst s",s,"");
  106.     xxppp = 1;
  107.     xxslip = 0;
  108.     if ((y = cmkey(os2ppptab,
  109.    nos2ppp,
  110.    "PPP driver interface",
  111.    "ppp0",
  112.    xxstring)
  113.  ) < 0)
  114. return(y);
  115.     debug(F101,"OS2 SET PORT PPP INTERFACE y","",y);
  116.     xxppp = (y % 10) + 1;
  117. #endif /* NT */
  118. } else if (*s == '_') { /* User used "_" prefix */
  119.     s++; /* Remove it */
  120.     /* Rest must be numeric */
  121.     debug(F110,"OS2 SET PORT HANDLE _subst s",s,0);
  122.     if (!rdigits(s)) {
  123. slmsg = "Invalid file handle";
  124. printf("?Invalid format for file handlen");
  125. return(-9);
  126.     }
  127. #ifdef NT
  128.     xxtapi = 0;
  129. #else /* NT */
  130.     xxslip = xxppp = 0;
  131. #endif /* NT */
  132. } else { /* A normal COMx port or a string */
  133.     s = brstrip(s); /* Strip braces if any */
  134. #ifdef NT
  135. #ifdef CK_TAPI
  136.     /* Windows TAPI support - Look up in keyword table */
  137.     if (tapilinetab && _tapilinetab && ntapiline > 0) {
  138. if (!ckstrcmp(s,"tapi",4,0)) {
  139.     /* Find out what the lowest numbered TAPI device is */
  140.     /* and use it as the default.                       */
  141.     int j = 9999, k = -1;
  142.     for (i = 0; i < ntapiline; i++) {
  143.      if (tapilinetab[i].kwval < j) {
  144.     j = tapilinetab[i].kwval;
  145.     k = i;
  146. }
  147.     }
  148.     if (k >= 0)
  149.       s = _tapilinetab[k].kwd;
  150.     else
  151.       s = "";
  152.     if ((y = cmkey(_tapilinetab,ntapiline,
  153.    "TAPI device name",s,xxstring)) < 0)
  154.       return(y);
  155.     xxtapi = 1;
  156.     /* Get the non Underscored string */
  157.     for (i = 0; i < ntapiline; i++ ) {
  158.      if (tapilinetab[i].kwval == y) {
  159.     s = tapilinetab[i].kwd;
  160.     break;
  161. }
  162.     }
  163. } else
  164.   xxtapi = 0;
  165.     }
  166. #endif /* CK_TAPI */
  167. #else /* NT */
  168.     /* not OS/2 SLIP or PPP */
  169.     xxslip = xxppp = 0;
  170. #endif /* NT */
  171.         }
  172. strcpy(tmpbuf,s); /* Copy to a safe place */
  173. s = tmpbuf;
  174. if ((x = cmcfm()) < 0)
  175.   return(x);
  176. #else /* !OS2 */
  177. cmfdbi(&sw,_CMKEY,"Device name, or switch",
  178.        "","",npsltab,4,xxstring,psltab,&tx);
  179. cmfdbi(&tx,_CMTXT,"",dftty,"",0,0,xxstring,NULL,NULL);
  180. while (!confirmed) {
  181.     x = cmfdb(&sw);
  182.     debug(F101,"setlin cmfdb","",x);
  183.     if (x < 0)
  184.       if (x != -3)
  185. return(x);
  186.     if (x == -3) {
  187. if ((x = cmcfm()) < 0) {
  188.     return(x);
  189. } else {
  190.     confirmed = 1;
  191.     break;
  192. }
  193.     }
  194.     switch (cmresult.fcode) {
  195.       case _CMTXT:
  196. strcpy(tmpbuf,cmresult.sresult);
  197. s = tmpbuf;
  198. debug(F110,"setlin CMTXT",tmpbuf,0);
  199. confirmed = 1;
  200. break;
  201.       case _CMKEY: /* Switch */
  202. debug(F101,"setlin CMKEY",tmpbuf,cmresult.nresult);
  203. switch (cmresult.nresult) {
  204.   case SL_CNX: /* /CONNECT */
  205.     cx = 1;
  206.     sx = 0;
  207.     break;
  208.   case SL_SRV: /* /SERVER */
  209.     cx = 0;
  210.     sx = 1;
  211.     break;
  212. #ifdef VMS
  213.   case SL_SHR: /* /SHARE */
  214.     shr = 1;
  215.     break;
  216.   case SL_NSH: /* /NOSHARE */
  217.     shr = 0;
  218.     break;
  219. #endif /* VMS */
  220. }
  221. continue;
  222.       default:
  223. debug(F101,"setlin bad cmfdb result","",cmresult.fcode);
  224. slmsg = "Internal error";
  225. printf("?Internal parsing errorn");
  226. return(-9);
  227.     }
  228. }
  229. #endif /* OS2 */
  230. if (!confirmed)
  231.   if ((x = cmcfm()) < 0)
  232.     return(x);
  233. debug(F101,"setlin confirmed mdmtyp","",mdmtyp);
  234. if (clsconnx(1) < 0) /* Close the connection */
  235.   return(success = 0);
  236. if (*s) { /* They gave a device name */
  237.     _local = -1; /* Let ttopen decide about it */
  238. } else { /* They just said "set line" */
  239.     s = dftty; /* so go back to normal tty */
  240.     _local = dfloc; /* and mode. */
  241. }
  242. #ifdef VMS
  243. {
  244.     extern int ok_to_share;
  245.     ok_to_share = shr;
  246. }
  247. #endif /* VMS */
  248. #ifdef OS2 /* Must wait until after ttclos() */
  249. #ifdef NT /* to change these settings       */
  250. #ifdef CK_TAPI
  251. tttapi = xxtapi;
  252. #endif /* CK_TAPI */
  253. #else
  254. ttslip = xxslip;
  255. ttppp  = xxppp;
  256. #endif /* NT */
  257. debug(F110,"OS2 SET PORT final s",s,"");
  258. #endif /* OS2 */
  259.     }
  260.     success = 0;
  261.     if (mdmtyp > -1) { /* Serial connections... */
  262. /* Open the new line */
  263. if ((y = ttopen(s,&_local,mdmtyp,cdtimo)) > -1) {
  264.     cxtype = (mdmtyp > 0) ? CXT_MODEM : CXT_DIRECT;
  265. #ifdef COMMENT
  266.     flow = cxflow[cxtype]; /* Set connection type and flow */
  267. #else
  268.     setflow(); /* Only if autoflow()! */
  269. #endif /* COMMENT */
  270.     success = 1;
  271. #ifdef CK_TAPI
  272.     /* if the line is a tapi device, then we need to auto-execute */
  273.     /* SET MODEM TYPE TAPI - which we do the equivalent of here.  */
  274.     if (xxtapi) {
  275. extern int usermdm;
  276. usermdm = 0;
  277. initmdm(38);    /* From ckudia.c n_TAPI == 38 */
  278.     }
  279. #endif /* CK_TAPI */
  280. } else {
  281. #ifdef OS2ONLY
  282.     if (!strcmp(s,dftty))   /* Do not generate an error with dftty */
  283.       ;
  284.     else if (y == -6 && ttslip) {
  285. slmsg = "Can't access SLIP driver";
  286. if (!quiet || cmdsrc() == 0)
  287.   printf("?Unable to access SLIP driver.n");
  288.     } else if (y == -6 && ttppp) {
  289. if (!quiet || cmdsrc() == 0)
  290.   slmsg = "Can't access PPP driver";
  291. printf("?Unable to access PPP driver (wrong interface?)n");
  292.     } else
  293. #endif /* OS2ONLY */
  294.       if (y == -2) {
  295.   slmsg = "Timed out - no carrier";
  296.   if (!quiet || cmdsrc() == 0) {
  297.       printf("?Timed out, no carrier.n");
  298.       printf(
  299. "Try SET CARRIER OFF and SET LINE again, or elsen");
  300.       printf("SET MODEM, SET LINE, and then DIAL.n");
  301.   }
  302.       } else if (y == -3) {
  303.   slmsg = "Access to lock denied";
  304.   if (!quiet || cmdsrc() == 0) {
  305. #ifdef UNIX
  306.       printf(
  307. "Sorry, write access to UUCP lockfile directory denied.n");
  308. #ifndef NOHINTS
  309.       if (hints) {
  310.   printf("n*************************n");
  311.   printf(
  312. "HINT (Use SET HINTS OFF to suppress future hints):n");
  313.   printf(
  314. "Please read the installation instructions file, %sckuins.txt,n",
  315.  k_info_dir ? k_info_dir : ""
  316.  );
  317.   printf(
  318. "or the UNIX appendix of the manual, "Using C-Kermit".n"
  319.  );
  320.   printf("*************************nn");
  321.       }
  322. #endif /* NOHINTS */
  323. #else
  324.       printf("Sorry, access to lock denied: %sn",s);
  325. #endif /* UNIX */
  326.   }
  327.       } else if (y == -4) {
  328.   slmsg = "Access to device denied";
  329.   if (!quiet || cmdsrc() == 0) {
  330.       printf("Sorry, access to device denied: %sn",s);
  331. #ifdef UNIX
  332. #ifndef NOHINTS
  333.       if (hints) {
  334.   printf("n*************************n");
  335.   printf(
  336. "HINT (Use SET HINTS OFF to suppress future hints):n");
  337.   printf(
  338. "Please read the installation instructions file, %sckuins.txt,n",
  339.  k_info_dir ? k_info_dir : ""
  340.  );
  341.   printf(
  342. "or the UNIX appendix of the manual, "Using C-Kermit".n"
  343.  );
  344.   printf("*************************nn");
  345.       }
  346. #endif /* NOHINTS */
  347. #endif /* UNIX */
  348.   }
  349.       } else if (y == -5) {
  350.   slmsg = "Device is in use or unavailable";
  351.   if (!quiet || cmdsrc() == 0)
  352. #ifdef VMS
  353.     printf(
  354.    "Sorry, device is in use or otherwise unavailable: %sn",s);
  355. #else
  356.     printf("Sorry, device is in use: %sn",s);
  357. #endif /* VMS */
  358.       } else { /* Other error. */
  359.   slmsg = "Device open failed";
  360.   if (
  361. #ifdef VMS
  362.       1
  363. #else
  364.       errno
  365. #endif /* VMS */
  366.       ) {
  367.       int x; /* Find a safe, long buffer */
  368.       makestr(&tmpslmsg,ck_errstr());
  369.       slmsg = tmpslmsg;
  370. #ifndef VMS
  371.       debug(F111,"setlin serial errno",slmsg,errno);
  372. #endif /* VMS */
  373.       if (!quiet || cmdsrc() == 0) {
  374.   x = strlen(line) + 2; /* for the error message. */
  375.   if (LINBUFSIZ - x > 100) { /* Room for 100 chars */
  376.       tp = line + x;
  377.       sprintf(tp,"Sorry, can't open connection: %s",s);
  378.       perror(tp);
  379.   } else
  380.     printf("Sorry, can't open connection: %sn",s);
  381.       }
  382.   } else if (!quiet || cmdsrc() == 0)
  383.     printf("Sorry, can't open connection: %sn",s);
  384.       }
  385. }
  386.     }
  387. #ifdef NETCONN
  388.     else { /* mdmtyp < 0: Network connection */
  389. char *p;
  390. int i, n;
  391. #ifndef NODIAL
  392. debug(F101,"setlin mynet 3","",mynet);
  393. debug(F101,"setlin nhcount","",nhcount);
  394. if ((nhcount > 1) && !quiet && !backgrd) {
  395.     int k;
  396.     printf("%d entr%s found for "%s"%sn",
  397.    nhcount,
  398.    (nhcount == 1) ? "y" : "ies",
  399.    s,
  400.    (nhcount > 0) ? ":" : "."
  401.    );
  402.     for (i = 0; i < nhcount; i++) {
  403.     printf("%3d. %-12s => %-9s %s",
  404.    i+1,n_name,nh_p2[i],nh_p[i]);
  405. for (k = 0; k < 4; k++) { /* Also list net-specific items */
  406.     if (nh_px[k][i])   /* free format... */
  407.       printf(" %s",nh_px[k][i]);
  408.     else
  409.       break;
  410. }
  411. printf("n");
  412.     }
  413. }
  414. if (nhcount == 0)
  415.   n = 1;
  416. else
  417.   n = nhcount;
  418. #else
  419. n = 1;
  420. nhcount = 0;
  421. #endif /* NODIAL */
  422. for (i = 0; i < n; i++) { /* Loop for each entry found */
  423. #ifndef NODIAL
  424.     debug(F101,"setlin loop i","",i);
  425.     if (nhcount > 0) { /* If we found at least one entry... */
  426. strcpy(line,nh_p[i]); /* Copy the current entry to line[] */
  427. if (lookup(netcmd,nh_p2[i],nnets,&x) > -1) { /* Net type */
  428.     mynet = netcmd[x].kwval;
  429.     mdmtyp  = 0 - mynet;
  430.     debug(F101,"setlin mynet 4","",mynet);
  431. } else {
  432.     slmsg = "Network type not supported";
  433.     printf("Error - network type "%s" not supportedn",
  434.    nh_p2[i]
  435.    );
  436.     continue;
  437. }
  438. switch (mynet) { /* Net-specific things */
  439.   case NET_TCPB: { /* TCP/IP */
  440. #ifdef TCPSOCKET
  441.       char *q;
  442.       int flag = 0;
  443.       /* Extract ":service", if any, from host string */
  444.       debug(F110,"setlin service 1",line,0);
  445.       for (q = line; (*q != '') && (*q != ':'); q++)
  446. ;
  447.       if (*q == ':') { *q++ = NUL; flag = 1; }
  448.       debug(F111,"setlin service 2",line,flag);
  449.       /* Get service, if any, from directory entry */
  450.       if (!*srvbuf) {
  451.   if (nh_px[0][i]) {
  452.       ckstrncpy(srvbuf,nh_px[0][i],SRVBUFSIZ);
  453.       debug(F110,"setlin service 3",srvbuf,0);
  454.   }
  455.   if (flag) {
  456.       ckstrncpy(srvbuf,q,SRVBUFSIZ);
  457.       debug(F110,"setlin service 4",srvbuf,0);
  458.   }
  459.       }
  460.                       /* Save the hostname */
  461.                       strcpy(hostname,line);
  462.       /* If we have a service, append to host name/address */
  463.       if (*srvbuf) {
  464.   strncat(line, ":", LINBUFSIZ);
  465.   strncat(line, srvbuf, LINBUFSIZ);
  466.   debug(F110,"setlin service 5",line,0);
  467.       }
  468. #ifdef RLOGCODE
  469.       /* If no service given but command was RLOGIN */
  470.       else if (ttnproto == NP_RLOGIN) { /* add this... */
  471.   strncat(line, ":login",LINBUFSIZ);
  472.   debug(F110,"setlin service 6",line,0);
  473.       }
  474. #ifdef CK_AUTHENTICATION
  475. #ifdef CK_KERBEROS
  476.       else if (ttnproto == NP_K4LOGIN ||
  477.        ttnproto == NP_K5LOGIN) { /* add this... */
  478.   strncat(line, ":klogin",LINBUFSIZ);
  479.   debug(F110,"setlin service 7",line,0);
  480.       }
  481.       else if (ttnproto == NP_EK4LOGIN ||
  482.        ttnproto == NP_EK5LOGIN) { /* add this... */
  483.   strncat(line, ":eklogin",LINBUFSIZ);
  484.   debug(F110,"setlin service 8",line,0);
  485.       }
  486. #endif /* CK_KERBEROS */
  487. #endif /* CK_AUTHENTICATION */
  488. #endif /* RLOGCODE */
  489.       else { /* Otherwise, add ":telnet". */
  490.   strncat(line, ":telnet", LINBUFSIZ);
  491.   debug(F110,"setlin service 9",line,0);
  492.       }
  493.                       if (tmpusrid) if (tmpusrid[0]) {
  494.                           ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
  495.                           makestr(&tmpusrid,NULL);
  496.                           uidflag = 1;
  497.                       }
  498.       /* Fifth field, if any, is user ID (for rlogin) */
  499.       if (nh_px[1][i] && !uidflag)
  500. ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
  501. #ifdef RLOGCODE
  502.       if ((ttnproto == NP_RLOGIN
  503. #ifdef CK_AUTHENTICATION
  504. #ifdef CK_KERBEROS
  505.    || ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN
  506.    || ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN
  507. #endif /* CK_KERBEROS */
  508. #endif /* CK_AUTHENTICATION */
  509.    ) && !uidbuf[0]) {
  510.   slmsg = "Username required";
  511.   printf("Username required for rloginn");
  512.   return(-9);
  513.       }
  514. #endif /* RLOGCODE */
  515. #endif /* TCPSOCKET */
  516.       break;
  517.   }
  518.   case NET_PIPE:
  519. #ifdef NPIPE
  520.     if (!pipename[0]) { /* User didn't give a pipename */
  521. if (nh_px[0][i]) { /* But directory entry has one */
  522.     if (strcmp(pipename,"\pipe\")) {
  523. strcpy(pipename,"\pipe\");
  524. strncat(srvbuf,nh_px[0][i],PIPENAML-6);
  525.     } else {
  526. ckstrncpy(pipename,nh_px[0][i],PIPENAML);
  527.     }
  528.     debug(F110,"setlin pipeneme",pipename,0);
  529. }
  530.     }
  531. #endif /* NPIPE */
  532.     break;
  533.   case NET_SLAT:
  534. #ifdef SUPERLAT
  535.     if (!slat_pwd[0]) { /* User didn't give a password */
  536. if (nh_px[0][i]) { /* But directory entry has one */
  537.     ckstrncpy(slat_pwd,nh_px[0][i],18);
  538.     debug(F110,"setlin SuperLAT password",slat_pwd,0);
  539. }
  540.     }
  541. #endif /* SUPERLAT */
  542.     break;
  543.   case NET_SX25: /* X.25 keyword parameters */
  544.   case NET_IX25:
  545.   case NET_VX25: {
  546. #ifdef ANYX25
  547.       int k; /* Cycle through the four fields */
  548.       for (k = 0; k < 4; k++) {
  549.   if (!nh_px[k][i]) /* Bail out if none left */
  550.     break;
  551.   if (!ckstrcmp(nh_px[k][i],"cug=",4,0)) {
  552.       closgr = atoi(nh_px[k][i]+4);
  553.       debug(F101,"X25 CUG","",closgr);
  554.   } else if (!ckstrcmp(nh_px[k][i],"cud=",4,0)) {
  555.       cudata = 1;
  556.       ckstrncpy(udata,nh_px[k][i]+4,MAXCUDATA);
  557.       debug(F110,"X25 CUD",cudata,0);
  558.   } else if (!ckstrcmp(nh_px[k][i],"rev=",4,0)) {
  559.       revcall = !ckstrcmp(nh_px[k][i]+4,"=on",3,0);
  560.       debug(F101,"X25 REV","",revcall);
  561. #ifndef IBMX25
  562.   } else if (!ckstrcmp(nh_px[k][i],"pad=",4,0)) {
  563.       int x3par, x3val;
  564.       char *s1, *s2;
  565.       s1 = s2 = nh_px[k][i]+4; /* PAD parameters */
  566.       while (*s2) {            /* Pick them apart */
  567.   if (*s2 == ':') {
  568.       *s2 = NUL;
  569.       x3par = atoi(s1);
  570.       s1 = ++s2;
  571.       continue;
  572.   } else if (*s2 == ',') {
  573.       *s2 = NUL;
  574.       x3val = atoi(s1);
  575.       s1 = ++s2;
  576.       debug(F111,"X25 PAD",x3par,x3val);
  577.       if (x3par > -1 &&
  578.   x3par <= MAXPADPARMS)
  579. padparms[x3par] = x3val;
  580.       continue;
  581.   } else
  582.     s2++;
  583.       }
  584. #endif /* IBMX25 */
  585.   }
  586.       }
  587. #endif /* ANYX25 */
  588.       break;
  589.   }
  590.   default: /* Nothing special for other nets */
  591.     break;
  592. }
  593.     } else { /* No directory entries found. */
  594. strcpy(line,tmpbuf); /* Put this back... */
  595. if (mynet == NET_TCPB) /* If the user gave a TCP service */
  596.                   strcpy(hostname,line);
  597.   if (*srvbuf) { /* append it to host name/address */
  598.       strncat(line, ":", LINBUFSIZ);
  599.       strncat(line, srvbuf,LINBUFSIZ);
  600.   }
  601.     }
  602. #endif /* NODIAL */
  603.     /*
  604.        Get here with host name/address and all net-specific
  605.        parameters set, ready to open the connection.
  606.     */
  607.     mdmtyp = -mynet; /* This should have been done */
  608. /* already but just in case ... */
  609.     debug(F110,"setlin net line[] before ttopen",line,0);
  610.     debug(F101,"setlin net mdmtyp before ttopen","",mdmtyp);
  611.     debug(F101,"setlin net ttnproto","",ttnproto);
  612. #ifdef CK_AUTHENTICATION
  613.             if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
  614.                  a_type > -1) {
  615.                 if (!sl_auth_saved) {
  616.                     int x;
  617.                     for (x = 0; x < AUTHTYPLSTSZ; x++)
  618.       sl_auth_type_user[x] = auth_type_user[x];
  619.                     sl_auth_saved = 1;
  620.                 }
  621.                 if (!sl_topt_a_s_saved) {
  622.                     sl_topt_a_su = TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION);
  623.                     sl_topt_a_s_saved = 1;
  624.                 }
  625.                 if (!sl_topt_a_c_saved) {
  626.                     sl_topt_a_cm = TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION);
  627.                     sl_topt_a_c_saved = 1;
  628.                 }
  629.                 switch (a_type) {
  630.                   case AUTHTYPE_AUTO:
  631.                     auth_type_user[0] = AUTHTYPE_AUTO;
  632.                     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
  633.                     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RQ;
  634.                     break;
  635.                   case AUTHTYPE_NULL:
  636.     auth_type_user[0] = AUTHTYPE_NULL;
  637.     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  638.     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_RF;
  639.     break;
  640. #ifdef CK_SRP
  641.   case AUTHTYPE_SRP:
  642.                     auth_type_user[0] = AUTHTYPE_SRP;
  643.                     auth_type_user[1] = AUTHTYPE_NULL;
  644.                     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  645.                     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  646.                     break;
  647. #endif /* CK_SRP */
  648. #ifdef CK_SSL
  649.   case AUTHTYPE_SSL:
  650.                     auth_type_user[0] = AUTHTYPE_SSL;
  651.                     auth_type_user[1] = AUTHTYPE_NULL;
  652.                     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  653.                     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  654.                     break;
  655. #endif /* CK_SSL */
  656. #ifdef NT
  657.   case AUTHTYPE_NTLM:
  658.                     auth_type_user[0] = AUTHTYPE_NTLM;
  659.                     auth_type_user[1] = AUTHTYPE_NULL;
  660.                     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  661.                     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  662.                     break;
  663. #endif /* NT */
  664. #ifdef CK_KERBEROS
  665.   case AUTHTYPE_KERBEROS_V4:
  666.                     auth_type_user[0] = AUTHTYPE_KERBEROS_V4;
  667.                     auth_type_user[1] = AUTHTYPE_NULL;
  668.                     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  669.                     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  670.                     break;
  671.   case AUTHTYPE_KERBEROS_V5:
  672.                     auth_type_user[0] = AUTHTYPE_KERBEROS_V5;
  673.                     auth_type_user[1] = AUTHTYPE_NULL;
  674.                     TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  675.                     TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) = TN_NG_MU;
  676.                     break;
  677. #endif /* CK_KERBEROS */
  678.                 }
  679.             }
  680.             /*
  681.                If the user is going to require a Kerberos connection
  682.                of a particular type, let's make sure we have a valid TGT.
  683.             */
  684.     slmsg = "Authentication failure";
  685.             if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
  686. (line[0] == '*' &&
  687.  TELOPT_DEF_S_U_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU ||
  688.  line[0] != '*' &&
  689.  TELOPT_DEF_C_ME_MODE(TELOPT_AUTHENTICATION) == TN_NG_MU)
  690. ) {
  691. #ifdef CK_KERBEROS
  692.                 if ( auth_type_user[0] == AUTHTYPE_KERBEROS_V4 ) {
  693.                     extern int krb4_autoget;
  694.                     if (!ck_krb4_is_installed()) {
  695. printf(
  696.         "?Required authentication method (Kerberos 4) is not installedn"
  697.        );
  698.                         slrestor();
  699. return(success = 0);
  700.                     }
  701. #ifdef COMMENT
  702.                     /* This code results in false failures when using */
  703.                     /* kerberos to machines in realms other than the  */
  704.                     /* default since we don't know the realm of the   */
  705.                     /* other machine until perform the reverse DNS    */
  706.                     /* lookup.                                        */
  707.     else if (line[0] != '*' && !ck_krb4_is_tgt_valid() &&
  708.        (!krb4_autoget ||
  709. krb4_autoget && !ck_krb4_autoget_TGT(NULL))) {
  710.                         printf(
  711.         "?Kerberos 4: Ticket Getting Ticket not valid.n"
  712.        );
  713.                         slrestor();
  714.                         return(success = 0);
  715.                     }
  716. #endif /* COMMENT */
  717.                 } else if (auth_type_user[0] == AUTHTYPE_KERBEROS_V5) {
  718.                     extern int krb5_autoget;
  719.                     if (!ck_krb5_is_installed()) {
  720. printf(
  721.         "?Required authentication method (Kerberos 5) is not installedn"
  722.        );
  723.                         slrestor();
  724.                         return(success = 0);
  725.                     }
  726. #ifdef COMMENT
  727.                     /* This code results in false failures when using */
  728.                     /* kerberos to machines in realms other than the  */
  729.                     /* default since we don't know the realm of the   */
  730.                     /* other machine until perform the reverse DNS    */
  731.                     /* lookup.                                        */
  732.     else if (line[0] != '*' && !ck_krb5_is_tgt_valid() &&
  733.        (!krb5_autoget ||
  734. krb5_autoget && !ck_krb5_autoget_TGT(NULL))) {
  735.                         printf(
  736.         "?Kerberos 5: Ticket Getting Ticket not valid.n"
  737.        );
  738.                         slrestor();
  739.                         return(success = 0);
  740.                     }
  741. #endif /* COMMENT */
  742.                 }
  743. #endif /* CK_KERBEROS */
  744. #ifdef NT
  745.                 if (auth_type_user[0] == AUTHTYPE_NTLM) {
  746.                     if (!ck_ntlm_is_installed()) {
  747. printf(
  748.         "?Required authentication method (NTLM) is not installedn"
  749.        );
  750.                         slrestor();
  751.                         return(success = 0);
  752.                     } else if (line[0] != '*' && !ck_ntlm_is_valid()) {
  753.                         printf("?NTLM: Credentials are unavailable.n");
  754.                         slrestor();
  755.                         return(success = 0);
  756.                     }
  757.                 }
  758. #endif /* NT */
  759. #ifdef CK_SSL
  760.                 if (auth_type_user[0] == AUTHTYPE_SSL) {
  761.                     if (!ck_ssleay_is_installed()) {
  762. printf(
  763.         "?Required authentication method (SSL) is not installedn"
  764.        );
  765.                         slrestor();
  766.                         return(success = 0);
  767.                     }
  768.                 }
  769. #endif /* CK_SSL */
  770. #ifdef CK_SRP
  771.                 if (auth_type_user[0] == AUTHTYPE_SRP) {
  772.                     if (!ck_srp_is_installed()) {
  773. printf(
  774.         "?Required authentication method (SRP) is not installedn"
  775.        );
  776.                         slrestor();
  777.                         return(success = 0);
  778.                     }
  779.                 }
  780. #endif /* CK_SRP */
  781.             }
  782. #endif /* CK_AUTHENTICATION */
  783. #ifdef CK_ENCRYPTION
  784.             if ((ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
  785.                  e_type > -1) {
  786.                 if (!sl_cx_saved) {
  787.                     sl_cx_type = cx_type;
  788.                     sl_cx_saved = 1;
  789.                 }
  790.                 if (!sl_topt_e_s_saved) {
  791.                     sl_topt_e_su = TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION);
  792.                     sl_topt_e_sm = TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION);
  793.                     sl_topt_e_s_saved = 1;
  794.                 }
  795.                 if (!sl_topt_e_c_saved) {
  796.                     sl_topt_e_cu = TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION);
  797.                     sl_topt_e_cm = TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION);
  798.                     sl_topt_e_c_saved = 1;
  799.                 }
  800.                 cx_type = e_type;
  801.                 if (cx_type == CX_AUTO) {
  802.                     TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
  803.                     TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
  804.                     TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
  805.                     TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RQ;
  806.                 } else if (cx_type == CX_NONE) {
  807.                     TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  808.                     TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  809.                     TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  810.                     TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_RF;
  811.                 } else {
  812.                     TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  813.                     TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  814.                     TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  815.                     TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) = TN_NG_MU;
  816.                 }
  817.             }
  818.             if (ttnproto == NP_EK4LOGIN || ttnproto == NP_EK5LOGIN ||
  819. (ttnproto == NP_TELNET || ttnproto == NP_KERMIT) &&
  820. ((line[0] == '*' &&
  821.   TELOPT_DEF_S_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
  822.   TELOPT_DEF_S_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU) ||
  823.  (line[0] != '*' &&
  824.   TELOPT_DEF_C_U_MODE(TELOPT_ENCRYPTION) == TN_NG_MU &&
  825.   TELOPT_DEF_C_ME_MODE(TELOPT_ENCRYPTION) == TN_NG_MU))
  826. ) {
  827.                 if (!ck_crypt_is_installed()) {
  828.     slmsg = "Encryption failure";
  829.                     printf("?Required Encryption methods are not installedn");
  830.                     slrestor();
  831.                     return(success = 0);
  832.                 }
  833.             }
  834. #endif /* CK_ENCRYPTION */
  835. #ifdef RLOGCODE
  836. #ifdef CK_KERBEROS
  837. #ifdef KRB4
  838.             if (ttnproto == NP_K4LOGIN || ttnproto == NP_EK4LOGIN) {
  839.                 extern int krb4_autoget;
  840.                 char tgt[256];
  841.                 char * realm;
  842.                 /* this is fine except for one huge problem         */
  843.                 /* we don't have the full hostname at this point    */
  844.                 /* so we really need to perform a DNS lookup before */
  845.                 /* calling ttopen().                                */
  846.                 realm = ck_krb4_realmofhost(ckgetfqhostname(hostname));
  847.                 sprintf(tgt,"krbtgt.%s@%s",realm,realm);
  848.                 if (!ck_krb4_is_installed()) {
  849.     printf(
  850.         "?Required authentication method (Kerberos 4) is not installedn"
  851.    );
  852.                     slrestor();
  853.                     return(success = 0);
  854.                 } else {
  855.                     if ((ck_krb4_tkt_isvalid(tgt) <= 0) &&
  856. (!krb4_autoget ||
  857.  krb4_autoget && !ck_krb4_autoget_TGT(realm))) {
  858. printf(
  859.    "?Kerberos 4: Ticket Getting Ticket not valid.n");
  860. slrestor();
  861. return(success = 0);
  862.                     }
  863.                 }
  864.             }
  865. #endif /* KRB4 */
  866. #ifdef KRB5
  867.             if (ttnproto == NP_K5LOGIN || ttnproto == NP_EK5LOGIN) {
  868.                 extern int krb5_autoget;
  869.                 char tgt[256];
  870.                 char * realm;
  871.                 /* this is fine except for one huge problem         */
  872.                 /* we don't have the full hostname at this point    */
  873.                 /* so we really need to perform a DNS lookup before */
  874.                 /* calling ttopen().                                */
  875.                 realm = ck_krb5_realmofhost(ckgetfqhostname(hostname));
  876.                 sprintf(tgt,"krbtgt/%s@%s",realm,realm);
  877.                 if (!ck_krb5_is_installed()) {
  878.     printf(
  879.         "?Required authentication method (Kerberos 5) is not installedn"
  880.    );
  881.                     slrestor();
  882.                     return(success = 0);
  883.                 } else if (!((ck_krb5_tkt_isvalid(NULL,tgt) > 0) ||
  884.                               ck_krb5_is_tgt_valid()) &&
  885.    (!krb5_autoget ||
  886.     krb5_autoget && !ck_krb5_autoget_TGT(realm))) {
  887.                     printf("?Kerberos 5: Ticket Getting Ticket not valid.n");
  888.                     slrestor();
  889.                     return(success = 0);
  890.                 }
  891.             }
  892. #endif /* KRB5 */
  893. #endif /* CK_KERBEROS */
  894. #endif /* RLOGCODE */
  895. #ifdef NETCONN
  896. #ifndef NOSPL
  897.             if (tmpstring) {
  898.                 if (tmpstring[0]) {
  899.                     ckstrncpy(pwbuf,tmpstring,PWBUFL+1);
  900.                     pwflg = 1;
  901.                     pwcrypt = 0;
  902.                 } else
  903.                     pwflg = 0;
  904.                 makestr(&tmpstring,NULL);
  905.             }
  906. #ifdef RLOGCODE
  907.             if (tmpusrid) if (tmpusrid[0]) {
  908.                 if (!sl_uid_saved) {
  909.                     ckstrncpy(sl_uidbuf,uidbuf,UIDBUFLEN);
  910.                     sl_uid_saved = 1;
  911.                 }
  912. ckstrncpy(uidbuf,tmpusrid,UIDBUFLEN);
  913.                 makestr(&tmpusrid,NULL);
  914.                 uidflag = 1;
  915.             }
  916. #endif /* RLOGCODE */
  917. #endif /* NOSPL */
  918. #endif /* NETCONN */
  919. #ifdef TNCODE
  920.             if (!sl_tn_saved) {
  921.                 sl_tn_wait = tn_wait_flg;
  922.                 sl_tn_saved = 1;
  923.             }
  924.     tn_wait_flg = wait;
  925. #endif /* TNCODE */
  926.     /* Try to open */
  927.     if ((y = ttopen(line, &_local, mdmtyp, 0 )) < 0) {
  928.                 slrestor();
  929. slmsg = "Network connection failure";
  930. #ifdef VMS
  931. if (hints && !cmdsrc() && ttnproto == NP_RLOGIN) {
  932.     slmsg = "RLOGIN failure";
  933.     printf("*************************n");
  934.     printf("Hint: The RLOGIN port is privileged in VMS.n");
  935.     printf("(Use SET HINTS OFF to suppress future hints.)n");
  936.     printf("*************************n");
  937. }
  938. #else  /* Not VMS... */
  939. if (errno) {
  940.     int x;
  941.     debug(F111,"set host line, errno","",errno);
  942.     makestr(&tmpslmsg,ck_errstr());
  943.     slmsg = tmpslmsg;
  944.     x = strlen(line) + 2;
  945.     if (LINBUFSIZ - x > 100) {
  946. tp = line + x;
  947. #ifdef OS2
  948. printf("Can't connect to %sn",line);
  949. #else /* OS2 */
  950. #ifdef COMMENT
  951. sprintf(tp,"Can't connect to %s",line);
  952. perror(tp);
  953. #endif /* COMMENT */
  954. #ifdef UNIX
  955. if (hints && !cmdsrc() && ttnproto == NP_RLOGIN) {
  956.     slmsg = "RLOGIN failure";
  957.     printf("*************************n");
  958.     printf(
  959.      "Hint: The RLOGIN port is privileged in UNIX.n");
  960.     printf(
  961.     "(Use SET HINTS OFF to suppress future hints.)n");
  962.     printf("*************************n");
  963. }
  964. #endif /* UNIX */
  965. #endif /* OS2 */
  966.     } else printf("Can't connect to %sn",line);
  967. } else
  968. #endif /* VMS */
  969.   printf("Can't open connection to %sn",line);
  970. continue;
  971.     } else {
  972. success = 1;
  973. switch (mynet) {
  974.   case NET_TCPA:
  975.   case NET_TCPB:
  976.     cxtype = CXT_TCPIP;
  977.     break;
  978.   case NET_SLAT:
  979.     cxtype = CXT_LAT;
  980.     break;
  981.   case NET_SX25:
  982.   case NET_IX25:
  983.   case NET_HX25:
  984.   case NET_VX25:
  985.     cxtype = CXT_X25;
  986.     break;
  987.   case NET_BIOS:
  988.     cxtype = CXT_NETBIOS;
  989.     break;
  990.   case NET_FILE:
  991.   case NET_PIPE:
  992.   case NET_CMD:
  993.   case NET_DLL:
  994.   case NET_PTY:
  995.     cxtype = CXT_PIPE;
  996.     break;
  997.   default:
  998.     cxtype = CXT_PIPE;
  999.     break;
  1000. }
  1001. break;
  1002.     }
  1003. } /* for-loop */
  1004. s = line;
  1005.     } /* network connection */
  1006. #endif /* NETCONN */
  1007. /*
  1008.   NOTE:
  1009.   The following will fail if Kermit is running as a daemon with no
  1010.   controlling tty.  Needs research.
  1011. */
  1012.     if (!success) {
  1013. local = dfloc; /* Go back to normal */
  1014. #ifndef MAC
  1015. strcpy(ttname,dftty); /* Restore default tty name */
  1016. #endif /* MAC */
  1017. speed = ttgspd();
  1018. network = 0; /* No network connection active */
  1019. haveline = 0;
  1020. if (mdmtyp < 0) { /* Switching from net to async? */
  1021.     if (mdmsav > -1) /* Restore modem type from last */
  1022.       mdmtyp = mdmsav; /* SET MODEM command, if any. */
  1023.     else
  1024.       mdmtyp = 0;
  1025.     mdmsav = -1;
  1026. }
  1027. return(0); /* Return failure */
  1028.     }
  1029.     if (_local > -1) local = _local; /* Opened ok, set local/remote. */
  1030.     slmsg = NULL;
  1031.     network = (mdmtyp < 0); /* Remember connection type. */
  1032.     strcpy(ttname,s); /* Copy name into real place. */
  1033.     debug(F110,"setlin ok",ttname,0);
  1034.     debug(F101,"setlin network","",network);
  1035.     if (!network)
  1036.       speed = ttgspd(); /* Get the current speed. */
  1037.     debug(F101,"setlin local","",local);
  1038. #ifdef NETCONN
  1039.     if (network) {
  1040. debug(F101,"setlin mynet","",mynet);
  1041. #ifndef NOXFER
  1042. /* Force prefixing of 255 on TCP/IP connections... */
  1043. if (mynet == NET_TCPB) {
  1044.     debug(F101,"setlin reliable A","",reliable);
  1045. #ifdef CK_SPEED
  1046.     ctlp[(unsigned)255] = 1;
  1047. #endif /* CK_SPEED */
  1048.     if (reliable != SET_OFF || !setreliable)
  1049.       reliable = SET_ON; /* Transport is reliable end to end */
  1050.     debug(F101,"setlin reliable B","",reliable);
  1051. } else if (mynet == NET_SX25 ||
  1052.    mynet == NET_VX25 ||
  1053.    mynet == NET_IX25 ||
  1054.    mynet == NET_HX25) {
  1055.     duplex = 1; /* Local echo for X.25 */
  1056.     if (reliable != SET_OFF || !setreliable)
  1057.       reliable = SET_ON; /* Transport is reliable end to end */
  1058. }
  1059. #endif /* NOXFER */
  1060.     }
  1061. #endif /* NETCONN */
  1062. #ifndef NOXFER
  1063.     debug(F101,"setlin reliable","",reliable);
  1064. #endif /* NOXFER */
  1065. #ifdef OS2
  1066.     if (mdmtyp <= 0) /* Network or Direct Connection */
  1067.       DialerSend(OPT_KERMIT_CONNECT, 0);
  1068. #endif /* OS2 */
  1069.     setflow(); /* Set appropriate flow control */
  1070.     haveline = 1;
  1071. #ifdef CKLOGDIAL
  1072. #ifdef NETCONN
  1073.     if (network) /* Start connection log record */
  1074.       dolognet();
  1075.     else
  1076. #endif /* NETCONN */
  1077.       dologline();
  1078. #endif /* CKLOGDIAL */
  1079. #ifndef NOSPL
  1080.     if (local) {
  1081. if (nmac) { /* Any macros defined? */
  1082.     int k; /* Yes */
  1083.     k = mlook(mactab,"on_open",nmac); /* Look this up */
  1084.     if (k >= 0) { /* If found, */
  1085. if (dodo(k,ttname,0) > -1) /* set it up, */
  1086.   parser(1); /* and execute it */
  1087.     }
  1088. }
  1089.     }
  1090. #endif /* NOSPL */
  1091.     if (local && (cx || sx)) { /* /CONNECT or /SERVER switch given */
  1092. extern int carrier;
  1093. if (xx == XYLINE && carrier != CAR_OFF) { /* on serial connection... */
  1094.     /* Open() turns on DTR -- wait up to a second for CD to come up */
  1095.     int i, x;
  1096.     for (i = 0; i < 10; i++) { /* WAIT 1 CD... */
  1097. x = ttgmdm();
  1098. if (x < 0 || x & BM_DCD)
  1099.   break;
  1100. msleep(100);
  1101.     }
  1102. }
  1103. if (cx) { /* /CONNECT */
  1104.     success = doconect(0);
  1105. #ifdef CKLOGDIAL
  1106.     if (ttchk() < 0)
  1107.       dologend();
  1108. #endif /* CKLOGDIAL */
  1109.     return(success);
  1110. #ifndef NOXFER
  1111. } else if (sx) { /* /SERVER */
  1112.     sstate = 'x';
  1113. #ifdef MAC
  1114.     what = W_RECV;
  1115.     scrcreate();
  1116. #endif /* MAC */
  1117.     if (local) displa = 1;
  1118. #ifdef AMIGA
  1119.     reqoff(); /* No DOS requestors while server */
  1120. #endif /* AMIGA */
  1121. #endif /* NOXFER */
  1122. }
  1123.     }
  1124.     return(success = 1);
  1125. }
  1126. #endif /* NOLOCAL */
  1127. #ifdef CKCHANNELIO
  1128. /*
  1129.   C-Library based file-i/o package for scripts.  This should be portable to
  1130.   all C-Kermit versions since it uses the same APIs we have always used for
  1131.   processing command files.  The entire channel i/o package is contained
  1132.   herein, apart from some keyword table entries in the main keyword table
  1133.   and the help text in the HELP command module.
  1134.   On platforms like VMS and VOS, this package handles only UNIX-style
  1135.   stream files.  If desired, it can be replaced for those platforms by
  1136.   <#>ifdef'ing out this code and adding the equivalent replacement routines
  1137.   to the ck?fio.c module, e.g. for RMS-based file i/o in ckvfio.c.
  1138. */
  1139. /* Define NOSTAT if the <#>include causes trouble. */
  1140. #ifndef NOSTAT
  1141. #ifdef VMS
  1142. #ifdef VAXC /* As it does in VAX C */
  1143. #define NOSTAT
  1144. #endif /* VAXC */
  1145. #endif /* VMS */
  1146. #endif /* NOSTAT */
  1147. #ifndef NOSTAT
  1148. #include <sys/stat.h>
  1149. #endif /* NOSTAT */
  1150. #ifdef NLCHAR
  1151. static int z_lt = 1; /* Length of line terminator */
  1152. #else
  1153. static int z_lt = 2;
  1154. #endif /* NLCHAR */
  1155. struct ckz_file { /* C-Kermit file struct */
  1156.     FILE * z_fp; /* Includes the C-Lib file struct */
  1157.     unsigned int z_flags; /* Plus C-Kermit mode flags, */
  1158.     long z_nline; /* current line number if known, */
  1159.     char z_name[CKMAXPATH+2]; /* and the file's name. */
  1160. };
  1161. static struct ckz_file * z_file = NULL; /* Array of C-Kermit file structs */
  1162. static int z_inited = 0; /* Flag for array initialized */
  1163. int z_maxchan = Z_MAXCHAN; /* Max number of C-Kermit channels */
  1164. int z_openmax = CKMAXOPEN; /* Max number of open files overall */
  1165. int z_nopen = 0; /* How many channels presently open */
  1166. int z_error = 0; /* Most recent error */
  1167. int z_filcount = -1; /* Most recent FILE COUNT result */
  1168. #define RD_LINE 0 /* FILE READ options */
  1169. #define RD_CHAR 1
  1170. #define RD_SIZE 2
  1171. #define WR_LINE RD_LINE /* FILE WRITE options */
  1172. #define WR_CHAR RD_CHAR
  1173. #define WR_SIZE RD_SIZE
  1174. #define WR_STRI 3
  1175. #define WR_LPAD 4
  1176. #define WR_RPAD 5
  1177. #ifdef UNIX
  1178. extern int ckmaxfiles; /* Filled in by sysinit(). */
  1179. #endif /* UNIX */
  1180. /* See ckcker.h for error numbers */
  1181. /* See ckcdeb.h for Z_MAXCHAN and CKMAXOPEN definitions */
  1182. /* NOTE: For VMS we might be able to fill in ckmaxfiles */
  1183. /* from FILLM and CHANNELCNT -- find out about these... */
  1184. static char * fopnargs[] = { /* Mode combinations for fopen() */
  1185. #ifdef COMMENT
  1186.     /* All combinations of rwa */
  1187.     "",  "r",  "w",  "rw",  "a",  "ra",  "wa",  "rwa", /* Text mode */
  1188.     "b", "rb", "wb", "rwb", "ab", "rab", "wab", "rwab" /* Binary mode */
  1189. #else
  1190.     /* Combinations and syntax permitted by C libraries... */
  1191.     "",  "r",  "w",  "r+",  "a",  "",   "a",  "", /* Text mode */
  1192. #ifdef OS2
  1193.     "",  "rb", "wb", "r+b", "ab", "",   "ab", "" /* Binary modes for K95 */
  1194. #else
  1195. #ifdef VMS
  1196.     "",  "rb", "wb", "r+b", "ab", "",   "ab", "" /* Binary modes for VMS */
  1197. #else
  1198.     "",  "r",   "w", "r+",  "a",  "",   "a",  "" /* Binary modes for UNIX */
  1199. #endif /* VMS */
  1200. #endif /* OS2 */
  1201. #endif /* COMMENT */
  1202. };
  1203. static int nfopnargs = sizeof(fopnargs) / sizeof(char *);
  1204. char * /* Error messages */
  1205. ckferror(n) int n; {
  1206.     switch (n) {
  1207.       case FX_NER: return("No error");
  1208.       case FX_SYS: return(ck_errstr());
  1209.       case FX_EOF: return("End of file");
  1210.       case FX_NOP: return("File not open");
  1211.       case FX_CHN: return("Channel out of range");
  1212.       case FX_RNG: return("Parameter out of range");
  1213.       case FX_NMF: return("Too many files open");
  1214.       case FX_FOP: return("Operation conflicts with OPEN mode");
  1215.       case FX_NYI: return("OPEN mode not supported");
  1216.       case FX_BOM: return("Illegal combination of OPEN modes");
  1217.       case FX_ACC: return("Access denied");
  1218.       case FX_FNF: return("File not found");
  1219.       case FX_OFL: return("Buffer overflow");
  1220.       case FX_LNU: return("Current line number unknown");
  1221.       case FX_UNK: return("Operation fails - reason unknown");
  1222.       default: return("Error number out of range");
  1223.     }
  1224. }
  1225. /*
  1226.   Z _ O P E N --  Open a file for the requested type of access.
  1227.   Call with:
  1228.     name:  Name of file to be opened.
  1229.     flags: Any combination of FM_xxx values except FM_EOF (ckcker.h).
  1230.   Returns:
  1231.     >= 0 on success: The assigned channel number
  1232.     <  0 on failure: A negative FX_xxx error code (ckcker.h).
  1233. */
  1234. int
  1235. z_open(name, flags) char * name; int flags; {
  1236.     int i, n;
  1237.     FILE * t;
  1238.     char * mode;
  1239.     debug(F111,"z_open",name,flags);
  1240.     if (!name) name = ""; /* Check name argument */
  1241.     if (!name[0])
  1242.       return(z_error = FX_BFN);
  1243.     if (flags & FM_CMD) /* Opening pipes not implemented yet */
  1244.       return(z_error = FX_NYI); /* (and not portable either) */
  1245.     debug(F101,"z_open nfopnargs","",nfopnargs);
  1246.     if (flags < 0 || flags >= nfopnargs) /* Range check flags */
  1247.       return(z_error = FX_RNG);
  1248.     mode = fopnargs[flags]; /* Get fopen() arg */
  1249.     debug(F111,"z_open fopen args",mode,flags);
  1250.     if (!mode[0]) /* Check for illegal combinations */
  1251.       return(z_error = FX_BOM);
  1252.     if (!z_inited) { /* If file structs not inited */
  1253. debug(F101,"z_open z_maxchan 1","",z_maxchan);
  1254. #ifdef UNIX
  1255. debug(F101,"z_open ckmaxfiles","",ckmaxfiles);
  1256. if (ckmaxfiles > 0) { /* Set in ck?tio.c: sysinit() */
  1257.     int x;
  1258.     x = ckmaxfiles - ZNFILS - 5;
  1259.     if (x > z_maxchan) /* sysconf() value greater than */
  1260.       z_maxchan = x; /* value from header files. */
  1261.     debug(F101,"z_open z_maxchan 2","",z_maxchan);
  1262. }
  1263. #endif /* UNIX */
  1264. if (z_maxchan < Z_MINCHAN) /* Allocate at least this many. */
  1265.   z_maxchan = Z_MINCHAN;
  1266. debug(F101,"z_open z_maxchan 3","",z_maxchan);
  1267. /* Note: This could be a pretty big chunk of memory */
  1268. /* if z_maxchan is a big number.  If this becomes a problem */
  1269. /* we'll need to malloc and free each element at open/close time */
  1270. if (!(z_file = (struct ckz_file *)
  1271.       malloc(sizeof(struct ckz_file) * (z_maxchan + 1))))
  1272.   return(z_error = FX_NMF);
  1273. for (i = 0; i < z_maxchan; i++) {
  1274.     z_file[i].z_fp = NULL;
  1275.     z_file[i].z_flags = 0;
  1276.     z_file[i].z_nline = 0;
  1277.     *(z_file[i].z_name) = '';
  1278. }
  1279. z_inited = 1; /* Remember we did */
  1280.     }
  1281.     for (n = -1, i = 0; i < z_maxchan; i++) {
  1282. if (!z_file[i].z_fp) {
  1283.     n = i;
  1284.     break;
  1285. }
  1286.     }
  1287.     if (n < 0 || n >= z_maxchan) /* Any free channels? */
  1288.       return(z_error = FX_NMF); /* No, fail. */
  1289.     errno = 0;
  1290.     z_file[n].z_flags = 0; /* In case of failure... */
  1291.     t = fopen(name, mode); /* Try to open the file. */
  1292.     if (!t) { /* Failed... */
  1293. debug(F111,"z_open error",name,errno);
  1294. #ifdef EMFILE
  1295. if (errno == EMFILE)
  1296.   return(z_error = FX_NMF);
  1297. #endif /* EMFILE */
  1298. return(z_error = (errno ?  FX_SYS : FX_UNK)); /* Return error code */
  1299.     }
  1300. #ifdef NT
  1301. #ifdef O_SEQUENTIAL
  1302.     if (t) /* Caching hint for NT */
  1303.       _setmode(_fileno(t),O_SEQUENTIAL);
  1304. #endif /* O_SEQUENTIAL */
  1305. #endif /* NT */
  1306.     z_nopen++; /* Open, count it. */
  1307.     z_file[n].z_fp = t; /* Stash the file pointer */
  1308.     z_file[n].z_flags = flags; /* and the flags */
  1309.     z_error = 0;
  1310.     zfnqfp(name,CKMAXPATH,z_file[n].z_name); /* and the file's full name */
  1311.     return(n); /* Return the channel number */
  1312. }
  1313. int
  1314. z_close(channel) int channel; { /* Close file on given channel */
  1315.     int x;
  1316.     FILE * t;
  1317.     if (!z_inited) /* Called before any files are open? */
  1318.       return(z_error = FX_NOP);
  1319.     if (channel >= z_maxchan) /* Channel out of range? */
  1320.       return(z_error = FX_CHN);
  1321.     if (!(t = z_file[channel].z_fp)) /* Channel wasn't open? */
  1322.       return(z_error = FX_NOP);
  1323.     errno = 0; /* Set errno 0 to get a good reading */
  1324.     x = fclose(t); /* Try to close */
  1325.     if (x == EOF) /* On failure */
  1326.       return(z_error = FX_SYS); /* indicate system error. */
  1327.     z_nopen--; /* Closed OK, decrement open count */
  1328.     z_file[channel].z_fp = NULL; /* Set file pointer to NULL */
  1329.     z_file[channel].z_nline = 0; /* Current line number is 0 */
  1330.     z_file[channel].z_flags = 0; /* Set flags to 0 */
  1331.     *(z_file[channel].z_name) = ''; /* Clear name */
  1332.     return(z_error = 0);
  1333. }
  1334. /*
  1335.   Z _ O U T  --  Output string to channel.
  1336.   Call with:
  1337.     channel:     Channel number to write to.
  1338.     s:           String to write.
  1339.     length > -1: How many characters of s to write.
  1340.     length < 0:  Write entire NUL-terminated string.
  1341.     flags == 0:  Supply line termination.
  1342.     flags >  0:  Don't supply line termination.
  1343.     flags <  0:  Write 'length' NUL characters.
  1344.   Special case:
  1345.     If flags > -1 and s is empty or NULL and length == 1, write 1 NUL.
  1346.   Returns:
  1347.     Number of characters written to channel on success, or
  1348.     negative FX_xxx error code on failure.
  1349. */
  1350. int
  1351. z_out(channel,s,length,flags) int channel, flags, length; char * s; {
  1352.     FILE * t;
  1353.     int x, n;
  1354.     char c = '';
  1355.     if (!s) s = ""; /* Guard against null pointer */
  1356. #ifdef DEBUG
  1357.     if (deblog) {
  1358. debug(F111,"z_out",s,channel);
  1359. debug(F101,"z_out length","",length);
  1360. debug(F101,"z_out flags","",flags);
  1361.     }
  1362. #endif /* DEBUG */
  1363.     if (!z_inited) /* File i/o inited? */
  1364.       return(z_error = FX_NOP);
  1365.     if (channel >= z_maxchan) /* Channel in range? */
  1366.       return(z_error = FX_CHN);
  1367.     if (!(t = z_file[channel].z_fp)) /* File open? */
  1368.       return(z_error = FX_NOP);
  1369.     if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* In write mode? */
  1370.       return(z_error = FX_FOP);
  1371.     n = length; /* Length of string to write */
  1372.     if (n < 0) { /* Negative means get it ourselves */
  1373. if (flags < 0) /* Except when told to write NULs in */
  1374.   return(z_error = FX_RNG); /* which case args are inconsistent */
  1375. n = strlen(s); /* Get length of string arg */
  1376.     }
  1377.     errno = 0; /* Reset errno */
  1378.     debug(F101,"z_out n","",n);
  1379.     if (flags < 0) { /* Writing NULs... */
  1380. int i;
  1381. for (i = 0; i < n; i++) {
  1382.     x = fwrite(&c,1,1,t);
  1383.     if (x < 1)
  1384.       return(z_error = (errno ? FX_SYS : FX_UNK));
  1385. }
  1386. z_file[channel].z_nline = -1; /* Current line no longer known */
  1387. z_error = 0;
  1388. return(i);
  1389.     } else { /* Writing string arg */
  1390. if (n == 1 && !s[0]) /* Writing one char but it's NUL */
  1391.   x = fwrite(&c,1,1,t);
  1392. else /* Writing non-NUL char or string */
  1393.   x = fwrite(s,1,n,t);
  1394. debug(F101,"z_out fwrite",ckitoa(x),errno);
  1395. if (x < n) /* Failure to write requested amount */
  1396.   return(z_error = (errno ? FX_SYS : FX_UNK)); /* Return error */
  1397. if (flags == 0) { /* If supplying line termination */
  1398.     if (fwrite("n",1,1,t)) /* do that  */
  1399.       x += z_lt; /* count the terminator */
  1400.     if (z_file[channel].z_nline > -1) /* count this line */
  1401.       z_file[channel].z_nline++;
  1402. } else {
  1403.     z_file[channel].z_nline = -1; /* Current line no longer known */
  1404. }
  1405.     }
  1406.     z_error = 0;
  1407.     return(x);
  1408. }
  1409. #define Z_INBUFLEN 64
  1410. /*
  1411.   Z _ I N  --  Multichannel i/o file input function.
  1412.   Call with:
  1413.     channel number to read from.
  1414.     s = address of destination buffer.
  1415.     buflen = destination buffer length.
  1416.     length = Number of bytes to read, must be < buflen.
  1417.     flags: 0 = read a line; nonzero = read the given number of bytes.
  1418.   Returns:
  1419.     Number of bytes read into buffer or a negative error code.
  1420.     A terminating NUL is deposited after the last byte that was read.
  1421. */
  1422. int
  1423. z_in(channel,s,buflen,length,flags)
  1424.  int channel, buflen, length, flags; char * s;
  1425. /* z_in */ {
  1426.     int i, j, x;
  1427.     FILE * t;
  1428.     char * p;
  1429.     if (!z_inited) /* Check everything... */
  1430.       return(z_error = FX_NOP);
  1431.     if (channel >= z_maxchan)
  1432.       return(z_error = FX_CHN);
  1433.     if (!(t = z_file[channel].z_fp))
  1434.       return(z_error = FX_NOP);
  1435.     if (!((z_file[channel].z_flags) & FM_REA))
  1436.       return(z_error = FX_FOP);
  1437.     if (!s) /* Check destination */
  1438.      return(z_error = FX_RNG);
  1439.     s[0] = NUL;
  1440.     if (length == 0) /* Read 0 bytes - easy. */
  1441.       return(z_error = 0);
  1442.     debug(F101,"z_in channel","",channel);
  1443.     debug(F101,"z_in buflen","",buflen);
  1444.     debug(F101,"z_in length","",length);
  1445.     debug(F101,"z_in flags","",flags);
  1446.     if (length < 0 || buflen < 0) /* Check length args */
  1447.       return(z_error = FX_RNG);
  1448.     if (buflen <= length)
  1449.       return(z_error = FX_RNG);
  1450.     errno = 0; /* Reset errno */
  1451.     if (flags) { /* Read block or byte */
  1452. i = fread(s,1,length,t);
  1453. #ifdef DEBUG
  1454. if (deblog) {
  1455.     debug(F111,"z_in block",s,i);
  1456.     debug(F101,"z_in block errno","",errno);
  1457.     debug(F101,"z_in block ferror","",ferror(t));
  1458.     debug(F101,"z_in block feof","",feof(t));
  1459. }
  1460. #endif /* DEBUG */
  1461. z_file[channel].z_nline = -1; /* Current line no longer known */
  1462.     } else { /* Read line */
  1463. #ifndef COMMENT
  1464. /* This method is used because it's simpler than the others */
  1465.         /* and also marginally faster. */
  1466. for (i = 0; i < length; i++) {
  1467.     if ((x = getc(t)) == EOF)
  1468.       break;
  1469.     s[i] = x;
  1470.     if (s[i] == 'n') {
  1471. s[i] = '';
  1472. break;
  1473.     }
  1474. }
  1475. debug(F111,"z_in line byte loop",ckitoa(errno),i);
  1476. if (z_file[channel].z_nline > -1)
  1477.   z_file[channel].z_nline++;
  1478. #else
  1479. #ifdef COMMENT2
  1480. /* Straightforward but strlen() slows it down. */
  1481. s[0] = '';
  1482. i = 0;
  1483. if (fgets(s,length,t)) {
  1484.     i = strlen(s);
  1485.     if (i > 0 && s[i-1] == 'n') i--;
  1486. }
  1487. debug(F111,"z_in line fgets",ckitoa(errno),i);
  1488. if (z_file[channel].z_nline > -1)
  1489.   z_file[channel].z_nline++;
  1490. #else
  1491. /* This is a do-it-yourself fgets() with its own readahead and */
  1492. /* putback.  It's a bit faster than real fgets() but not enough */
  1493. /* to justify the added complexity or the risk of the ftell() and */
  1494. /* fseek() calls failing. */
  1495. int k, flag = 0;
  1496. long pos;
  1497. for (i = 0; !flag && i <= (length - Z_INBUFLEN); i += Z_INBUFLEN) {
  1498.     k = ((length - i) < Z_INBUFLEN) ? length - i : Z_INBUFLEN;
  1499.     if ((x = fread(s+i,1,k,t)) < 1)
  1500.       break;
  1501.     s[i+x] = '';
  1502.     for (j = 0; j < x; j++) {
  1503. if (s[i+j] == 'n') {
  1504.     s[i+j] = '';
  1505.     flag ++;
  1506.     pos = ftell(t);
  1507.     if (pos > -1) {
  1508. pos -= (x - j - 1);
  1509. x = fseek(t, pos, 0);
  1510. i += j;
  1511. break;
  1512.     } else
  1513.       return(z_error = FX_SYS);
  1514. }
  1515.     }
  1516. }
  1517. if (z_file[channel].z_nline > -1)
  1518.   z_file[channel].z_nline++;
  1519. debug(F111,"z_in line chunk loop",ckitoa(errno),i);
  1520. #endif /* COMMENT2 */
  1521. #endif /* COMMENT */
  1522.     }
  1523.     debug(F111,"z_in i",ckitoa(errno),i);
  1524.     if (i < 0) i = 0; /* NUL-terminate result */
  1525.     s[i] = '';
  1526.     if (i > 0) {
  1527. z_error = 0;
  1528. return(i);
  1529.     }
  1530.     if (i == 0 && feof(t)) /* EOF on reading? */
  1531.       return(z_error = FX_EOF); /* Return EOF code */
  1532.     return(errno ? (z_error = -1) : i); /* Return length or system error */
  1533. }
  1534. int
  1535. z_flush(channel) int channel; { /* Flush output channel */
  1536.     FILE * t;
  1537.     int x;
  1538.     if (!z_inited) /* Regular checks */
  1539.       return(z_error = FX_NOP);
  1540.     if (channel >= z_maxchan)
  1541.       return(z_error = FX_CHN);
  1542.     if (!(t = z_file[channel].z_fp))
  1543.       return(z_error = FX_NOP);
  1544.     if (!((z_file[channel].z_flags) & (FM_WRI|FM_APP))) /* Write access? */
  1545.       return(z_error = FX_FOP);
  1546.     errno = 0; /* Reset errno */
  1547.     x = fflush(t); /* Try to flush */
  1548.     return(x ? (z_error = FX_SYS) : 0); /* Return system error or 0 if OK */
  1549. }
  1550. int
  1551. #ifdef CK_ANSIC
  1552. z_seek(int channel, long pos) /* Move file pointer to byte */
  1553. #else
  1554. z_seek(channel,pos) int channel; long pos; /* (seek to given position) */
  1555. #endif /* CK_ANSIC */
  1556. {
  1557.     int i, x = 0, rc;
  1558.     FILE * t;
  1559.     if (!z_inited) /* Check... */
  1560.       return(z_error = FX_NOP);
  1561.     if (channel >= z_maxchan)
  1562.       return(z_error = FX_CHN);
  1563.     if (!(t = z_file[channel].z_fp))
  1564.       return(z_error = FX_NOP);
  1565.     if (pos < 0L) {
  1566. x = 2;
  1567. pos = (pos == -2) ? -1L : 0L;
  1568.     }
  1569.     errno = 0;
  1570.     rc = fseek(t,pos,x); /* Try to seek */
  1571.     debug(F111,"z_seek",ckitoa(errno),rc);
  1572.     if (rc < 0) /* OK? */
  1573.       return(z_error = FX_SYS); /* No. */
  1574.     z_file[channel].z_nline = ((pos || x) ? -1 : 0);
  1575.     return(z_error = 0);
  1576. }
  1577. int
  1578. #ifdef CK_ANSIC
  1579. z_line(int channel, long pos) /* Move file pointer to line */
  1580. #else
  1581. z_line(channel,pos) int channel; long pos; /* (seek to given position) */
  1582. #endif /* CK_ANSIC */
  1583. {
  1584.     int i, len, x = 0;
  1585.     long current = 0L, prev = -1L, old = -1L;
  1586.     FILE * t;
  1587.     char tmpbuf[256];
  1588.     if (!z_inited) /* Check... */
  1589.       return(z_error = FX_NOP);
  1590.     if (channel >= z_maxchan)
  1591.       return(z_error = FX_CHN);
  1592.     if (!(t = z_file[channel].z_fp))
  1593.       return(z_error = FX_NOP);
  1594.     debug(F101,"z_line pos","",pos);
  1595.     if (pos < 0L) { /* EOF wanted */
  1596.         long n;
  1597. n = z_file[channel].z_nline;
  1598. if (n < 0) {
  1599.     rewind(t);
  1600.     n = 0;
  1601. }
  1602. while (1) { /* This could take a while... */
  1603.     if ((x = getc(t)) == EOF)
  1604.       break;
  1605.     if (x == 'n') {
  1606. n++;
  1607. if (pos == -2) {
  1608.     old = prev;
  1609.     prev = ftell(t);
  1610. }
  1611.     }
  1612. }
  1613. if (pos == -2) {
  1614.     if ((x = z_seek(channel,old)) < 0)
  1615.       return(z_error = x);
  1616.     else
  1617.       n--;
  1618. }
  1619. z_file[channel].z_nline = n;
  1620. return(z_error = 0);
  1621.     }
  1622.     if (pos == 0L) { /* Rewind wanted */
  1623. z_file[channel].z_nline = 0L;
  1624. rewind(t);
  1625. debug(F100,"z_line rewind","",0);
  1626. return(0L);
  1627.     }
  1628.     tmpbuf[255] = NUL; /* Make sure buf is NUL terminated */
  1629.     current = z_file[channel].z_nline; /* Current line */
  1630.     /*
  1631.       If necessary the following could be optimized, e.g. for positioning
  1632.       to a previous line in a large file without starting over.
  1633.     */
  1634.     if (current < 0 || pos < current) { /* Not known or behind us... */
  1635. debug(F101,"z_line rewinding","",pos);
  1636. if ((x = z_seek(channel, 0L)) < 0) /* Rewind */
  1637.   return(z_error = x);
  1638. if (pos == 0) /* If 0th line wanted we're done */
  1639.   return(z_error = 0);
  1640. current = 0;
  1641.     }
  1642.     while (current < pos) { /* Search for specified line */
  1643. if (fgets(tmpbuf,255,t)) {
  1644.     len = strlen(tmpbuf);
  1645.     if (len > 0 && tmpbuf[len-1] == 'n') {
  1646. current++;
  1647. debug(F111,"z_line read",ckitoa(len),current);
  1648.     } else if (len == 0) {
  1649. return(z_error = FX_UNK);
  1650.     }
  1651. } else {
  1652.     z_file[channel].z_nline = -1L;
  1653.     debug(F101,"z_line premature EOF","",current);
  1654.     return(z_error = FX_EOF);
  1655. }
  1656.     }
  1657.     z_file[channel].z_nline = current;
  1658.     debug(F101,"z_line result","",current);
  1659.     z_error = 0;
  1660.     return(current);
  1661. }
  1662. char *
  1663. z_getname(channel) int channel; { /* Return name of file on channel */
  1664.     FILE * t;
  1665.     if (!z_inited) {
  1666. z_error = FX_NOP;
  1667. return(NULL);
  1668.     }
  1669.     if (channel >= z_maxchan) {
  1670. z_error = FX_CHN;
  1671. return(NULL);
  1672.     }
  1673.     if (!(t = z_file[channel].z_fp)) {
  1674. z_error = FX_NOP;
  1675. return(NULL);
  1676.     }
  1677.     return((char *)(z_file[channel].z_name));
  1678. }
  1679. int
  1680. z_getmode(channel) int channel; { /* Return OPEN modes of channel */
  1681.     FILE * t; /* 0 if file not open */
  1682. #ifndef NOSTAT
  1683.     struct stat statbuf;
  1684. #endif /* NOSTAT */
  1685.     int x;
  1686.     if (!z_inited)
  1687.       return(0);
  1688.     if (channel >= z_maxchan)
  1689.       return(z_error = FX_CHN);
  1690.     if (!(t = z_file[channel].z_fp))
  1691.       return(0);
  1692.     x = z_file[channel].z_flags;
  1693.     if (feof(t)) { /* This might not work for */
  1694. x |= FM_EOF; /* output files */
  1695. #ifndef NOSTAT
  1696.     /* But this does if we can use it. */
  1697.     } else if (stat(z_file[channel].z_name,&statbuf) > -1) {
  1698. if (ftell(t) == statbuf.st_size)
  1699.   x |= FM_EOF;
  1700. #endif /* NOSTAT */
  1701.     }
  1702.     return(x);
  1703. }
  1704. long
  1705. z_getpos(channel) int channel; { /* Get file pointer position */
  1706.     FILE * t; /* on this channel */
  1707.     long x;
  1708.     if (!z_inited)
  1709.       return(z_error = FX_NOP);
  1710.     if (channel >= z_maxchan)
  1711.       return(z_error = FX_CHN);
  1712.     if (!(t = z_file[channel].z_fp))
  1713.       return(z_error = FX_NOP);
  1714.     x = ftell(t);
  1715.     return((x < 0L) ? (z_error = FX_SYS) : x);
  1716. }
  1717. long
  1718. z_getline(channel) int channel; { /* Get current line number */
  1719.     FILE * t; /* in file on this channel */
  1720.     long rc;
  1721.     if (!z_inited)
  1722.       return(z_error = FX_NOP);
  1723.     if (channel >= z_maxchan)
  1724.       return(z_error = FX_CHN);
  1725.     if (!(t = z_file[channel].z_fp))
  1726.       return(z_error = FX_NOP);
  1727.     debug(F101,"z_getline","",z_file[channel].z_nline);
  1728.     rc = z_file[channel].z_nline;
  1729.     return((rc < 0) ? (z_error = FX_LNU) : rc);
  1730. }
  1731. int
  1732. z_getfnum(channel) int channel; { /* Get file number / handle */
  1733.     FILE * t; /* for file on this channel */
  1734.     if (!z_inited)
  1735.       return(z_error = FX_NOP);
  1736.     if (channel >= z_maxchan)
  1737.       return(z_error = FX_CHN);
  1738.     if (!(t = z_file[channel].z_fp))
  1739.       return(z_error = FX_NOP);
  1740.     z_error = 0;
  1741.     return(fileno(t));
  1742. }
  1743. /*
  1744.   Line-oriented counts and seeks are as dumb as they can be at the moment.
  1745.   Later we can speed them up by building little indexes.
  1746. */
  1747. long
  1748. z_count(channel, what) int channel, what; { /* Count bytes or lines in file */
  1749.     FILE * t;
  1750.     int i, x;
  1751.     long pos, count = 0L;
  1752.     if (!z_inited) /* Check stuff... */
  1753.       return(z_error = FX_NOP);
  1754.     if (channel >= z_maxchan)
  1755.       return(z_error = FX_CHN);
  1756.     if (!(t = z_file[channel].z_fp))
  1757.       return(z_error = FX_NOP);
  1758.     pos = ftell(t); /* Save current file pointer */
  1759.     errno = 0;
  1760.     z_error = 0;
  1761.     if (what == RD_CHAR) { /* Size in bytes requested */
  1762. if (!fseek(t,0L,2)) { /* Seek to end */
  1763.     count = ftell(t); /* Get file pointer */
  1764.     fseek(t,pos,0); /* Restore file file pointer */
  1765.     return(count);
  1766. } else /* Fallback in case seek fails */
  1767.   return(zgetfs(z_file[channel].z_name));
  1768.     }
  1769.     rewind(t); /* Line count requested - rewind. */
  1770.     while (1) { /* Count lines. */
  1771. if ((x = getc(t)) == EOF) /* Stupid byte loop */
  1772.   break; /* but it works as well as anything */
  1773. if (x == 'n') /* else... */
  1774.   count++;
  1775.     }
  1776.     x = fseek(t,pos,0); /* Restore file pointer */
  1777.     return(count);
  1778. }
  1779. /* User interface for generalized channel-oriented file i/o */
  1780. struct keytab fctab[] = { /* FILE subcommands */
  1781.     "close",      FIL_CLS, 0,
  1782.     "count",      FIL_COU, 0,
  1783.     "flush",      FIL_FLU, 0,
  1784.     "list",       FIL_LIS, 0,
  1785.     "open",       FIL_OPN, 0,
  1786.     "read",       FIL_REA, 0,
  1787.     "rewind",     FIL_REW, 0,
  1788.     "seek",       FIL_SEE, 0,
  1789.     "status",     FIL_STA, 0,
  1790.     "write",      FIL_WRI, 0
  1791. };
  1792. int nfctab = (sizeof (fctab) / sizeof (struct keytab));
  1793. static struct keytab fcswtab[] = { /* OPEN modes */
  1794.     "/append",    FM_APP,  0,
  1795.     "/binary",    FM_BIN,  0,
  1796. #ifdef COMMENT
  1797.     "/command",   FM_CMD,  0, /* Not implemented */
  1798. #endif /* COMMENT */
  1799.     "/read",      FM_REA,  0,
  1800.     "/write",     FM_WRI,  0
  1801. };
  1802. static int nfcswtab = (sizeof (fcswtab) / sizeof (struct keytab));
  1803. static struct keytab fclkwtab[] = { /* CLOSE options */
  1804.     "all",        1,       0
  1805. };
  1806. static struct keytab fsekwtab[] = { /* SEEK symbols */
  1807.     "eof",        1,       0,
  1808.     "last",       2,       0
  1809. };
  1810. static int nfsekwtab = (sizeof (fsekwtab) / sizeof (struct keytab));
  1811. #define SEE_LINE  RD_LINE /* SEEK options */
  1812. #define SEE_CHAR  RD_CHAR
  1813. #define SEE_REL   3
  1814. #define SEE_ABS   4
  1815. static struct keytab fskswtab[] = {
  1816.     "/absolute",  SEE_ABS,  0,
  1817.     "/byte",      SEE_CHAR, 0,
  1818.     "/character", SEE_CHAR, CM_INV,
  1819.     "/line",      SEE_LINE, 0,
  1820.     "/relative",  SEE_REL,  0
  1821. };
  1822. static int nfskswtab = (sizeof (fskswtab) / sizeof (struct keytab));
  1823. #define COU_LINE  RD_LINE /* COUNT options */
  1824. #define COU_CHAR  RD_CHAR
  1825. #define COU_LIS   3
  1826. #define COU_NOL   4
  1827. static struct keytab fcoswtab[] = {
  1828.     "/bytes",     COU_CHAR, 0,
  1829.     "/characters",COU_CHAR, CM_INV,
  1830.     "/lines",     COU_LINE, 0,
  1831.     "/list",      COU_LIS,  0,
  1832.     "/nolist",    COU_NOL,  0,
  1833.     "/quiet",     COU_NOL,  CM_INV
  1834. };
  1835. static int nfcoswtab = (sizeof (fcoswtab) / sizeof (struct keytab));
  1836. static struct keytab frdtab[] = { /* READ types */
  1837.     "/block",     RD_SIZE, CM_INV|CM_ARG,
  1838.     "/byte",      RD_CHAR, CM_INV,
  1839.     "/character", RD_CHAR, 0,
  1840.     "/line",      RD_LINE, 0,
  1841.     "/size",      RD_SIZE, CM_ARG
  1842. };
  1843. static int nfrdtab = (sizeof (frdtab) / sizeof (struct keytab));
  1844. static struct keytab fwrtab[] = { /* WRITE types */
  1845.     "/block",     WR_SIZE, CM_INV|CM_ARG,
  1846.     "/byte",      WR_CHAR, CM_INV,
  1847.     "/character", WR_CHAR, 0,
  1848.     "/line",      WR_LINE, 0,
  1849.     "/lpad",      WR_LPAD, CM_ARG,
  1850.     "/rpad",      WR_RPAD, CM_ARG,
  1851.     "/size",      WR_SIZE, CM_ARG,
  1852.     "/string",    WR_STRI, 0
  1853. };
  1854. static int nfwrtab = (sizeof (fwrtab) / sizeof (struct keytab));
  1855. static char blanks[] = "40404040"; /* Some blanks for formatting */
  1856. int
  1857. dofile(op) int op; { /* Do the FILE command */
  1858.     char vnambuf[VNAML]; /* Buffer for variable names */
  1859.     char *vnp = NULL; /* Pointer to same */
  1860.     char zfilnam[CKMAXPATH+2];
  1861.     char * p;
  1862.     struct FDB fl, sw, nu;
  1863.     long z;
  1864.     int rsize, filmode = 0, relative = -1, eofflg = 0;
  1865.     int rc, x, y, cx, n, getval, dummy, confirmed, listing = -1;
  1866.     int charflag = 0, sizeflag = 0;
  1867.     int pad = 32, wr_lpad = 0, wr_rpad = 0;
  1868.     if (op == XXFILE) { /* FILE command was given */
  1869. /* Get subcommand */
  1870. if ((cx = cmkey(fctab,nfctab,"Operation","",xxstring)) < 0) {
  1871.     if (cx == -3) {
  1872. printf("?File operation requiredn");
  1873. x = -9;
  1874.     }
  1875.     return(cx);
  1876. }
  1877.     } else { /* Shorthand command was given */
  1878. switch (op) {
  1879.   case XXF_CL: cx = FIL_CLS; break; /* FCLOSE */
  1880.   case XXF_FL: cx = FIL_FLU; break; /* FFLUSH */
  1881.   case XXF_LI: cx = FIL_LIS; break; /* FLIST */
  1882.   case XXF_OP: cx = FIL_OPN; break; /* etc... */
  1883.   case XXF_RE: cx = FIL_REA; break;
  1884.   case XXF_RW: cx = FIL_REW; break;
  1885.   case XXF_SE: cx = FIL_SEE; break;
  1886.   case XXF_ST: cx = FIL_STA; break;
  1887.   case XXF_WR: cx = FIL_WRI; break;
  1888.   case XXF_CO: cx = FIL_COU; break;
  1889.   default: return(-2);
  1890. }
  1891.     }
  1892.     switch (cx) { /* Do requested subcommand */
  1893.       case FIL_OPN: /* OPEN */
  1894. cmfdbi(&sw, /* Switches */
  1895.        _CMKEY, /* fcode */
  1896.        "Variable or switch", /* hlpmsg */
  1897.        "", /* default */
  1898.        "", /* addtl string data */
  1899.        nfcswtab, /* addtl numeric data 1: tbl size */
  1900.        4, /* addtl numeric data 2: 4 = cmswi */
  1901.        xxstring, /* Processing function */
  1902.        fcswtab, /* Keyword table */
  1903.        &fl /* Pointer to next FDB */
  1904.        );
  1905. cmfdbi(&fl, /* Anything that doesn't match */
  1906.        _CMFLD, /* fcode */
  1907.        "Variable", /* hlpmsg */
  1908.        "",
  1909.        "",
  1910.        0,
  1911.        0,
  1912.        NULL,
  1913.        NULL,
  1914.        NULL
  1915.        );
  1916. while (1) {
  1917.     x = cmfdb(&sw); /* Parse something */
  1918.     if (x < 0) {
  1919. if (x == -3) {
  1920.     printf("?Variable name and file name requiredn");
  1921.     x = -9;
  1922. }
  1923. return(x);
  1924.     }
  1925.     if (cmresult.fcode == _CMFLD)
  1926.       break;
  1927.     else if (cmresult.fcode == _CMKEY) {
  1928. char c;
  1929. c = cmgbrk();
  1930. if ((getval =
  1931.      (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  1932.     printf("?This switch does not take an argumentn");
  1933.     return(-9);
  1934. }
  1935. #ifdef COMMENT
  1936. /* Uncomment if we add any switches ere that take args */
  1937. if (!getval && (cmgkwflgs() & CM_ARG)) {
  1938.     printf("?This switch requires an argumentn");
  1939.     return(-9); /* (none do...) */
  1940. }
  1941. #endif /* COMMENT */
  1942. filmode |= cmresult.nresult; /* OR in the file mode */
  1943.     } else
  1944.       return(-2);
  1945. }
  1946. strcpy(vnambuf,cmresult.sresult); /* Not a switch - get the string */
  1947. if (!vnambuf[0] || chknum(vnambuf)) { /* (if there is one...) */
  1948.     printf("?Variable name requiredn");
  1949.     return(-9);
  1950. }
  1951. vnp = vnambuf; /* Check variable-name syntax */
  1952. if (vnambuf[0] == CMDQ &&
  1953.     (vnambuf[1] == '%' || vnambuf[1] == '&'))
  1954.   vnp++;
  1955. y = 0;
  1956. if (*vnp == '%' || *vnp == '&') {
  1957.     if ((y = parsevar(vnp,&x,&dummy)) < 0) {
  1958. printf("?Syntax error in variable namen");
  1959. return(-9);
  1960.     }
  1961. }
  1962. if (!(filmode & FM_RWA)) /* If no access mode specified */
  1963.   filmode |= FM_REA; /* default to /READ. */
  1964. y = 0; /* Now parse the filename */
  1965. if ((filmode & FM_RWA) == FM_WRI)
  1966.   x = cmofi("Name of new file","",&s,xxstring);
  1967. else if ((filmode & FM_RWA) == FM_REA)
  1968.   x = cmifi("Name of existing file","",&s,&y,xxstring);
  1969. else {
  1970.     x = cmiofi("Filename","",&s,&y,xxstring);
  1971.     debug(F101,"fopen /append x","",x);
  1972. }
  1973. if (x == -9) {
  1974.     if (zchko(s) < 0) {
  1975. printf("Can't create "%s"n",s);
  1976. return(x);
  1977.     }
  1978. } else if (x < 0) {
  1979.     if (x == -3) {
  1980. printf("?Filename requiredn");
  1981. x = -9;
  1982.     }
  1983.     return(x);
  1984. }
  1985. if (y) { /* No wildcards */
  1986.     printf("?Wildcards not allowed heren");
  1987.     return(-9);
  1988. }
  1989. if (filmode & (FM_APP|FM_WRI)) { /* Check output access */
  1990.     if (zchko(s) < 0) {  /* and set error code if denied */
  1991. z_error = FX_ACC;
  1992. printf("?Write access denied - "%s"n",s);
  1993. return(-9);
  1994.     }
  1995. }
  1996. ckstrncpy(zfilnam,s,CKMAXPATH); /* Is OK - make safe copy */
  1997. if ((x = cmcfm()) < 0) /* Get confirmation of command */
  1998.   return(x);
  1999. if ((n = z_open(zfilnam,filmode)) < 0) {
  2000.     printf("?OPEN failed - %s: %sn",zfilnam,ckferror(n));
  2001.     return(-9);
  2002. }
  2003. addmac(vnambuf,ckitoa(n)); /* Assign channel number to variable */
  2004. return(success = 1);
  2005.       case FIL_REW: /* REWIND */
  2006. if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
  2007.     if (x == -3) {
  2008. printf("?Channel number requiredn");
  2009. x = -9;
  2010.     }
  2011.     return(x);
  2012. }
  2013. if ((x = cmcfm()) < 0)
  2014.   return(x);
  2015. if ((rc = z_seek(n,0L)) < 0) {
  2016.     printf("?REWIND failed - Channel %d: %sn",n,ckferror(rc));
  2017.     return(-9);
  2018. }
  2019. return(success = 1);
  2020.       case FIL_CLS: /* CLOSE */
  2021.   cmfdbi(&sw, /* Second FDB - switches */
  2022.  _CMKEY, /* fcode */
  2023.  "Channel number; or keyword",
  2024.  "",
  2025.  "", /* addtl string data */
  2026.  1, /* addtl numeric data 1: tbl size */
  2027.  0, /* addtl numeric data 2: 4 = cmswi */
  2028.  xxstring, /* Processing function */
  2029.  fclkwtab, /* Keyword table */
  2030.  &nu /* Pointer to next FDB */
  2031.  );
  2032.   cmfdbi(&nu, /* First FDB - command switches */
  2033.  _CMNUM, /* fcode */
  2034.  "",
  2035.  "", /* default */
  2036.  "", /* addtl string data */
  2037.  10, /* addtl numeric data 1: radix */
  2038.  0, /* addtl numeric data 2: 0 */
  2039.  xxstring, /* Processing function */
  2040.  NULL, /* Keyword table */
  2041.  NULL /* Pointer to next FDB */
  2042.  ); /*  */
  2043. x = cmfdb(&sw); /* Parse something */
  2044. if (x < 0) {
  2045.     if (x == -3) {
  2046. printf("?Channel number or ALL requiredn");
  2047. x = -9;
  2048.     }
  2049.     return(x);
  2050. }
  2051. if (cmresult.fcode == _CMNUM)
  2052.   n = cmresult.nresult;
  2053. else if (cmresult.fcode == _CMKEY)
  2054.   n = -1;
  2055. if ((x = cmcfm()) < 0)
  2056.   return(x);
  2057. rc = 1;
  2058. if (n < 0) {
  2059.     int count = 0;
  2060.     int i;
  2061.     for (i = 0; i < z_maxchan; i++) {
  2062. x = z_close(i);
  2063. if (x == FX_SYS) {
  2064.     printf("?CLOSE failed - Channel %d: %sn",n,ckferror(x));
  2065.     rc = 0;
  2066. } else if (x > -1)
  2067.   count++;
  2068.     }
  2069.     debug(F101,"FILE CLOSE ALL","",count);
  2070. } else if ((x = z_close(n)) < 0) {
  2071.     printf("?CLOSE failed - Channel %d: %sn",n,ckferror(x));
  2072.     return(-9);
  2073. }
  2074. return(success = rc);
  2075.       case FIL_REA: /* READ */
  2076.       case FIL_WRI: /* WRITE */
  2077. rsize = 0;
  2078. cmfdbi(&sw, /* Switches */
  2079.        _CMKEY, /* fcode */
  2080.        "Channel or switch", /* hlpmsg */
  2081.        "", /* default */
  2082.        "", /* addtl string data */
  2083.        (cx == FIL_REA) ? nfrdtab : nfwrtab,
  2084.        4, /* addtl numeric data 2: 4 = cmswi */
  2085.        xxstring, /* Processing function */
  2086.        (cx == FIL_REA) ? frdtab : fwrtab, /* Keyword table */
  2087.        &nu /* Pointer to next FDB */
  2088.        );
  2089. cmfdbi(&nu, /* Channel number */
  2090.        _CMNUM, /* fcode */
  2091.        "Channel",
  2092.        "", /* default */
  2093.        "", /* addtl string data */
  2094.        10, /* addtl numeric data 1: radix */
  2095.        0, /* addtl numeric data 2: 0 */
  2096.        xxstring, /* Processing function */
  2097.        NULL, /* Keyword table */
  2098.        NULL /* Pointer to next FDB */
  2099.        );
  2100. do {
  2101.     x = cmfdb(&sw); /* Parse something */
  2102.     if (x < 0) {
  2103. if (x == -3) {
  2104.     printf("?Channel number requiredn");
  2105.     x = -9;
  2106. }
  2107. return(x);
  2108.     }
  2109.     if (cmresult.fcode == _CMNUM) /* Channel number */
  2110.       break;
  2111.     else if (cmresult.fcode == _CMKEY) { /* Switch */
  2112. char c;
  2113. c = cmgbrk();
  2114. if ((getval =
  2115.      (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  2116.     printf("?This switch does not take an argumentn");
  2117.     return(-9);
  2118. }
  2119. if (!getval && (cmgkwflgs() & CM_ARG)) {
  2120.     printf("?This switch requires an argumentn");
  2121.     return(-9);
  2122. }
  2123. switch (cmresult.nresult) {
  2124.   case WR_LINE:
  2125.     charflag = 0;
  2126.     sizeflag = 0;
  2127.     rsize = 0;
  2128.     break;
  2129.   case WR_CHAR:
  2130.     rsize = 1;
  2131.     charflag = 1;
  2132.     sizeflag = 1;
  2133.     break;
  2134.   case WR_SIZE:
  2135.     if ((x = cmnum("Bytes","",10,&rsize, xxstring)) < 0) {
  2136. if (x == -3) {
  2137.     printf("?Number requiredn");
  2138.     x = -9;
  2139. }
  2140. return(x);
  2141.     }
  2142.     charflag = 0;
  2143.     sizeflag = 1;
  2144.     break;
  2145.   case WR_STRI:
  2146.     rsize = 1;
  2147.     charflag = 0;
  2148.     sizeflag = 0;
  2149.     break;
  2150.   case WR_LPAD:
  2151.   case WR_RPAD:
  2152.     if ((x = cmnum("Numeric ASCII character value",
  2153.    "32",10,&pad, xxstring)) < 0)
  2154.       return(x);
  2155.     if (cmresult.nresult == WR_LPAD)
  2156.       wr_lpad = 1;
  2157.     else
  2158.       wr_rpad = 1;
  2159.     break;
  2160. }
  2161. debug(F101,"FILE READ rsize 2","",rsize);
  2162.     } else
  2163.       return(-2);
  2164. } while
  2165.   (cmresult.fcode == _CMKEY);
  2166. n = cmresult.nresult; /* Channel */
  2167. debug(F101,"FILE READ/WRITE channel","",n);
  2168. if (cx == FIL_WRI) { /* WRITE */
  2169.     int len = 0;
  2170.     if ((x = cmtxt("Text","",&s,xxstring)) < 0)
  2171.       return(x);
  2172.     strcpy(line,s); /* Make a safe copy */
  2173.     s = line;
  2174.     s = brstrip(s); /* Strip braces */
  2175.     if (charflag) { /* Write one char */
  2176. len = 1; /* So length = 1 */
  2177. rsize = 1; /* Don't supply terminator */
  2178.     } else if (!sizeflag) { /* Write a string */
  2179. len = -1; /* So length is unspecified */
  2180.     } else { /* Write a block of given size */
  2181. int i, k, xx;
  2182. if (rsize > TMPBUFSIZ) {
  2183.     z_error = FX_OFL;
  2184.     printf("?Buffer overflown");
  2185.     return(-9);
  2186. }
  2187. len = rsize; /* rsize is really length */
  2188. rsize = 1; /* Don't supply a terminator */
  2189. xx = strlen(s); /* Size of given string */
  2190. if (xx >= len) { /* Bigger or equal */
  2191.     s[len] = NUL;
  2192. } else if (wr_lpad) { /* Smaller, left-padding requested */
  2193.     for (i = 0; i < len - xx; i++) /* Must make a copy */
  2194.       tmpbuf[i] = pad;
  2195.     strcpy(tmpbuf+i,s);
  2196.     tmpbuf[len] = NUL;
  2197.     s = tmpbuf; /* Redirect write source */
  2198. } else { /* Smaller with right-padding */
  2199.     for (i = xx; i < len; i++)
  2200.       s[i] = pad;
  2201.     s[len] = NUL;
  2202. }
  2203.     }
  2204.     if ((rc = z_out(n,s,len,rsize)) < 0) { /* Try to write */
  2205. printf("?Channel %d WRITE error: %sn",n,ckferror(rc));
  2206. return(-9);
  2207.     }
  2208. } else { /* FIL_REA READ */
  2209.     confirmed = 0;
  2210.     vnambuf[0] = NUL;
  2211.     x = cmfld("Variable name","",&s,NULL);
  2212.     debug(F111,"FILE READ cmfld",s,x);
  2213.     if (x < 0) {
  2214. if (x == -3 || !*s) {
  2215.     if ((x = cmcfm()) < 0)
  2216.       return(x);
  2217.     else
  2218.       confirmed++;
  2219. } else
  2220.   return(x);
  2221.     }
  2222.     strcpy(vnambuf,s);
  2223.     debug(F111,"FILE READ vnambuf",vnambuf,confirmed);
  2224.     if (vnambuf[0]) { /* Variable name given, check it */
  2225. if (!confirmed) {
  2226.     x = cmcfm();
  2227.     if (x < 0)
  2228.       return(x);
  2229.     else
  2230.       confirmed++;
  2231. }
  2232. vnp = vnambuf;
  2233. if (vnambuf[0] == CMDQ &&
  2234.     (vnambuf[1] == '%' || vnambuf[1] == '&'))
  2235.   vnp++;
  2236. y = 0;
  2237. if (*vnp == '%' || *vnp == '&') {
  2238.     if ((y = parsevar(vnp,&x,&dummy)) < 0) {
  2239. printf("?Syntax error in variable namen");
  2240. return(-9);
  2241.     }
  2242. }
  2243.     }
  2244.     debug(F111,"FILE READ variable",vnambuf,confirmed);
  2245.     if (!confirmed)
  2246.       if ((x = cmcfm()) < 0)
  2247. return(x);
  2248.     line[0] = NUL; /* Clear destination buffer */
  2249.     if (rsize >= LINBUFSIZ) /* Don't overrun it */
  2250.       rsize = LINBUFSIZ - 1;
  2251.     if (rsize == 0) /* Read a line */
  2252.       rc = z_in(n,line,LINBUFSIZ,LINBUFSIZ-1,0);
  2253.     else
  2254.       rc = z_in(n,line,LINBUFSIZ,rsize,1); /* Read a block */
  2255.     if (rc < 0) { /* Error... */
  2256. debug(F101,"FILE READ error","",rc);
  2257. debug(F101,"FILE READ errno","",errno);
  2258. if (rc == FX_EOF) { /* EOF - fail but no error message */
  2259.     return(success = 0);
  2260. } else { /* Other error - fail and print msg */
  2261.     printf("?READ error: %sn",ckferror(rc));
  2262.     return(-9);
  2263. }
  2264.     }
  2265.     debug(F110,"FILE READ data",line,0);
  2266.     if (vnambuf[0]) /* Read OK - If variable name given */
  2267.       addmac(vnambuf,line); /* Assign result to variable */
  2268.     else /* otherwise */
  2269.       printf("%sn",line); /* just print it */
  2270. }
  2271. return(success = 1);
  2272.       case FIL_SEE: /* SEEK */
  2273.       case FIL_COU: /* COUNT */
  2274. rsize = RD_CHAR; /* Defaults to /BYTE */
  2275. cmfdbi(&sw, /* Switches */
  2276.        _CMKEY, /* fcode */
  2277.        "Channel or switch", /* hlpmsg */
  2278.        "", /* default */
  2279.        "", /* addtl string data */
  2280.        ((cx == FIL_SEE) ? nfskswtab : nfcoswtab),
  2281.        4, /* addtl numeric data 2: 4 = cmswi */
  2282.        xxstring, /* Processing function */
  2283.        ((cx == FIL_SEE) ? fskswtab : fcoswtab),
  2284.        &nu /* Pointer to next FDB */
  2285.        );
  2286. cmfdbi(&nu, /* Channel number */
  2287.        _CMNUM, /* fcode */
  2288.        "Channel",
  2289.        "", /* default */
  2290.        "", /* addtl string data */
  2291.        10, /* addtl numeric data 1: radix */
  2292.        0, /* addtl numeric data 2: 0 */
  2293.        xxstring, /* Processing function */
  2294.        NULL, /* Keyword table */
  2295.        NULL /* Pointer to next FDB */
  2296.        );
  2297. do {
  2298.     x = cmfdb(&sw); /* Parse something */
  2299.     if (x < 0) {
  2300. if (x == -3) {
  2301.     printf("?Channel number requiredn");
  2302.     x = -9;
  2303. }
  2304. return(x);
  2305.     }
  2306.     if (cmresult.fcode == _CMNUM) /* Channel number */
  2307.       break;
  2308.     else if (cmresult.fcode == _CMKEY) { /* Switch */
  2309. char c;
  2310. c = cmgbrk();
  2311. if ((getval =
  2312.      (c == ':' || c == '=')) && !(cmgkwflgs() & CM_ARG)) {
  2313.     printf("?This switch does not take an argumentn");
  2314.     return(-9);
  2315. }
  2316. if (cx == FIL_SEE) {
  2317.     switch (cmresult.nresult) {
  2318.       case SEE_REL: relative = 1; break;
  2319.       case SEE_ABS: relative = 0; break;
  2320.       default: rsize = cmresult.nresult;
  2321.     }
  2322. } else if (cx == FIL_COU) {
  2323.     switch (cmresult.nresult) {
  2324.       case COU_LIS: listing = 1; break;
  2325.       case COU_NOL: listing = 0; break;
  2326.       default: rsize = cmresult.nresult;
  2327.     }
  2328. }
  2329.     }
  2330. } while
  2331.   (cmresult.fcode == _CMKEY);
  2332. n = cmresult.nresult; /* Channel */
  2333. debug(F101,"FILE SEEK/COUNT channel","",n);
  2334. if (cx == FIL_COU) {
  2335.     if ((x = cmcfm()) < 0)
  2336.       return(x);
  2337.     z_filcount = z_count(n,rsize);
  2338.     if (z_filcount < 0) {
  2339. rc = z_filcount;
  2340. printf("?COUNT error: %sn",ckferror(rc));
  2341. return(-9);
  2342.     }
  2343.     if (listing < 0)
  2344.       listing = !cmdsrc();
  2345.     if (listing)
  2346.       printf(" %ld %s%sn",
  2347.      z_filcount,
  2348.      ((rsize == RD_CHAR) ? "byte" : "line"),
  2349.      ((z_filcount == 1L) ? "" : "s")
  2350.      );
  2351.     return(success = (z_filcount > -1) ? 1 : 0);
  2352. }
  2353. cmfdbi(&sw, /* SEEK symbolic targets (EOF) */
  2354.        _CMKEY, /* fcode */
  2355.        "Channel number;n or keyword",
  2356.        "",
  2357.        "", /* addtl string data */
  2358.        nfsekwtab, /* addtl numeric data 1: table size */
  2359.        0, /* addtl numeric data 2: 4 = cmswi */
  2360.        xxstring, /* Processing function */
  2361.        fsekwtab, /* Keyword table */
  2362.        &nu /* Pointer to next FDB */
  2363.        );
  2364. cmfdbi(&nu, /* Channel number */
  2365.        _CMNUM, /* fcode */
  2366.        "",
  2367.        "", /* default */
  2368.        "", /* addtl string data */
  2369.        10, /* addtl numeric data 1: radix */
  2370.        0, /* addtl numeric data 2: 0 */
  2371.        xxstring, /* Processing function */
  2372.        NULL, /* Keyword table */
  2373.        NULL /* Pointer to next FDB */
  2374.        );
  2375. x = cmfdb(&sw); /* Parse something */
  2376. if (x < 0) {
  2377.     if (x == -3) {
  2378. printf("?Channel number or EOF requiredn");
  2379. x = -9;
  2380.     }
  2381.     return(x);
  2382. }
  2383. if (cmresult.fcode == _CMNUM) {
  2384.     y = cmresult.nresult;
  2385.     debug(F110,"FILE SEEK atmbuf",atmbuf,0);
  2386.     if (relative < 0) {
  2387. if (cx == FIL_SEE && (atmbuf[0] == '+' || atmbuf[0] == '-'))
  2388.   relative = 1;
  2389. else
  2390.   relative = 0;
  2391.     }
  2392. } else if (cmresult.fcode == _CMKEY) {
  2393.     eofflg = cmresult.nresult;
  2394.     relative = 0;
  2395.     y = 0 - eofflg;
  2396. }
  2397. if ((x = cmcfm()) < 0)
  2398.   return(x);
  2399. z = y; /* Convert to long */
  2400. y = 1; /* Recycle this */
  2401. z_flush(n);
  2402. debug(F101,"FILE SEEK relative","",relative);
  2403. debug(F101,"FILE SEEK rsize","",rsize);
  2404. if (rsize == RD_CHAR) { /* Seek to byte position */
  2405.     if (relative) {
  2406. long pos;
  2407. pos = z_getpos(n);
  2408. if (pos < 0L) {
  2409.     rc = pos;
  2410.     printf("?Relative SEEK failed: %sn",ckferror(rc));
  2411.     return(-9);
  2412. }
  2413. z += pos;
  2414.     } else {
  2415. if (z < 0 && !eofflg) { /* Negative arg but not relative */
  2416.     y = 0; /* Remember this was bad */
  2417.     z = 0; /* but substitute 0 */
  2418. }
  2419.     }
  2420.     debug(F101,"FILE SEEK /CHAR z","",z);
  2421.     if (z < 0 && !eofflg) {
  2422. z_error = FX_RNG;
  2423. return(success = 0);
  2424.     }
  2425.     if ((rc = z_seek(n,z)) < 0) {
  2426. if (rc == FX_EOF) return(success = 0);
  2427. printf("?SEEK /BYTE failed - Channel %d: %sn",n,ckferror(rc));
  2428. return(-9);
  2429.     }
  2430. } else { /* Seek to line */
  2431.     if (relative) {
  2432. long pos;
  2433. pos = z_getline(n);
  2434. debug(F101,"FILE SEEK /LINE pos","",pos);
  2435. if (pos < 0L) {
  2436.     rc = pos;
  2437.     printf("?Relative SEEK failed: %sn",ckferror(rc));
  2438.     return(-9);
  2439. }
  2440. z += pos;
  2441.     }
  2442.     debug(F101,"FILE SEEK /LINE z","",z);
  2443.     if (z < 0 && !eofflg) {
  2444. z_error = FX_RNG;
  2445. return(success = 0);
  2446.     }
  2447.     if ((rc = z_line(n,z)) < 0) {
  2448. if (rc == FX_EOF) return(success = 0);
  2449. printf("?SEEK /LINE failed - Channel %d: %sn",n,ckferror(rc));
  2450. return(-9);
  2451.     }
  2452. }
  2453. return(success = y);
  2454.       case FIL_LIS: { /* LIST open files */
  2455. #ifdef CK_TTGWSIZ
  2456.   extern int cmd_rows, cmd_cols;
  2457. #endif /* CK_TTGWSIZ */
  2458.           extern int xaskmore;
  2459.   int i, x, n = 0, paging = 0;
  2460.   char * s;
  2461.   if ((x = cmcfm()) < 0)
  2462.     return(x);
  2463. #ifdef CK_TTGWSIZ
  2464.   if (cmd_rows > 0 && cmd_cols > 0)
  2465. #endif /* CK_TTGWSIZ */
  2466.     paging = xaskmore;
  2467.   printf("System open file limit: %4dn", z_openmax);
  2468.   printf("Maximum for FILE OPEN:  %4dn", z_maxchan);
  2469.   printf("Files currently open:   %4dnn", z_nopen);
  2470.   n = 4;
  2471.   for (i = 0; i < z_maxchan; i++) {
  2472.       s = z_getname(i); /* Got one? */
  2473.       if (s) { /* Yes */
  2474.   char m[8];
  2475.   m[0] = NUL;
  2476.   printf("%2d. %s",i,s); /* Print name */
  2477.   n++;  /* Count it */
  2478.   x = z_getmode(i);  /* Get modes & print them */
  2479.   if (x > -1) {
  2480.       if (x & FM_REA) strcat(m,"R");
  2481.       if (x & FM_WRI) strcat(m,"W");
  2482.       if (x & FM_APP) strcat(m,"A");
  2483.       if (x & FM_BIN) strcat(m,"B");
  2484.       if (m[0])
  2485. printf(" (%s)",m);
  2486.       if (x & FM_EOF)
  2487. printf(" [EOF]");
  2488.       else
  2489. printf(" %ld",z_getpos(i)); /* And file position too */
  2490.   }
  2491.   printf("n");
  2492. #ifdef CK_TTGWSIZ
  2493.   if (paging > 0) { /* Pause at end of screen */
  2494.       if (n > cmd_rows - 3) {
  2495.   if (!askmore())
  2496.     break;
  2497.   else
  2498.     n = 0;
  2499.       }
  2500.   }
  2501. #endif /* CK_TTGWSIZ */
  2502.       }
  2503.   }
  2504.   return(success = 1);
  2505.       }
  2506.       case FIL_FLU: /* FLUSH */
  2507. if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
  2508.     if (x == -3) {
  2509. printf("?Channel number requiredn");
  2510. x = -9;
  2511.     }
  2512.     return(x);
  2513. }
  2514. if ((x = cmcfm()) < 0)
  2515.   return(x);
  2516. if ((rc = z_flush(n)) < 0) {
  2517.     printf("?FLUSH failed - Channel %d: %sn",n,ckferror(rc));
  2518.     return(-9);
  2519. }
  2520. return(success = 1);
  2521.       case FIL_STA: /* STATUS */
  2522. if ((x = cmnum("Channel number","",10,&n, xxstring)) < 0) {
  2523.     if (x == -3) {
  2524. printf("?Channel number requiredn");
  2525. x = -9;
  2526.     }
  2527.     return(x);
  2528. }
  2529. if ((x = cmcfm()) < 0)
  2530.   return(x);
  2531. p = blanks + 3; /* Tricky formatting... */
  2532. if (n < 1000) p--;
  2533. if (n < 100) p--;
  2534. if (n < 10) p--;
  2535. if ((rc = z_getmode(n)) < 0) {
  2536.     printf("Channel %d:%s%sn",n,p,ckferror(rc));
  2537.     return(success = 0);
  2538. } else if (!rc) {
  2539.     printf("Channel %d:%sNot openn",n,p);
  2540.     return(success = 0);
  2541. } else {
  2542.     long xx;
  2543.     s = z_getname(n);
  2544.     if (!s) s = "(name unknown)";
  2545.     printf("Channel %d:%sOpenn",n,p);
  2546.     printf(" File:        %sn Modes:      ",s);
  2547.     if (rc & FM_REA) printf(" /READ");
  2548.     if (rc & FM_WRI) printf(" /WRITE");
  2549.     if (rc & FM_APP) printf(" /APPEND");
  2550.     if (rc & FM_BIN) printf(" /BINARY");
  2551.     if (rc & FM_CMD) printf(" /COMMAND");
  2552.     if (rc & FM_EOF) printf(" [EOF]");
  2553.     printf("n Size:        %ldn",z_count(n,RD_CHAR));
  2554.     printf(" At byte:     %ldn",z_getpos(n));
  2555.     xx = z_getline(n);
  2556.     if (xx > -1)
  2557.       printf(" At line:     %ldn",xx);
  2558.     return(success = 1);
  2559. }
  2560.       default:
  2561. return(-2);
  2562.     }
  2563. }
  2564. #endif /* CKCHANNELIO */
  2565. #ifndef NOSETKEY
  2566. /* Save Key maps and in OS/2 Mouse maps */
  2567. int
  2568. savkeys(name,disp) char * name; int disp; {
  2569.     char *tp;
  2570.     static struct filinfo xx;
  2571.     int savfil, i, j, k;
  2572.     char buf[1024];
  2573.     zclose(ZMFILE);
  2574.     if (disp) {
  2575. xx.bs = 0; xx.cs = 0; xx.rl = 0; xx.org = 0; xx.cc = 0;
  2576. xx.typ = 0; xx.dsp = XYFZ_A; xx.os_specific = '';
  2577. xx.lblopts = 0;
  2578. savfil = zopeno(ZMFILE,name,NULL,&xx);
  2579.     } else savfil = zopeno(ZMFILE,name,NULL,NULL);
  2580.     if (savfil) {
  2581. #ifdef OS2
  2582. ztime(&tp);
  2583. zsout(ZMFILE, "; Kermit 95 SAVE KEYMAP file: ");
  2584. zsoutl(ZMFILE,tp);
  2585. if (mskkeys) {
  2586.     zsoutl(ZMFILE,
  2587.  "if eq "\v(program)" "C-Kermit" set mskermit keycodes on");
  2588. } else {
  2589.     zsoutl(ZMFILE,
  2590.          "if NOT eq "\v(program)" "C-Kermit" stop 1 C-Kermit required.");
  2591.     zsoutl(ZMFILE,"set mskermit keycodes off");
  2592. }
  2593. zsoutl(ZMFILE,"");
  2594. #else /* OS2 */
  2595. ztime(&tp);
  2596. zsout(ZMFILE, "; C-Kermit SAVE KEYMAP file: ");
  2597. zsoutl(ZMFILE,tp);
  2598. #endif /* OS2 */
  2599. zsoutl(ZMFILE,"; Clear previous keyboard mappings ");
  2600. zsoutl(ZMFILE,"set key clear");
  2601. #ifdef OS2
  2602. for (k = 0; k < nttkey; k++) {
  2603.     if (!ttkeytab[k].flgs) {
  2604. sprintf(buf, "set terminal key %s clear", ttkeytab[k].kwd);
  2605. zsoutl(ZMFILE,buf);
  2606.     }
  2607. }
  2608. #endif /* OS2 */
  2609. zsoutl(ZMFILE,"");
  2610. for (i = 0; i < KMSIZE; i++) {
  2611.     if (macrotab[i]) {
  2612. int len = strlen((char *)macrotab[i]);
  2613. #ifdef OS2
  2614. sprintf(buf,"set key \%d ",mskkeys ? cktomsk(i) : i);
  2615. #else /* OS2 */
  2616. sprintf(buf,"set key \%d ",i);
  2617. #endif /* OS2 */
  2618. zsout(ZMFILE,buf);
  2619. for (j = 0; j < len; j++) {
  2620.     char ch = macrotab[i][j];
  2621.     if (ch <= SP || ch >= DEL ||
  2622.  ch == '-' || ch == ',' ||
  2623.                          ch == '{' || ch == '}' ||
  2624.                          ch == ';' || ch == '?' ||
  2625.                          ch == '.' || ch == ''' ||
  2626.                          ch == '\' || ch == '/' ||
  2627.                          ch == '#') {
  2628. sprintf(buf, "\{%d}", ch);
  2629. zsout(ZMFILE,buf);
  2630.     } else {
  2631. sprintf(buf, "%c", ch);
  2632. zsout(ZMFILE,buf);
  2633.     }
  2634. }
  2635. #ifdef OS2
  2636. sprintf(buf, "t; %s", keyname(i));
  2637. zsoutl(ZMFILE,buf);
  2638. #else
  2639. zsoutl(ZMFILE,"");
  2640. #endif /* OS2 */
  2641.     } else if ( keymap[i] != i ) {
  2642. #ifndef NOKVERBS
  2643. if (IS_KVERB(keymap[i])) {
  2644.     for (j = 0; j < nkverbs; j++)
  2645.       if (kverbs[j].kwval == (keymap[i] & ~F_KVERB))
  2646. break;
  2647.     if (j != nkverbs) {
  2648. #ifdef OS2
  2649. sprintf(buf, "set key \%d \K%st; %s",
  2650. mskkeys ? cktomsk(i) : i,
  2651. kverbs[j].kwd, keyname(i)
  2652. );
  2653. zsoutl(ZMFILE,buf);
  2654. #else
  2655. sprintf(buf, "set key \%d \K%s", i, kverbs[j].kwd);
  2656. zsoutl(ZMFILE,buf);
  2657. #endif
  2658.     }
  2659. } else
  2660. #endif /* NOKVERBS */
  2661.   {
  2662. #ifdef OS2
  2663.       sprintf(buf, "set key \%d \{%d}t; %s",
  2664.       mskkeys ? cktomsk(i) : i,
  2665.       keymap[i],
  2666.       keyname(i)
  2667.       );
  2668.       zsoutl(ZMFILE,buf);
  2669. #else
  2670.       sprintf(buf, "set key \%d \{%d}", i, keymap[i]);
  2671.       zsoutl(ZMFILE,buf);
  2672. #endif /* OS2 */
  2673.   }
  2674.     }
  2675. }
  2676. #ifdef OS2
  2677. /* OS/2 also has the SET TERMINAL KEY <termtype> defines */
  2678. for (k = 0; k < nttkey; k++) {
  2679.     extern struct keynode * ttkeymap[];
  2680.     struct keynode * pnode = NULL;
  2681.     if (ttkeytab[k].flgs) /* Don't process CM_INV or CM_ABR */
  2682.       continue;
  2683.     zsoutl(ZMFILE,"");
  2684.     sprintf(buf, "; SET TERMINAL KEY %s", ttkeytab[k].kwd );
  2685.     zsoutl(ZMFILE,buf);
  2686.     for (pnode = ttkeymap[ttkeytab[k].kwval];
  2687.  pnode;
  2688.  pnode = pnode->next
  2689.  ) {
  2690. switch (pnode->def.type) {
  2691.   case key:
  2692.     sprintf(buf, "set terminal key %s \%d \{%d}t; %s",
  2693.               ttkeytab[k].kwd,
  2694.     mskkeys ? cktomsk(pnode->key) : pnode->key,
  2695.     pnode->def.key.scancode,
  2696.     keyname(pnode->key)
  2697.     );
  2698.     zsoutl(ZMFILE,buf);
  2699.     break;
  2700.   case kverb:
  2701.     for (j = 0; j < nkverbs; j++)
  2702.       if (kverbs[j].kwval == (pnode->def.kverb.id & ~F_KVERB))
  2703. break;
  2704.     if (j != nkverbs) {
  2705. sprintf(buf, "set terminal key %s \%d \K%st; %s",
  2706. ttkeytab[k].kwd,
  2707. mskkeys ? cktomsk(pnode->key) : pnode->key,
  2708. kverbs[j].kwd, keyname(pnode->key)
  2709. );
  2710. zsoutl(ZMFILE,buf);
  2711.     }
  2712.     break;
  2713.   case macro: {
  2714.       int len = strlen((char *)pnode->def.macro.string);
  2715.       sprintf(buf,"set terminal key %s \%d ",
  2716.       ttkeytab[k].kwd,
  2717.       mskkeys ? cktomsk(pnode->key) : pnode->key);
  2718.       zsout(ZMFILE,buf);
  2719.       for (j = 0; j < len; j++) {
  2720.   char ch = pnode->def.macro.string[j];
  2721.   if (ch <= SP || ch >= DEL ||
  2722.                                ch == '-' || ch == ',' ||
  2723.                                ch == '{' || ch == '}' ||
  2724.                                ch == ';' || ch == '?' ||
  2725.                                ch == '.' || ch == ''' ||
  2726.                                ch == '\' || ch == '/' ||
  2727.                                ch == '#') {
  2728.       sprintf(buf, "\{%d}", ch);
  2729.       zsout(ZMFILE,buf);
  2730.   } else {
  2731.       sprintf(buf, "%c", ch);
  2732.       zsout(ZMFILE,buf);
  2733.   }
  2734.       }
  2735.       sprintf(buf, "t; %s", keyname(pnode->key));
  2736.       zsoutl(ZMFILE,buf);
  2737.       break;
  2738.   }
  2739.   case literal: {
  2740.       int len = strlen((char *)pnode->def.literal.string);
  2741.       sprintf(buf,"set terminal key %s /literal \%d ",
  2742.       ttkeytab[k].kwd,
  2743.       mskkeys ? cktomsk(pnode->key) : pnode->key);
  2744.       zsout(ZMFILE,buf);
  2745.       for (j = 0; j < len; j++) {
  2746.   char ch = pnode->def.literal.string[j];
  2747.   if (ch <= SP || ch >= DEL ||
  2748.                                ch == '-' || ch == ',' ||
  2749.                                ch == '{' || ch == '}' ||
  2750.                                ch == ';' || ch == '?' ||
  2751.                                ch == '.' || ch == ''' ||
  2752.                                ch == '\' || ch == '/' ||
  2753.                                ch == '#') {
  2754.       sprintf(buf, "\{%d}", ch);
  2755.       zsout(ZMFILE,buf);
  2756.   } else {
  2757.       sprintf(buf, "%c", ch);
  2758.       zsout(ZMFILE,buf);
  2759.   }
  2760.       }
  2761.       sprintf(buf, "t; %s", keyname(pnode->key));
  2762.       zsoutl(ZMFILE,buf);
  2763.       break;
  2764.   }
  2765.   case esc:
  2766.     sprintf(buf,
  2767.        "set terminal key %s /literal \%d \{%d}\{%d}t; %s",
  2768.     ttkeytab[k].kwd,
  2769.     mskkeys ? cktomsk(pnode->key) : pnode->key,
  2770.     ISDG200(ttkeytab[k].kwval) ? 30 : 27,
  2771.     pnode->def.esc.key & ~F_ESC,
  2772.     keyname(pnode->key)
  2773.     );
  2774.     zsoutl(ZMFILE,buf);
  2775.     break;
  2776.   case csi:
  2777.     sprintf(buf,
  2778.        "set terminal key %s /literal \%d \{27}[\{%d}t; %s",
  2779.     ttkeytab[k].kwd,
  2780.     mskkeys ? cktomsk(pnode->key) : pnode->key,
  2781.     pnode->def.csi.key & ~F_CSI,
  2782.     keyname(pnode->key)
  2783.     );
  2784.     zsoutl(ZMFILE,buf);
  2785.     break;
  2786.   default:
  2787.     continue;
  2788. }
  2789.     }
  2790. }
  2791. #endif /* OS2 */
  2792. zsoutl(ZMFILE,"");
  2793. zsoutl(ZMFILE,"; End");
  2794. zclose(ZMFILE);
  2795. return(success = 1);
  2796.     } else {
  2797. return(success = 0);
  2798.     }
  2799. }
  2800. #endif /* NOSETKEY */
  2801. #ifdef OS2
  2802. struct keytab cmdtrmopt[] = {
  2803.     "scrollback", 0, 0
  2804. };
  2805. _PROTOTYP(int savscrbk, (int, char *, int));
  2806. #endif /* OS2 */
  2807. int
  2808. dosave(xx) int xx; {
  2809.     int x, y, disp;
  2810.     char * s = NULL;
  2811.     extern struct keytab disptb[];
  2812. #ifdef ZFNQFP
  2813.     struct zfnfp * fnp;
  2814. #endif /* ZFNQFP */
  2815.     switch (xx) {
  2816. #ifdef OS2
  2817.     case XSCMD:
  2818.     case XSTERM:
  2819. if ((y = cmkey(cmdtrmopt,1,"What to save","scrollback",xxstring)) < 0)
  2820.   return(y);
  2821. z = cmofi("Name of Scrollback file","scrollbk.txt",&s,xxstring);
  2822. if (z < 0) return(z);
  2823. if (z == 2) {
  2824.     printf("?Sorry, %s is a directory namen",s);
  2825.     return(-9);
  2826. }
  2827. #ifdef ZFNQFP
  2828. if (fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf)) {
  2829.     if (fnp->fpath)
  2830. if ((int) strlen(fnp->fpath) > 0)
  2831.   s = fnp->fpath;
  2832. }
  2833. #endif /* ZFNQFP */
  2834. strcpy(line,s);
  2835. s = line;
  2836. #ifdef MAC
  2837. z = 0;
  2838. #else
  2839. if ((z = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
  2840.   return(z);
  2841. #endif /* MAC */
  2842. disp = z;
  2843. if ((x = cmcfm()) < 0) return(x);
  2844.         switch (xx) {
  2845.   case XSCMD:
  2846.             return(success = savscrbk(VCMD,s,disp));
  2847.   case XSTERM:
  2848.             return(success = savscrbk(VTERM,s,disp));
  2849.   default:
  2850.             return(success = 0);
  2851.         }
  2852. #endif /* OS2 */
  2853. #ifndef NOSETKEY
  2854.       case XSKEY:
  2855. y = cmofi("Name of Kermit command file","keymap.ksc",&s,xxstring);
  2856. if (y < 0) return(y);
  2857. if (y == 2) {
  2858.     printf("?Sorry, %s is a directory namen",s);
  2859.     return(-9);
  2860. }
  2861. #ifdef ZFNQFP
  2862. if (fnp = zfnqfp(s,TMPBUFSIZ - 1,tmpbuf)) {
  2863.     if (fnp->fpath)
  2864. if ((int) strlen(fnp->fpath) > 0)
  2865.   s = fnp->fpath;
  2866. }
  2867. #endif /* ZFNQFP */
  2868. strcpy(line,s);
  2869. s = line;
  2870. #ifdef MAC
  2871. y = 0;
  2872. #else
  2873. if ((y = cmkey(disptb,2,"Disposition","new",xxstring)) < 0)
  2874.   return(y);
  2875. #endif /* MAC */
  2876. disp = y;
  2877. if ((x = cmcfm()) < 0) return(x);
  2878. return (savkeys(s,disp));
  2879. #endif /* NOSETKEY */
  2880.       default:
  2881. if ((x = cmcfm()) < 0) return(x);
  2882. printf("Not implemented - %sn",cmdbuf);
  2883. return(success = 0);
  2884.     }
  2885. }
  2886. /*
  2887.   R E A D T E X T
  2888.   Read text with a custom prompt into given buffer using command parser but
  2889.   with no echoing or entry into recall buffer.
  2890. */
  2891. int
  2892. readtext(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
  2893. #ifdef CK_RECALL
  2894.     int sv_recall; /* For turning off command recall */
  2895.     extern int on_recall; /* around Password prompting */
  2896. #endif /* CK_RECALL */
  2897.     int rc;
  2898. #ifdef OS2
  2899.     extern int vmode;
  2900.     int vmode_sav = vmode;
  2901.     if (win95_popup
  2902. #ifdef IKSD
  2903.          && !inserver
  2904. #endif /* IKSD */
  2905.          )
  2906.       return(popup_readtext(vmode,prmpt,buffer,bufsiz,0));
  2907.     if (vmode == VTERM) {
  2908.         vmode = VCMD;
  2909.         VscrnIsDirty(VTERM);
  2910.         VscrnIsDirty(VCMD);
  2911.     }
  2912. #endif /* OS2 */
  2913. #ifdef CK_RECALL
  2914.     sv_recall = on_recall; /* Save and turn off command recall */
  2915.     on_recall = 0;
  2916. #endif /* CK_RECALL */
  2917.     cmsavp(psave,PROMPTL); /* Save old prompt */
  2918.     cmsetp(prmpt); /* Make new prompt */
  2919.     concb((char)escape); /* Put console in cbreak mode */
  2920.     cmini(1); /* and echo mode */
  2921.     if (pflag) prompt(xxstring); /* Issue prompt if at top level */
  2922.     cmres(); /* Reset the parser */
  2923.     for (rc = -1; rc < 0; ) { /* Prompt till they answer */
  2924.         rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
  2925.         cmres(); /* Reset the parser again */
  2926.     }
  2927.     ckstrncpy(buffer,s,bufsiz);
  2928. #ifdef CK_RECALL
  2929.     on_recall = sv_recall; /* Restore command recall */
  2930. #endif /* CK_RECALL */
  2931.     cmsetp(psave); /* Restore original prompt */
  2932. #ifdef OS2
  2933.     if (vmode != vmode_sav) {
  2934.         vmode = VTERM;
  2935.         VscrnIsDirty(VCMD);
  2936.         VscrnIsDirty(VTERM);
  2937.     }
  2938. #endif /* OS2 */
  2939.     return(0);
  2940. }
  2941. #endif /* NOICP */
  2942. /* A general function to allow a Password or other information  */
  2943. /* to be read from the command prompt without it going into     */
  2944. /* the recall buffer or being echo'd.                           */
  2945. int
  2946. readpass(prmpt, buffer, bufsiz) char * prmpt; char * buffer; int bufsiz; {
  2947. #ifdef NOICP
  2948.     printf("%s", prmpt);
  2949.     gets(buffer);
  2950.     return(1);
  2951. #else  /* NOICP */
  2952. #ifdef CK_RECALL
  2953.     int sv_recall; /* For turning off command recall */
  2954.     extern int on_recall; /* around Password prompting */
  2955. #endif /* CK_RECALL */
  2956.     int rc;
  2957. #ifdef OS2
  2958.     extern int vmode;
  2959.     int vmode_sav = vmode;
  2960. #endif /* OS2 */
  2961. #ifdef CKSYSLOG
  2962.     int savlog;
  2963. #endif /* CKSYSLOG */
  2964. #ifdef OS2
  2965.     if (win95_popup
  2966. #ifdef IKSD
  2967.          && !inserver
  2968. #endif /* IKSD */
  2969.          )
  2970.       return(popup_readpass(vmode,prmpt,buffer,bufsiz,0));
  2971. #endif /* OS2 */
  2972. #ifdef CKSYSLOG
  2973.     savlog = ckxsyslog; /* Save and turn off syslogging */
  2974.     ckxsyslog = 0;
  2975. #endif /* CKSYSLOG */
  2976. #ifdef OS2
  2977.     if (vmode == VTERM) {
  2978.         vmode = VCMD;
  2979.         VscrnIsDirty(VTERM);
  2980.         VscrnIsDirty(VCMD);
  2981.     }
  2982. #endif /* OS2 */
  2983. #ifdef CK_RECALL
  2984.     sv_recall = on_recall; /* Save and turn off command recall */
  2985.     on_recall = 0;
  2986. #endif /* CK_RECALL */
  2987.     cmsavp(psave,PROMPTL); /* Save old prompt */
  2988.     cmsetp(prmpt); /* Make new prompt */
  2989.     concb((char)escape); /* Put console in cbreak mode */
  2990.     cmini(0); /* and no-echo mode */
  2991.     if (pflag) prompt(xxstring); /* Issue prompt if at top level */
  2992.     cmres(); /* Reset the parser */
  2993.     for (rc = -1; rc < 0; ) { /* Prompt till they answer */
  2994.         rc = cmtxt("","",&s,NULL); /* Get a literal line of text */
  2995.         cmres(); /* Reset the parser again */
  2996.     }
  2997.     ckstrncpy(buffer,s,bufsiz);
  2998. #ifdef CK_RECALL
  2999.     on_recall = sv_recall; /* Restore command recall */
  3000. #endif /* CK_RECALL */
  3001.     printf("rn"); /* Echo a CRLF */
  3002.     cmsetp(psave); /* Restore original prompt */
  3003.     cmini(1); /* Restore echo mode */
  3004. #ifdef OS2
  3005.     if (vmode != vmode_sav) {
  3006.         vmode = VTERM;
  3007.         VscrnIsDirty(VCMD);
  3008.         VscrnIsDirty(VTERM);
  3009.     }
  3010. #endif /* OS2 */
  3011. #ifdef CKSYSLOG
  3012.     ckxsyslog = savlog; /* Restore syslogging */
  3013. #endif /* CKSYSLOG */
  3014.     return(0);
  3015. #endif /* NOICP */
  3016. }
  3017. #ifndef NOICP
  3018. struct keytab authtab[] = { /* Available authentication types */
  3019. #ifdef CK_KERBEROS
  3020.     "k4",        AUTH_KRB4, CM_INV,
  3021.     "k5",        AUTH_KRB5, CM_INV,
  3022.     "kerberos4", AUTH_KRB4, 0,
  3023.     "kerberos5", AUTH_KRB5, 0,
  3024.     "krb4",      AUTH_KRB4, CM_INV,
  3025.     "krb5",      AUTH_KRB5, CM_INV,
  3026. #endif /* CK_KERBEROS */
  3027. #ifdef NT
  3028.     "ntlm",      AUTH_NTLM, 0,
  3029. #endif /* NT */
  3030. #ifdef CK_SRP
  3031.     "srp",       AUTH_SRP,  0,
  3032. #endif /* CK_SRP */
  3033. #ifdef CK_SSL
  3034.     "ssl",       AUTH_SSL,  0,
  3035. #endif /* CK_SSL */
  3036.     "",         0,      0
  3037. };
  3038. int authtabn = sizeof(authtab)/sizeof(struct keytab)-1;
  3039. #ifdef CK_KERBEROS
  3040. struct keytab kerbtab[] = { /* Kerberos authentication types */
  3041.     "k4",        AUTH_KRB4, CM_INV,
  3042.     "k5",        AUTH_KRB5, CM_INV,
  3043.     "kerberos4", AUTH_KRB4, 0,
  3044.     "kerberos5", AUTH_KRB5, 0,
  3045.     "krb4",      AUTH_KRB4, CM_INV,
  3046.     "krb5",      AUTH_KRB5, CM_INV
  3047. };
  3048. int kerbtabn = sizeof(kerbtab)/sizeof(struct keytab);
  3049. static struct keytab krb_s_tbl[] = { /* AUTHENTICATE command switches: */
  3050.     "/cache",   KRB_S_CA, CM_ARG
  3051. };
  3052. static int krb_s_n = sizeof(krb_s_tbl)/sizeof(struct keytab);
  3053. static struct keytab krb_v_tbl[] = { /* KERBEROS version values: */
  3054.     "4",    4, 0,
  3055.     "5",    5, 0, /* (add others as needed...) */
  3056.     "auto", 0, 0 /* Note: 0 = auto */
  3057. };
  3058. static int krb_v_n = sizeof(krb_v_tbl)/sizeof(struct keytab);
  3059. static struct keytab krb_a_tbl[] = { /* KERBEROS actions: */
  3060.     "destroy",           KRB_A_DE, 0,
  3061.     "initialize",        KRB_A_IN, 0,
  3062.     "list-credentials",  KRB_A_LC, 0
  3063. };
  3064. static int krb_a_n = sizeof(krb_a_tbl)/sizeof(struct keytab);
  3065. static struct keytab krb4_i_tbl[] = { /* KERBEROS 4 INITIALIZE switches: */
  3066.     "/brief",            KRB_I_BR, 0,      /* /BRIEF       */
  3067.     "/instance",         KRB_I_IN, CM_ARG, /* /INSTANCE:   */
  3068.     "/lifetime",         KRB_I_LF, CM_ARG, /* /LIFETIME:   */
  3069.     "/not-preauth",      KRB_I_NPA, 0,     /* /NOT-PREAUTH */
  3070.     "/password",         KRB_I_PW, CM_ARG, /* /PASSWORD:   */
  3071. #ifdef OS2
  3072.     "/popup",            KRB_I_POP, 0,     /* /POPUP       */
  3073. #endif /* OS2 */
  3074.     "/preauth",          KRB_I_PA, 0,      /* /PREAUTH     */
  3075.     "/realm",            KRB_I_RL, CM_ARG, /* /REALM:      */
  3076.     "/verbose",          KRB_I_VB, 0,      /* /VERBOSE     */
  3077.     "", 0, 0
  3078. };
  3079. static int krb4_i_n = sizeof(krb4_i_tbl)/sizeof(struct keytab) - 1;
  3080. static struct keytab krb5_i_tbl[] = { /* KERBEROS 5 INITIALIZE switches: */
  3081.     "/addresses",        KRB_I_ADR, CM_ARG,
  3082.     "/forwardable",      KRB_I_FW,  0,    /* /FORWARDABLE */
  3083.     "/instance",         KRB_I_IN, CM_ARG, /* /INSTANCE:   */
  3084.     "/k4",               KRB_I_K4,  CM_INV, /* /KERBEROS4   */
  3085.     "/kerberos4",        KRB_I_K4,  0,      /* /KERBEROS4   */
  3086.     "/krb4",             KRB_I_K4,  CM_INV, /* /KERBEROS4   */
  3087.     "/lifetime",         KRB_I_LF,  CM_ARG, /* /LIFETIME:   */
  3088.     "/no-k4",            KRB_I_NK4, CM_INV,/* /NO-KERBEROS4 */
  3089.     "/no-kerberos4",     KRB_I_NK4, 0,     /* /NO-KERBEROS4 */
  3090.     "/no-krb4",          KRB_I_NK4, CM_INV,/* /NO-KERBEROS4 */
  3091.     "/not-forwardable",  KRB_I_NFW, 0,    /* /NOT-FORWARDABLE */
  3092.     "/not-proxiable",    KRB_I_NPR, 0,     /* /NOT-PROXIABLE   */
  3093.     "/password",         KRB_I_PW,  CM_ARG, /* /PASSWORD:   */
  3094. #ifdef OS2
  3095.     "/popup",            KRB_I_POP, 0,     /* /POPUP       */
  3096. #endif /* OS2 */
  3097.     "/postdate",         KRB_I_PD, CM_ARG, /* /POSTDATE:   */
  3098.     "/pr",               KRB_I_PR, CM_INV|CM_ABR, /* to allow for */
  3099.     "/pro",              KRB_I_PR, CM_INV|CM_ABR, /* different spellings */
  3100.     "/prox",             KRB_I_PR, CM_INV|CM_ABR,
  3101.     "/proxiable",        KRB_I_PR, 0,      /* /PROXIABLE   */
  3102.     "/proxyable",        KRB_I_PR, CM_INV, /* /PROXYABLE   */
  3103.     "/realm",            KRB_I_RL, CM_ARG, /* /REALM:      */
  3104.     "/renew",            KRB_I_RN, 0,    /* /RENEW       */
  3105.     "/renewable",        KRB_I_RB, CM_ARG, /* /RENEWABLE:  */
  3106.     "/service",          KRB_I_SR, CM_ARG, /* /SERVICE:    */
  3107.     "/validate",         KRB_I_VA, 0,     /* /VALIDATE    */
  3108.     "", 0, 0
  3109. };
  3110. static int krb5_i_n = sizeof(krb5_i_tbl)/sizeof(struct keytab) - 1;
  3111. static struct keytab klctab[] = { /* List Credentials switches*/
  3112.     "/addresses",  XYKLCAD, 0,
  3113.     "/encryption", XYKLCEN, 0,
  3114.     "/flags",      XYKLCFL, 0
  3115. };
  3116. static int nklctab = sizeof(klctab)/sizeof(struct keytab);
  3117. extern int krb_action;
  3118. extern struct krb_op_data krb_op;
  3119. extern struct krb5_list_cred_data krb5_lc;
  3120. extern struct krb5_init_data krb5_init;
  3121. extern char * krb5_d_principal; /* Default principal */
  3122. extern char * krb5_d_instance;
  3123. extern char * krb5_d_realm; /* Default realm */
  3124. extern char * krb5_d_cc; /* Default credentials cache */
  3125. extern char * krb5_d_srv;               /* Default service name */
  3126. extern int    krb5_d_lifetime;          /* Default lifetime */
  3127. extern int    krb5_d_forwardable;
  3128. extern int    krb5_d_proxiable;
  3129. extern int    krb5_d_renewable;
  3130. extern int    krb5_autoget;
  3131. extern int    krb5_autodel;
  3132. extern int    krb5_d_getk4;
  3133. extern int    krb5_checkaddrs;
  3134. extern struct krb4_init_data krb4_init;
  3135. extern char * krb4_d_principal; /* Default principal */
  3136. extern char * krb4_d_realm; /* Default realm */
  3137. extern char * krb4_d_srv;               /* Default service name */
  3138. extern int    krb4_d_lifetime;          /* Default lifetime */
  3139. extern int    krb4_d_preauth;
  3140. extern char * krb4_d_instance;
  3141. extern int    krb4_autoget;
  3142. extern int    krb4_autodel;
  3143. extern int    krb4_checkaddrs;
  3144. #endif /* CK_KERBEROS */
  3145. #ifndef NOSHOW
  3146. #ifdef CK_AUTHENTICATION
  3147. int
  3148. sho_auth(cx) int cx; {
  3149.     extern int auth_type_user[];
  3150.     int i;
  3151.     char * p;
  3152.     int kv = 0, all = 0;
  3153. #ifdef IKSD
  3154.     if (inserver) {
  3155.         printf("?Sorry, command disabled.rn");
  3156.         return(success = 0);
  3157.     }
  3158. #endif /* IKSD */
  3159.     if (cx) {
  3160.         kv = cx;
  3161.     } else if (auth_type_user[0] != AUTHTYPE_AUTO) {
  3162.         kv = auth_type_user[0];
  3163.     } else {
  3164.         all = 1;
  3165.         kv = AUTHTYPE_KERBEROS_V4;
  3166.     }
  3167.     while (kv) {
  3168.         switch (kv) {
  3169.   case AUTHTYPE_KERBEROS_V4:
  3170.             kv = all ? AUTHTYPE_KERBEROS_V5 : 0;
  3171.             if (ck_krb4_is_installed())
  3172.       printf(" Authentication:      Kerberos 4n");
  3173.             else {
  3174.                 printf(" Authentication:      Kerberos 4 (not installed)n");
  3175.                 continue;
  3176.             }
  3177. #ifdef CK_KERBEROS
  3178.             if (krb_action < 0) {
  3179.                 p = "(none)";
  3180.             } else {
  3181.                 for (p = "", i = 0; i < krb_a_n; i++) {
  3182.                     if (krb_action == krb_a_tbl[i].kwval) {
  3183.                         p = krb_a_tbl[i].kwd;
  3184.                         break;
  3185.                     }
  3186.                 }
  3187.             }
  3188.             printf(" Action:              %sn", p);
  3189.             printf(" Default lifetime     %dn",krb4_d_lifetime);
  3190.             printf(" Lifetime:            %d (minutes)n",krb4_init.lifetime);
  3191.             printf(" Default preauth:     %dn",krb4_d_preauth);
  3192.             printf(" Preauth:             %dn",krb4_init.preauth);
  3193.             printf(" Default principal:   "%s"n",
  3194.                     krb4_d_principal ? krb4_d_principal : "");
  3195.             printf(" Principal:           "%s"n",
  3196.                     krb4_init.principal ? krb4_init.principal : "");
  3197.             printf(" Default realm:       "%s"n",
  3198.                     krb4_d_realm ? krb4_d_realm : "");
  3199.             printf(" Realm:               "%s"n",
  3200.                     krb4_init.realm ? krb4_init.realm : "");
  3201.             printf(" Default instance:    "%s"n",
  3202.                     krb4_d_instance ? krb4_d_instance : "");
  3203.             printf(" Instance:            "%s"n",
  3204.                     krb4_init.instance ? krb4_init.instance : "");
  3205.             printf(" Auto-Get TGTs:       %dn",krb4_autoget);
  3206.             printf(" Auto-Destroy TGTs:   %sn",
  3207.                     krb4_autodel==KRB_DEL_NO?"never":
  3208.                     krb4_autodel==KRB_DEL_CL?"on-close":"on-exit");
  3209.             printf(" Check IP Addresses:  %dn",krb4_checkaddrs);
  3210. #ifdef COMMENT
  3211.             printf(" Password:    "%s"n",
  3212.                     krb4_init.password  ? krb4_init.password  : "");
  3213. #endif /* COMMENT */
  3214. #endif /* CK_KERBEROS */
  3215.             printf("n");
  3216.             break;
  3217.   case AUTHTYPE_KERBEROS_V5:
  3218.             kv = all ? AUTHTYPE_SSL : 0;
  3219.             if (ck_krb5_is_installed())
  3220.       printf(" Authentication:      Kerberos 5n");
  3221.             else {
  3222.                 printf(" Authentication:      Kerberos 5 (not installed)n");
  3223.                 continue;
  3224.             }
  3225. #ifdef CK_KERBEROS
  3226.             printf(" Cache file:          %sn",
  3227.                     krb_op.cache ? krb_op.cache : "(none)");
  3228.             printf(" Default cache:       %sn",
  3229.                     krb5_d_cc ? krb5_d_cc : "(none)");
  3230.             if (krb_action < 0) {
  3231.                 p = "(none)";
  3232.             } else  {
  3233.                 for (p = "", i = 0; i < krb_a_n; i++) {
  3234.                     if (krb_action == krb_a_tbl[i].kwval) {
  3235.                         p = krb_a_tbl[i].kwd;
  3236.                         break;
  3237.                     }
  3238.                 }
  3239.             }
  3240.             printf(" Action:              %sn", p);
  3241.             printf(" Default forwardable  %dn",krb5_d_forwardable);
  3242.             printf(" Forwardable:         %dn",krb5_init.forwardable);
  3243.             printf(" Default lifetime     %dn",krb5_d_lifetime);
  3244.             printf(" Lifetime:            %d (minutes)n",krb5_init.lifetime);
  3245.             printf(" Postdate:            "%s"n",
  3246.                     krb5_init.postdate ? krb5_init.postdate: "");
  3247.             printf(" Default proxiable:   %dn",krb5_d_proxiable);
  3248.             printf(" Proxiable:           %dn",krb5_init.proxiable);
  3249.             printf(" Renew:               %dn",krb5_init.renew);
  3250.             printf(" Default renewable:   %d (minutes)n",krb5_d_renewable);
  3251.             printf(" Renewable:           %d (minutes)n",krb5_init.renewable);
  3252.             printf(" Service:             "%s"n",
  3253.                     krb5_init.service ? krb5_init.service : "");
  3254.             printf(" Validate:            %dn",krb5_init.validate);
  3255.             printf(" Default principal:   "%s"n",
  3256.                     krb5_d_principal ? krb5_d_principal : "");
  3257.             printf(" Principal:           "%s"n",
  3258.                     krb5_init.principal ? krb5_init.principal : "");
  3259.             printf(" Default instance:    "%s"n",
  3260.                     krb5_d_instance ? krb5_d_instance : "");
  3261.             printf(" Default realm:       "%s"n",
  3262.                     krb5_d_realm ? krb5_d_realm : "");
  3263.             printf(" Realm:               "%s"n",
  3264.                     krb5_init.realm ? krb5_init.realm : "");
  3265.             printf(" Auto-Get TGTs:       %dn",krb5_autoget);
  3266.             printf(" Auto-Destroy TGTs:   %sn",
  3267.                     krb5_autodel==KRB_DEL_NO?"never":
  3268.                     krb5_autodel==KRB_DEL_CL?"on-close":"on-exit");
  3269.             printf(" Default get K4 TGTs: %dn",krb5_d_getk4);
  3270.             printf(" Get K4 TGTs: %dn",krb5_init.getk4);
  3271.             printf(" Check IP Addresses:  %dn",krb5_checkaddrs);
  3272.             printf(" IP-Addresses:        ");
  3273.             if (krb5_init.addrs) {
  3274.                 for (i = 0; krb5_init.addrs[i]; i++) {
  3275.                     if (i)
  3276.       printf(",");
  3277.                     printf("%s",krb5_init.addrs[i]);
  3278.                 }
  3279.                 printf("n");
  3280.             } else
  3281.       printf("(use default)n");
  3282. #ifdef COMMENT
  3283.             printf(" Password:            "%s"n",
  3284.                     krb5_init.password  ? krb5_init.password  : "");
  3285. #endif /* COMMENT */
  3286. #endif /* CK_KERBEROS */
  3287.             printf("n");
  3288.             break;
  3289.   case AUTHTYPE_SSL:
  3290.             kv = 0;
  3291.             if (ck_ssleay_is_installed())
  3292.       printf(" Authentication:      SSL/TLSn");
  3293.             else {
  3294.                 printf(" Authentication:      SSL/TLS (not installed)n");
  3295.                 continue;
  3296.             }
  3297. #ifdef CK_SSL
  3298.             printf(" RSA Certs file: %sn",ssl_rsa_cert_file?
  3299.                   ssl_rsa_cert_file:"(none)");
  3300.             printf(" RSA Key file: %sn",ssl_rsa_key_file?
  3301.                   ssl_rsa_key_file:"(none)");
  3302.             printf(" DSA Certs file: %sn",ssl_dsa_cert_file?
  3303.                   ssl_dsa_cert_file:"(none)");
  3304.             printf(" DH Key file: %sn",ssl_dh_key_file?
  3305.                   ssl_dh_key_file:"(none)");
  3306.             printf(" DH Param file: %sn",ssl_dh_param_file?
  3307.                   ssl_dh_param_file:"(none)");
  3308.             printf(" CRL file: %sn",ssl_crl_file?
  3309.                   ssl_crl_file:"(none)");
  3310.             printf(" CRL dir: %sn",ssl_crl_dir?
  3311.                     ssl_crl_dir:"(none)");
  3312.             printf(" Verify file: %sn",ssl_verify_file?
  3313.                   ssl_verify_file:"(none)");
  3314.             printf(" Verify dir: %sn",ssl_verify_dir?
  3315.                   ssl_verify_dir:"(none)");
  3316.             printf(" Cipher list:n");
  3317.     if (ssl_con == NULL) {
  3318. SSL_library_init();
  3319. ssl_ctx = (SSL_CTX *)
  3320.   SSL_CTX_new((SSL_METHOD *)TLSv1_method());
  3321. if (ssl_ctx != NULL)
  3322.   ssl_con= (SSL *) SSL_new(ssl_ctx);
  3323.     }
  3324.     if (ssl_con != NULL) {
  3325. CHAR * p = NULL;
  3326. int i;
  3327. for (i = 0; ; i++) {
  3328.     p = (CHAR *) SSL_get_cipher_list(ssl_con,i);
  3329.     if (p == NULL)
  3330.       break;
  3331.     printf("    %sn",p);
  3332. }
  3333.     }
  3334.             printf(" Certs OK? %sn",ssl_certsok_flag? "yes" : "no");
  3335.             printf(" Debug mode: %sn", ssl_debug_flag ? "on" : "off");
  3336.             printf(" Verbose mode: %sn", ssl_verbose_flag ? "on" : "off");
  3337.             printf(" Verify mode: %sn",
  3338.                     ssl_verify_flag == SSL_VERIFY_NONE ? "none" :
  3339.                     ssl_verify_flag == SSL_VERIFY_PEER ? "peer-cert" :
  3340.                     "fail-if-no-peer-cert");
  3341.             printf(" SSL only? %sn", ssl_only_flag ? "yes" : "no");
  3342.             printf(" TLS only? %sn", tls_only_flag ? "yes" : "no");
  3343. #endif /* CK_SSL */
  3344.             break;
  3345.   case AUTHTYPE_NTLM:
  3346.             kv = 0;
  3347.             if (ck_ntlm_is_installed()) {
  3348.                 printf(" Authentication:      NTLMn");
  3349.                 printf(" No optionsn");
  3350.             } else {
  3351.                 printf(" Authentication:      NTLM (not installed)n");
  3352.                 continue;
  3353.             }
  3354.             printf("n");
  3355.             break;
  3356.   case AUTHTYPE_SRP:
  3357.             kv = 0;
  3358.             if (ck_srp_is_installed()) {
  3359.                 printf(" Authentication:      SRPn");
  3360.                 printf(" No optionsn");
  3361.             } else {
  3362.                 printf(" Authentication:      SRP (not installed)n");
  3363.                 continue;
  3364.             }
  3365.             printf("n");
  3366.             break;
  3367.         }
  3368.     }
  3369.     return(success = 1);
  3370. }
  3371. #endif /* CK_AUTHENTICATION */
  3372. #endif /* NOSHOW */
  3373. #ifdef CK_KERBEROS
  3374. /*  C P _ A U T H  --  AUTHENTICATE command parsing  */
  3375. int
  3376. cp_auth() { /* Command_Parse AUTHENTICATE */
  3377.     int c, i, n; /* Workers */
  3378.     int rc = 0; /* Return code */
  3379.     int getval; /* Parsing helpers */
  3380.     int tmpauth = 0; /* Temporary authentication type */
  3381.     int kv = 0; /* Temporary Kerberos version */
  3382.     int tmp_action = -1; /* Temporary Kerberos action */
  3383.     int tmp_klc = 0; /* Temporary list-credentials */
  3384.     char tmphlp[256]; /* For building help message */
  3385.     char * p;
  3386.     char * tmppswd  = NULL; /* Password */
  3387.     char * tmpprinz = NULL; /* Principal */
  3388.     char * tmprealm = NULL;             /* Realm */
  3389.     char * tmpcache = NULL; /* Cache file */
  3390.     char * tmpinst  = NULL;             /* K4 Instance */
  3391.     char * tmpaddrs[KRB5_NUM_OF_ADDRS];
  3392. #ifdef CK_RECALL
  3393.     int sv_recall; /* For turning off command recall */
  3394.     extern int on_recall; /* around Password prompting */
  3395. #endif /* CK_RECALL */
  3396.     struct stringint { /* Temporary array for switch values */
  3397. char * sval; /* String value */
  3398. int ival; /* Integer value */
  3399.     } pv[KRB_I_MAX+1]; /* This many */
  3400.     struct FDB kw, sw, fl; /* FDBs for each parse function */
  3401.     krb_action = -1; /* Initialize Kerberos action. */
  3402.     tmp_action = -1; /* And our local copy. */
  3403.     for (i = 0; i < KRB5_NUM_OF_ADDRS; i++)
  3404.       tmpaddrs[i] = NULL;
  3405.     if ((y = cmkey(kerbtab,kerbtabn,"authentication type","",xxstring)) < 0)
  3406.       {
  3407.   if (y == -3)
  3408.     printf("?Authentication type not specified - nothing happensn");
  3409.   return(y);
  3410.       }
  3411.     tmpauth = y;
  3412.     debug(F101,"kerberos authentication","",tmpauth);
  3413.     switch (tmpauth) {
  3414.       case AUTH_KRB4: kv = 4; break; /* Don't assume values are the same */
  3415.       case AUTH_KRB5: kv = 5; break;
  3416.       default:
  3417. printf("?Authentication type not supported: "%s"n",atmbuf);
  3418. return(-9);
  3419.     }
  3420.     /* From here down is Kerberos */
  3421.     ini_kerb(); /* Reset Init data to defaults */
  3422.     if (kv == 4) { /* Set K4 defaults */
  3423.         if (krb4_d_realm)
  3424.   makestr(&tmprealm,krb4_d_realm);
  3425.         if (krb4_d_principal)
  3426.   makestr(&tmpprinz,krb4_d_principal);
  3427.         if (krb4_d_instance)
  3428.   makestr(&tmpinst,krb4_d_instance);
  3429.     } else if (kv == 5) { /* Set K5 defaults */
  3430.         if (krb5_d_cc)
  3431.   makestr(&tmpcache,krb5_d_cc);
  3432.         if (krb5_d_realm)
  3433.   makestr(&tmprealm,krb5_d_realm);
  3434.         if (krb5_d_principal)
  3435.   makestr(&tmpprinz,krb5_d_principal);
  3436.         if (krb5_d_instance)
  3437.   makestr(&tmpinst,krb5_d_instance);
  3438.     }
  3439.     for (i = 0; i <= KRB_I_MAX; i++) { /* Initialize switch values */
  3440. pv[i].sval = NULL; /* to null pointers */
  3441. pv[i].ival = 0; /* and 0 int values */
  3442.     }
  3443.     if (kv == 4) { /* Kerberos 4 */
  3444.         pv[KRB_I_LF].ival = krb4_d_lifetime;
  3445.         pv[KRB_I_PA].ival = krb4_d_preauth;
  3446. if ((n = cmkey(krb_a_tbl,krb_a_n,"Kerberos 4 action","",xxstring)) < 0)
  3447.   {
  3448.       if (n == -3)
  3449. printf("?Action not specified - nothing happens.n");
  3450.       return(n);
  3451.   }
  3452.     } else if (kv == 5) { /* Kerberos 5 */
  3453.         pv[KRB_I_FW].ival = krb5_d_forwardable;
  3454.         pv[KRB_I_PR].ival = krb5_d_proxiable;
  3455.         pv[KRB_I_LF].ival = krb5_d_lifetime;
  3456.         pv[KRB_I_RB].ival = krb5_d_renewable;
  3457.         pv[KRB_I_K4].ival = krb5_d_getk4;
  3458. /* Make help message that shows switches and action keywords */
  3459. strcpy(tmphlp,"Kerberos 5 action, one of the following:n ");
  3460. for (i = 0; i < krb_a_n; i++) {
  3461.     strcat(tmphlp,krb_a_tbl[i].kwd);
  3462.     if (i == krb_a_n - 1)
  3463.       strcat(tmphlp,"nor switch");
  3464.     else
  3465.   strcat(tmphlp,"   ");
  3466. }
  3467. /* Set up first set of chained FDB's */
  3468. cmfdbi(&sw, /* First FDB - command switches */
  3469.        _CMKEY, /* fcode */
  3470.        tmphlp, /* hlpmsg */
  3471.        "", /* default (none) */
  3472.        "", /* addtl string data */
  3473.        krb_s_n, /* Switch table size */
  3474.        4, /* addtl numeric data 2: 4 = cmswi */
  3475.        xxstring, /* Processing function */
  3476.        krb_s_tbl, /* Switch table */
  3477.        &kw /* Pointer to next FDB */
  3478.        );
  3479. cmfdbi(&kw, /* Second FDB - action keywords */
  3480.        _CMKEY, /* fcode */
  3481.        "Kerberos action", /* hlpmsg */
  3482.        "", /* default (none) */
  3483.        "", /* addtl string data */
  3484.        krb_a_n, /* Switch table size */
  3485.        0, /* addtl num data (0 = NOT switch) */
  3486.        xxstring, /* Processing function */
  3487.        krb_a_tbl, /* Keyword table */
  3488.        NULL /* Pointer to next FDB (none) */
  3489.        );
  3490. /* Parse */
  3491. while (1) { /* Parse 0 or more switches */
  3492.     rc = cmfdb(&sw); /* Parse something */
  3493.     debug(F101,"kerberos cmfdb 1 rc","",rc);
  3494.     if (rc < 0) { /* Error */
  3495. if (rc == -3)
  3496.   printf("?Action not specified - nothing happens.n");
  3497. return(rc); /* or reparse needed */
  3498.     }
  3499.     if (cmresult.fdbaddr != &sw) /* Break out if not a switch */
  3500.       break;
  3501.     c = cmgbrk(); /* Have switch - get break character */
  3502.     getval = (c == ':' || c == '='); /* Must parse an agument? */
  3503.     if (getval && !(cmresult.kflags & CM_ARG)) {
  3504. printf("?This switch does not take argumentsn");
  3505. return(-9); /* OK because nothing malloc'd yet */
  3506.     }
  3507.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  3508. printf("?This switch requires an argumentn");
  3509. return(-9);
  3510.     }
  3511.     n = cmresult.nresult; /* Numeric result = switch value */
  3512.     debug(F101,"kerberos command switch","",n);
  3513.     switch (n) { /* Handle the switch */
  3514.       case KRB_S_CA: /* /CACHE:<filename> */
  3515. p = krb5_d_cc ? krb5_d_cc : "";
  3516. if ((y = cmofi("Name of cache file",p,&s,xxstring)) < 0) {
  3517.     if (y == -3)
  3518.       s = NULL;
  3519.     else
  3520.       return(y);
  3521. }
  3522. makestr(&tmpcache,s);
  3523. break;
  3524.       default:
  3525. printf("?Unexpected switch value - internal errorn");
  3526. return(-9); /* (if) nothing malloc'd yet. */
  3527.     }
  3528. }
  3529. if (cmresult.fdbaddr != &kw) { /* Checking... */
  3530.     printf("?Unexpected result - internal errorn");
  3531.     return(-9); /* Nothing malloc'd yet. */
  3532. }
  3533. n = cmresult.nresult; /* Get keyword value */
  3534.     } else {
  3535. printf("?Unexpected Kerberos version - Internal errorn");
  3536. return(-9);
  3537.     }
  3538.     debug(F101,"kerberos action","",n);
  3539.     switch (n) {
  3540.       case KRB_A_IN: /* INITIALIZE */
  3541.       case KRB_A_DE: /* DESTROY */
  3542.       case KRB_A_LC: /* LIST-CREDENTIALS */
  3543. tmp_action = n; /* OK, set */
  3544. break;
  3545.       default: /* Not OK, punt. */
  3546. printf("?Unexpected action - internal errorn");
  3547. return(-9);
  3548.     }
  3549.     if (tmp_action == KRB_A_IN) { /* Action is INITIALIZE */
  3550. int x;
  3551. cmfdbi(&sw, /* INITIALIZE switches */
  3552.        _CMKEY, /* fcode */
  3553.        "Principal,n or optional INITIALIZE switch(es)", /* hlpmsg */
  3554.        "", /* default (none) */
  3555.        "", /* addtl string data */
  3556.        kv == 4 ?  krb4_i_n : krb5_i_n, /* Switch table size */
  3557.        4, /* addtl numeric data 2: 4 = cmswi */
  3558.        xxstring, /* Processing function */
  3559.        kv == 4 ?  krb4_i_tbl : krb5_i_tbl, /* Switch table */
  3560.        &fl /* Pointer to next FDB */
  3561.        );
  3562. cmfdbi(&fl, /* 3rd FDB - command to send from */
  3563.        _CMFLD, /* fcode */
  3564.        "Principal", /* hlpmsg */
  3565.        kv == 4 ? krb4_d_principal : krb5_d_principal, /* principal */
  3566.        "", /* addtl string data */
  3567.        0, /* addtl numeric data 1 */
  3568.        0, /* addtl numeric data 2 */
  3569.        xxstring,
  3570.        NULL,
  3571.        NULL
  3572.        );
  3573. while (1) { /* Parse INIT switches or principal */
  3574.     rc = cmfdb(&sw);
  3575.     debug(F101,"kerberos cmfdb 2 rc","",rc);
  3576.     if (rc < 0) {
  3577. if (rc == -3)
  3578.   printf("?Principal name requiredn");
  3579. goto kerbx;
  3580.     }
  3581.     debug(F101,"kerberos cmfdb 2 fcode","",cmresult.fcode);
  3582.     if (cmresult.fcode != _CMKEY) /* Not a switch, quit switch loop */
  3583.       break;
  3584.     c = cmgbrk(); /* Switch - get break character */
  3585.     debug(F101,"kerberos cmfdb 2 cmgbrk","",c);
  3586.     getval = (c == ':' || c == '=');
  3587.     if (getval && !(cmresult.kflags & CM_ARG)) {
  3588. printf("?This switch does not take argumentsn");
  3589. return(-9); /* OK because nothing malloc'd yet */
  3590.     }
  3591.     if (!getval && (cmgkwflgs() & CM_ARG)) {
  3592. printf("?This switch requires an argumentn");
  3593. return(-9);
  3594.     }
  3595.     n = cmresult.nresult; /* Numeric result = switch value */
  3596.     switch (n) {
  3597.       /* These don't take args... */
  3598.               case KRB_I_PA:            /* /PREAUTH */
  3599.       case KRB_I_FW: /* /FORWARDABLE */
  3600.       case KRB_I_PR: /* /PROXIABLE */
  3601.               case KRB_I_RN: /* /RENEW */
  3602.       case KRB_I_VA: /* /VALIDATE */
  3603.               case KRB_I_NPA:           /* /NOT-PREAUTH */
  3604.               case KRB_I_NFW: /* /NOT-FORWARDABLE */
  3605.               case KRB_I_NPR: /* /NOT-PROXIABLE */
  3606.               case KRB_I_VB:            /* /VERBOSE */
  3607.               case KRB_I_BR:            /* /BRIEF */
  3608.               case KRB_I_K4:            /* /KERBEROS4 */
  3609.               case KRB_I_NK4:           /* /NO-KERBEROS4 */
  3610.               case KRB_I_POP:           /* /POPUP */
  3611. if (getval) {
  3612.     printf("?This switch does not take a valuen");
  3613.     rc = -9;
  3614.     goto kerbx;
  3615. }
  3616.                 switch (n) {
  3617.   case KRB_I_NPA:
  3618.                     pv[KRB_I_PA].ival = 0;
  3619.                     break;
  3620.   case KRB_I_NFW:
  3621.                     pv[KRB_I_FW].ival = 0;
  3622.                     break;
  3623.   case KRB_I_NPR:
  3624.                     pv[KRB_I_PR].ival = 0;
  3625.                     break;
  3626.   case KRB_I_VB:
  3627.                     pv[KRB_I_BR].ival = 0;
  3628.                     break;
  3629.                   case KRB_I_NK4:
  3630.                     pv[KRB_I_K4].ival = 0;
  3631.                     break;
  3632.   default:
  3633.                     pv[n].ival = 1;
  3634.                 }
  3635. break;
  3636. /* These do take arguments */
  3637.       case KRB_I_RB: /* /RENEWABLE:<minutes> */
  3638. pv[n].ival = 0;
  3639. if (!getval) break;
  3640. if ((rc = cmnum("Minutes",ckitoa(krb5_init.renewable),
  3641. 10,&y, xxstring)) < 0)
  3642.   goto kerbx;
  3643. pv[n].ival = y;
  3644. break;
  3645.       case KRB_I_LF: /* /LIFETIME:<minutes> */
  3646. pv[n].ival = 0;
  3647. sprintf(tmpbuf,"%d", /* Default is previous value */
  3648. kv == 4 ?
  3649. krb4_init.lifetime :
  3650. krb5_init.lifetime
  3651. );
  3652. if (!getval) break;
  3653. if ((rc = cmnum("Minutes",tmpbuf,10,&y, xxstring)) < 0)
  3654.   goto kerbx;
  3655. pv[n].ival = y;
  3656. break;
  3657.       case KRB_I_PD: /* /POSTDATE:<timestamp> */
  3658. if (pv[n].sval) {
  3659.     free(pv[n].sval);
  3660.     pv[n].sval = NULL;
  3661. }
  3662. if (!getval) break;
  3663. if ((rc = cmdate("date-time","",&s,0,xxstring)) < 0)
  3664.   goto kerbx;
  3665. makestr(&(pv[n].sval),s);
  3666. break;
  3667.       case KRB_I_SR: /* /SERVICE:<name> */
  3668. if (pv[n].sval) {
  3669.     free(pv[n].sval);
  3670.     pv[n].sval = NULL;
  3671. }
  3672. if (!getval) break;
  3673. if ((rc = cmfld("Service-name","",&s,xxstring)) < 0)
  3674.   goto kerbx;
  3675. makestr(&(pv[n].sval),s);
  3676. break;
  3677.               case KRB_I_RL: /* /REALM:<name> */
  3678. if (pv[n].sval) {
  3679.     free(pv[n].sval);
  3680.     pv[n].sval = NULL;
  3681. }
  3682. if (!getval) break;
  3683. if (kv == 4)
  3684.   p = krb4_d_realm ? krb4_d_realm : "";
  3685. else
  3686.   p = krb5_d_realm ? krb5_d_realm : "";
  3687. if ((rc = cmfld("Realm",p,&s,xxstring)) < 0)
  3688.   goto kerbx;
  3689. makestr(&(pv[n].sval),s);
  3690. break;
  3691.       case KRB_I_IN: /* /INSTANCE:<name> */
  3692. if (pv[n].sval) {
  3693.     free(pv[n].sval);
  3694.     pv[n].sval = NULL;
  3695. }
  3696. if (!getval) break;
  3697.                 if (kv == 4)
  3698.                     p = krb4_d_instance ? krb4_d_instance : "";
  3699.                 else
  3700.                     p = krb5_d_instance ? krb5_d_instance : "";
  3701. if ((rc = cmfld("Instance",p,&s,xxstring)) < 0)
  3702.   goto kerbx;
  3703. makestr(&(pv[n].sval),s);
  3704. break;
  3705.       case KRB_I_PW: /* /PASSWORD:<password> */
  3706. if (pv[n].sval) {
  3707.     free(pv[n].sval);
  3708.     pv[n].sval = NULL;
  3709. }
  3710. if (!getval) break;
  3711. if ((rc = cmfld("Password","",&s,xxstring)) < 0)
  3712.   goto kerbx;
  3713. makestr(&(pv[n].sval),s);
  3714. break;
  3715.               case KRB_I_ADR: /* /ADDRESSES:{<address-list>} */
  3716. if (pv[n].sval) {
  3717.     free(pv[n].sval);
  3718.     pv[n].sval = NULL;
  3719. }
  3720. if (!getval) break;
  3721. if ((rc = cmfld("List of IP addresses","",&s,xxstring)) < 0)
  3722.   goto kerbx;
  3723. makelist(s,tmpaddrs,KRB5_NUM_OF_ADDRS);
  3724. for (i = 0; i < KRB5_NUM_OF_ADDRS && tmpaddrs[i]; i++) {
  3725.     if (inet_addr(tmpaddrs[i]) == 0xffffffff) {
  3726. printf("invalid ip address: %sn",tmpaddrs[i]);
  3727. rc = -9;
  3728. goto kerbx;
  3729.     }
  3730. }
  3731. break;
  3732.       default:
  3733. printf("?Unexpected switch value - internal errorn");
  3734. rc = -9;
  3735. goto kerbx;
  3736.     }
  3737. }
  3738. if (cmresult.fcode != _CMFLD) {
  3739.     printf("?Unexected result - internal errorn");
  3740.     rc = -9;
  3741.     goto kerbx;
  3742. }
  3743.         /* cmresult.sresult may be of the form PRINCIPAL@REALM */
  3744.         i = ckindex("@",cmresult.sresult,0,0,0);
  3745.         if (i != 0) {
  3746.             makestr(&tmprealm,&cmresult.sresult[i]);
  3747.             cmresult.sresult[i-1] = '';
  3748.         }
  3749. makestr(&tmpprinz,cmresult.sresult); /* Principal (user) */
  3750. if ((rc = cmcfm()) < 0) { /* Now get confirmation */
  3751.             if (rc == -3) {
  3752. #ifdef IKSD
  3753. if (inserver) {
  3754.     printf("?Sorry, command disabledrn");
  3755.     return(success = 0);
  3756. }
  3757. #endif /* IKSD */
  3758. printf("?Principal name requiredn");
  3759.             }
  3760.             goto kerbx;
  3761.         }
  3762. #ifdef IKSD
  3763.         if (inserver) {
  3764.             printf("?Sorry, command disabledrn");
  3765.             return(success = 0);
  3766.         }
  3767. #endif /* IKSD */
  3768.         if (!tmpprinz || !tmpprinz[0]) {
  3769.             printf("?Principal name requiredn");
  3770.             goto kerbx;
  3771.         }
  3772.         if (!pv[KRB_I_RN].ival && !pv[KRB_I_VA].ival) {
  3773.             /* Don't use a password if Validating or Renewing */
  3774.     if (pv[KRB_I_PW].sval) { /* If they gave a /PASSWORD switch */
  3775. makestr(&tmppswd,pv[KRB_I_PW].sval); /* use this value */
  3776.     } else { /* Otherwise must prompt for it */
  3777. char prmpt[80];
  3778.                 if (pv[KRB_I_RL].sval)
  3779.   sprintf(prmpt,"%s@%s's Password: ",
  3780.   tmpprinz,pv[KRB_I_RL].sval);
  3781.                 else if (tmprealm)
  3782.   sprintf(prmpt,"%s@%s's Password: ",
  3783.   tmpprinz,tmprealm);
  3784.                 else
  3785.   sprintf(prmpt,"%s's Password: ",tmpprinz);
  3786. #ifdef OS2
  3787.                 if (pv[KRB_I_POP].ival) {
  3788.                     char passwd[80]="";
  3789.                     readpass(prmpt,passwd,80);
  3790.                     makestr(&tmppswd,passwd);
  3791.                     memset(passwd,0,80);
  3792.                 } else {
  3793. #endif /* OS2 */
  3794. #ifdef CK_RECALL
  3795.     sv_recall = on_recall; /* Save & turn off command recall */
  3796.     on_recall = 0;
  3797. #endif /* CK_RECALL */
  3798.     cmsavp(psave,PROMPTL); /* Save old prompt */
  3799.     cmsetp(prmpt); /* Make new prompt */
  3800.     concb((char)escape); /* Put console in cbreak mode */
  3801.     cmini(0); /* and no-echo mode */
  3802.     /* Issue prompt if at top level */
  3803.     if (pflag) prompt(xxstring);
  3804.     cmres(); /* Reset the parser */
  3805.     for (rc = -1; rc < 0; ) { /* Prompt till they answer */
  3806. /* Get a literal line of text */
  3807. rc = cmtxt("","",&s,NULL);
  3808. cmres(); /* Reset the parser again */
  3809.     }
  3810.     makestr(&tmppswd,s);
  3811. #ifdef CK_RECALL
  3812.     on_recall = sv_recall; /* Restore command recall */
  3813. #endif /* CK_RECALL */
  3814.     printf("n"); /* Echo a CRLF */
  3815.     cmsetp(psave); /* Restore original prompt */
  3816. #ifdef OS2
  3817.                 }
  3818. #endif /* OS2 */
  3819.     }
  3820.     x = 0; /* Check for password */
  3821.     if (tmppswd)
  3822.       if (*tmppswd)
  3823. x = 1;
  3824.     if (!x) {
  3825. printf("?Password requiredn");
  3826. goto kerbx;
  3827.     }
  3828.         }
  3829.     } else if (kv == 5 && tmp_action == KRB_A_LC) { /* LIST-CREDENTIALS */
  3830. tmp_klc = 0;
  3831. while (1) {
  3832.     if ((x = cmkey(klctab,nklctab,"Switch","",xxstring)) < 0) {
  3833. if (x == -3) {
  3834.     if ((rc = cmcfm()) < 0)
  3835.       goto kerbx;
  3836.     else
  3837.       break;
  3838. } else {
  3839.     rc = x;
  3840.     goto kerbx;
  3841. }
  3842.     }
  3843.     tmp_klc |= x;
  3844. }
  3845.     } else if ((rc = cmcfm()) < 0) /* DESTROY, just confirm */
  3846. goto kerbx;
  3847. /* Done - Move confirmed data to final locations */
  3848.     krb_action = tmp_action; /* Action requested */
  3849.     krb_op.version = kv; /* Kerberos version */
  3850.     krb_op.cache = tmpcache; /* Cache file */
  3851.     tmpcache = NULL; /* So we don't free it */
  3852.     switch (krb_action) {
  3853.       case KRB_A_IN: /* INITIALIZE */
  3854.         if (kv == 5) {
  3855.             krb5_init.forwardable = pv[KRB_I_FW].ival;
  3856.             krb5_init.proxiable   = pv[KRB_I_PR].ival;
  3857.             krb5_init.lifetime    = pv[KRB_I_LF].ival;
  3858.             krb5_init.renew       = pv[KRB_I_RN].ival;
  3859.             krb5_init.renewable   = pv[KRB_I_RB].ival;
  3860.             krb5_init.validate    = pv[KRB_I_VA].ival;
  3861.             /* Here we just reassign the pointers and then set them to NULL */
  3862.             /* so they won't be freed below. */
  3863.             krb5_init.postdate = pv[KRB_I_PD].sval; pv[KRB_I_PD].sval = NULL;
  3864.             krb5_init.service  = pv[KRB_I_SR].sval; pv[KRB_I_SR].sval = NULL;
  3865.     if (pv[KRB_I_RL].sval) {
  3866. krb5_init.realm  = pv[KRB_I_RL].sval; pv[KRB_I_RL].sval = NULL;
  3867.             } else if (tmprealm) {
  3868.                 krb5_init.realm = tmprealm; tmprealm = NULL;
  3869.             }
  3870.             if (pv[KRB_I_IN].sval) {
  3871.                 krb5_init.instance = pv[KRB_I_IN].sval;
  3872. pv[KRB_I_IN].sval = NULL;
  3873.             } else if ( tmpinst ) {
  3874.                 krb5_init.instance = tmpinst;
  3875. tmpinst = NULL;
  3876.             }
  3877.             if (tmpprinz) {
  3878.                 krb5_init.principal = tmpprinz;
  3879.                 tmpprinz = NULL;
  3880.             }
  3881.             krb5_init.password = tmppswd;
  3882.             tmppswd = NULL;
  3883.             krb5_init.getk4 = pv[KRB_I_K4].ival;
  3884.             if (krb5_init.getk4) {
  3885.                 krb4_init.lifetime = pv[KRB_I_LF].ival;
  3886.                 if (krb5_init.realm)
  3887.                     makestr(&krb4_init.realm,krb5_init.realm);
  3888.                 krb4_init.preauth  = krb4_d_preauth;
  3889.                 krb4_init.verbose  = pv[KRB_I_BR].ival ? 0 : 1;
  3890.                 if (krb5_init.principal)
  3891.                     makestr(&krb4_init.principal,krb5_init.principal);
  3892.                 if (krb5_init.principal)
  3893.                     makestr(&krb4_init.password,krb5_init.password);
  3894.             }
  3895.     for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
  3896.                 krb5_init.addrs[i] = tmpaddrs[i];
  3897.                 tmpaddrs[i] = NULL;
  3898.             }
  3899. } else if (kv == 4) { /* Same deal for Kerberos 4 */
  3900.             krb4_init.lifetime = pv[KRB_I_LF].ival;
  3901.     if (pv[KRB_I_RL].sval) {
  3902. krb4_init.realm  = pv[KRB_I_RL].sval;
  3903. pv[KRB_I_RL].sval = NULL;
  3904.             } else if ( tmprealm ) {
  3905.                 krb4_init.realm  = tmprealm;
  3906. tmprealm = NULL;
  3907.             }
  3908.             if (pv[KRB_I_IN].sval) {
  3909.                 krb4_init.instance = pv[KRB_I_IN].sval;
  3910. pv[KRB_I_IN].sval = NULL;
  3911.             } else if ( tmpinst ) {
  3912.                 krb4_init.instance = tmpinst;
  3913. tmpinst = NULL;
  3914.             }
  3915.             krb4_init.preauth  = pv[KRB_I_PA].ival;
  3916.             krb4_init.verbose  = pv[KRB_I_BR].ival ? 0 : 1;
  3917.             if (tmpprinz) {
  3918.                 krb4_init.principal = tmpprinz;
  3919.                 tmpprinz = NULL;
  3920.             }
  3921.             krb4_init.password = tmppswd;
  3922.             tmppswd = NULL;
  3923.         }
  3924. break;
  3925.       case KRB_A_LC: /* List Credentials */
  3926. krb5_lc.encryption = tmp_klc & XYKLCEN;
  3927. krb5_lc.flags = tmp_klc & XYKLCFL;
  3928. krb5_lc.addr  = tmp_klc & XYKLCAD;
  3929. break;
  3930.     }
  3931. /* Common exit - Free temporary storage */
  3932.   kerbx:
  3933.     for (i = 0; i <= KRB_I_MAX; i++) { /* Free malloc'd switch data */
  3934. if (pv[i].sval)
  3935.   free(pv[i].sval);
  3936.     }
  3937.     for (i = 0; i < KRB5_NUM_OF_ADDRS; i++) {
  3938.         if (tmpaddrs[i])
  3939.   free(tmpaddrs[i]);
  3940.     }
  3941.     if (tmpprinz) free(tmpprinz); /* And these too. */
  3942.     if (tmppswd)  free(tmppswd);
  3943.     if (tmpcache) free(tmpcache);
  3944.     if (tmprealm) free(tmprealm);
  3945.     if (tmpinst)  free(tmpinst);
  3946.     return(rc); /* Return the return code */
  3947. }
  3948. #endif /* CK_KERBEROS */
  3949. #ifdef CK_LOGIN
  3950. int
  3951. #ifdef CK_ANSIC
  3952. ckxlogin(CHAR * userid, CHAR * passwd, CHAR * acct, int promptok)
  3953. #else /* CK_ANSIC */
  3954. ckxlogin(userid, passwd, acct, promptok)
  3955.   CHAR * userid; CHAR * passwd; CHAR * acct; int promptok;
  3956. #endif /* CK_ANSIC */
  3957. /* ckxlogin */ {
  3958. #ifdef CK_RECALL
  3959.     int sv_recall; /* For turning off command recall */
  3960.     extern int on_recall; /* around Password prompting */
  3961. #endif /* CK_RECALL */
  3962. #ifdef CK_PAM
  3963.     extern int guest;
  3964. #endif /* CK_PAM */
  3965.     int rprompt = 0; /* Restore prompt */
  3966. #ifdef CKSYSLOG
  3967.     int savlog;
  3968. #endif /* CKSYSLOG */
  3969.     extern int what, srvcdmsg;
  3970.     int x = 0, ok = 0, rc = 0;
  3971.     CHAR * _u = NULL, * _p = NULL, * _a = NULL;
  3972.     debug(F111,"ckxlogin userid",userid,promptok);
  3973.     debug(F110,"ckxlogin passwd",passwd,0);
  3974.     isguest = 0; /* Global "anonymous" flag */
  3975.     if (!userid) userid = (CHAR *)"";
  3976.     if (!passwd) passwd = (CHAR *)"";
  3977.     debug(F111,"ckxlogin userid",userid,what);
  3978. #ifdef CK_RECALL
  3979.     sv_recall = on_recall; /* Save and turn off command recall */
  3980.     on_recall = 0;
  3981. #endif /* CK_RECALL */
  3982. #ifdef CKSYSLOG
  3983.     savlog = ckxsyslog; /* Save and turn off syslogging */
  3984. #endif /* CKSYSLOG */
  3985.     if ((!*userid || !*passwd) && /* Need to prompt for missing info */
  3986. promptok) {
  3987.         cmsavp(psave,PROMPTL); /* Save old prompt */
  3988. debug(F110,"ckxlogin saved",psave,0);
  3989. rprompt = 1;
  3990.     }
  3991.     if (!*userid) {
  3992. if (!promptok)
  3993.   return(0);
  3994.         cmsetp("Username: ");         /* Make new prompt */
  3995.         concb((char)escape); /* Put console in cbreak mode */
  3996.         cmini(1);
  3997. /* Flush typeahead */
  3998. #ifdef IKS_OPTION
  3999. debug(F101,
  4000.       "ckxlogin TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
  4001.       "",
  4002.       TELOPT_SB(TELOPT_KERMIT).kermit.me_start
  4003.       );
  4004. #endif /* IKS_OPTION */
  4005. while (ttchk() > 0) {
  4006.     x = ttinc(0);
  4007.     debug(F101,"ckxlogin flush user x","",x);
  4008. #ifdef TNCODE
  4009.     if (sstelnet) {
  4010. if (x == IAC) {
  4011.     x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
  4012.     debug(F101,"ckxlogin user tn_doop","",x);
  4013. #ifdef IKS_OPTION
  4014.     debug(F101,
  4015.       "ckxlogin user TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
  4016.       "",
  4017.       TELOPT_SB(TELOPT_KERMIT).kermit.me_start
  4018.       );
  4019. #endif /* IKS_OPTION */
  4020.     if (x < 0)
  4021.       goto XCKXLOG;
  4022.     switch (x) {
  4023.       case 1: ckxech = 1; break; /* Turn on echoing */
  4024.       case 2: ckxech = 0; break; /* Turn off echoing */
  4025. #ifdef IKS_OPTION
  4026.       case 4:  /* IKS event */
  4027. if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
  4028.   break;  /* else fall thru... */
  4029. #endif /* IKS_OPTION */
  4030.       case 6:  /* Logout */
  4031. goto XCKXLOG;
  4032.     }
  4033. }
  4034.     }
  4035. #endif /* TNCODE */
  4036. }
  4037.         if (pflag) prompt(xxstring); /* Issue prompt if at top level */
  4038.         cmres(); /* Reset the parser */
  4039.         for (x = -1; x < 0;) { /* Prompt till they answer */
  4040.     /* Get a literal line of text */
  4041.             x=cmtxt("Your username, or "ftp", or "anonymous"","",&s,NULL);
  4042.             if (x == -4 || x == -10) {
  4043.                 printf("rnLogin cancelledn");
  4044. #ifdef CKSYSLOG
  4045. ckxsyslog = savlog;
  4046. #endif /* CKSYSLOG */
  4047.                 doexit(GOOD_EXIT,0);
  4048.             }
  4049.     if (sstate) /* Did a packet come instead? */
  4050.       goto XCKXLOG;
  4051.             cmres(); /* Reset the parser again */
  4052.         }
  4053.         if ((_u = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
  4054.             printf("?Internal error: mallocn");
  4055.     goto XCKXLOG;
  4056.         } else {
  4057.             strcpy((char *)_u,s);
  4058.             userid = _u;
  4059.         }
  4060.     }
  4061.     ok = zvuser((char *)userid); /* Verify username */
  4062.     debug(F111,"ckxlogin zvuser",userid,ok);
  4063.     if (!*passwd && promptok
  4064. #ifdef CK_PAM
  4065. && guest
  4066. #endif /* CK_PAM */
  4067. ) {
  4068.         char prmpt[80];
  4069. #ifdef CKSYSLOG
  4070.         savlog = ckxsyslog; /* Save and turn off syslogging */
  4071.         ckxsyslog = 0;
  4072. #endif /* CKSYSLOG */
  4073. /* Flush typeahead again */
  4074. while (ttchk() > 0) {
  4075.     x = ttinc(0);
  4076.     debug(F101,"ckxlogin flush user x","",x);
  4077. #ifdef TNCODE
  4078.     if (sstelnet) {
  4079. if (x == IAC) {
  4080.     x = tn_doop((CHAR)(x & 0xff),ckxech,ttinc);
  4081.     debug(F101,"ckxlogin pass tn_doop","",x);
  4082. #ifdef IKS_OPTION
  4083.     debug(F101,
  4084.       "ckxlogin pass TELOPT_SB(TELOPT_KERMIT).kermit.me_start",
  4085.       "",
  4086.       TELOPT_SB(TELOPT_KERMIT).kermit.me_start
  4087.       );
  4088. #endif /* IKS_OPTION */
  4089.     if (x < 0)
  4090.       goto XCKXLOG;
  4091.     switch (x) {
  4092.       case 1: ckxech = 1; break; /* Turn on echoing */
  4093.       case 2: ckxech = 0; break; /* Turn off echoing */
  4094.       case 4:  /* IKS event */
  4095. if (!TELOPT_SB(TELOPT_KERMIT).kermit.me_start)
  4096.   break;  /* else fall thru... */
  4097.       case 6:  /* Logout */
  4098. goto XCKXLOG;
  4099.     }
  4100. }
  4101.     }
  4102. #endif /* TNCODE */
  4103. }
  4104.         if (!strcmp((char *)userid,"anonymous") ||
  4105.     !strcmp((char *)userid,"ftp") )
  4106.   sprintf(prmpt,"Enter e-mail address as Password: ");
  4107.         else if (*userid && strlen((char *)userid) < 60) {
  4108. #ifdef NT
  4109.             extern CHAR * pReferenceDomainName;
  4110.             if (pReferenceDomainName)
  4111.       sprintf(prmpt,"Enter %s\\%s's Password: ",
  4112.       pReferenceDomainName,userid);
  4113.             else
  4114. #endif /* NT */
  4115.       sprintf(prmpt,"Enter %s's Password: ",userid);
  4116.         } else
  4117.   sprintf(prmpt,"Enter Password: ");
  4118. cmsetp(prmpt); /* Make new prompt */
  4119. concb((char)escape); /* Put console in cbreak mode */
  4120.         if (strcmp((char *)userid,"anonymous") &&
  4121.     strcmp((char *)userid,"ftp") ) /* and if not anonymous */
  4122.   cmini(0); /* and no-echo mode */
  4123. else
  4124.   cmini(1);
  4125. if (pflag) prompt(xxstring); /* Issue prompt if at top level */
  4126. cmres(); /* Reset the parser */
  4127. for (x = -1; x < 0;) { /* Prompt till they answer */
  4128.     x = cmtxt("","",&s,NULL); /* Get a literal line of text */
  4129.             if (x == -4 || x == -10) {
  4130.                 printf("rnLogin cancelledrn");
  4131. #ifdef CKSYSLOG
  4132. ckxsyslog = savlog;
  4133. #endif /* CKSYSLOG */
  4134.                 doexit(GOOD_EXIT,0);
  4135.             }
  4136.     if (sstate) /* In case of a Kermit packet */
  4137.       goto XCKXLOG;
  4138.     cmres(); /* Reset the parser again */
  4139. }
  4140. printf("rn"); /* Echo a CRLF */
  4141. if ((_p = (CHAR *)malloc((int)strlen(s) + 1)) == NULL) {
  4142.     printf("?Internal error: mallocn");
  4143.     goto XCKXLOG;
  4144. } else {
  4145.     strcpy((char *)_p,s);
  4146.     passwd = _p;
  4147. }
  4148.     }
  4149. #ifdef CK_PAM
  4150.     else {
  4151. cmres(); /* Reset the parser */
  4152. /* We restore the prompt now because the PAM engine will call  */
  4153. /* readpass() which will overwrite psave. */
  4154. if (rprompt) {
  4155.     cmsetp(psave); /* Restore original prompt */
  4156.     debug(F110,"ckxlogin restored",psave,0);
  4157.     rprompt = 0;
  4158. }
  4159.     }
  4160. #endif /* CK_PAM */
  4161. #ifdef CKSYSLOG
  4162.     ckxsyslog = savlog;
  4163. #endif /* CKSYSLOG */
  4164.     if (ok) {
  4165. ok = zvpass((char *)passwd); /* Check password */
  4166. debug(F101,"ckxlogin zvpass","",ok);
  4167.     }
  4168.     if (ok > 0 && isguest) {
  4169. #ifndef NOPUSH
  4170. nopush = 1;
  4171. #endif /* NOPUSH */
  4172. srvcdmsg = 1;
  4173.     }
  4174.     rc = ok; /* Set the return code */
  4175.     if ((char *)uidbuf != (char *)userid)
  4176.       ckstrncpy(uidbuf,(char *)userid,UIDBUFLEN); /* Remember username */
  4177.   XCKXLOG: /* Common exit */
  4178. #ifdef CK_RECALL
  4179.     on_recall = sv_recall; /* Restore command recall */
  4180. #endif /* CK_RECALL */
  4181. #ifdef CKSYSLOG
  4182.     ckxsyslog = savlog; /* In case of GOTO above */
  4183. #endif /* CKSYSLOG */
  4184.     if (rprompt) {
  4185. cmsetp(psave); /* Restore original prompt */
  4186. debug(F110,"ckxlogin restored",psave,0);
  4187.     }
  4188.     if (_u || _p || _a) {
  4189.         if (_u) free(_u);
  4190.         if (_p) free(_p);
  4191.         if (_a) free(_a);
  4192.     }
  4193.     return(rc);
  4194. }
  4195. int
  4196. ckxlogout() {
  4197.     /* zvlogout(); */
  4198.     doexit(GOOD_EXIT,0); /* doexit calls zvlogout */
  4199.     return(0); /* not reached */
  4200. }
  4201. #endif /* CK_LOGIN */
  4202. #endif /* NOICP */