home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / ckustr.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  7KB  |  410 lines

  1. /*
  2.  * ckustr.c - string extraction/restoration routines
  3. */
  4.  
  5. #include <stdio.h>
  6. #include <sysexits.h>
  7. #include <varargs.h>
  8. #include <paths.h>
  9.  
  10. /*
  11.   STR_FILE must be defined as a quoted string on the cc command line,
  12.   for example:
  13.  
  14.       -DSTR_FILE=\\\"/usr/local/lib/cku196.sr\\\"
  15.  
  16.   This is the file where the strings go, and where C-Kermit looks for them
  17.   at runtime.
  18. */
  19.  
  20. #ifdef STR_FILE
  21. char    *StringFile = STR_FILE;
  22. #else
  23. char    *StringFile = "/usr/local/lib/cku196.sr";
  24. #endif /* STR_FILE */
  25.  
  26. /*
  27.  * If _PATH_CTIMED is defined (in <paths.h>) then use that definition.  2.11BSD
  28.  * has this defined but 2.10BSD and other systems do not.
  29. */
  30.  
  31. #ifndef _PATH_CTIMED
  32. #define    _PATH_CTIMED STR_CTIMED
  33. #endif
  34.  
  35. extern int errno;
  36. static int strfile = -1, ourpid = 0;
  37.  
  38. #define BUFLEN 256
  39.  
  40. errprep(offset, buf)
  41. unsigned short offset;
  42. char *buf;
  43. {
  44. register int pid = getpid();
  45.  
  46.     if (pid != ourpid) {
  47.         ourpid = pid;
  48.         if (strfile >= 0) {
  49.             close(strfile);
  50.             strfile = -1;
  51.         }
  52.     }
  53.     if (strfile < 0) {
  54.             char *p, *getenv();
  55.         if (p = getenv("KSTR"))
  56.           if (strlen(p))
  57.             StringFile = p;
  58.         strfile = open(StringFile, 0);
  59.         if (strfile < 0) {
  60. oops:
  61.             fprintf(stderr, "Cannot find %s\r\n", StringFile);
  62.             exit(EX_OSFILE);
  63.         }
  64.     }
  65.     if (lseek(strfile, (long) offset, 0) < 0
  66.             || read(strfile, buf, BUFLEN) <= 0)
  67.         goto oops;
  68. }
  69.  
  70. /* extracted string front end for printf() */
  71. /*VARARGS1*/
  72. strprerror(fmt, va_alist)
  73.     int fmt;
  74.     va_dcl
  75. {
  76.     va_list    ap;
  77.     char buf[BUFLEN];
  78.  
  79.     errprep(fmt, buf);
  80.     va_start(ap);
  81.     vprintf(buf, ap);
  82.     va_end(ap);
  83. }
  84.  
  85. /* extracted string front end for sprintf() */
  86. /*VARARGS1*/
  87. strsrerror(fmt, obuf, va_alist)
  88.     int fmt;
  89.     char *obuf;
  90.     va_dcl
  91. {
  92.     char buf[BUFLEN];
  93.     va_list    ap;
  94.  
  95.     errprep(fmt, buf);
  96.     va_start(ap);
  97.     vsprintf(obuf, buf, ap);
  98.     va_end(ap);
  99. }
  100.  
  101. /* extracted string front end for fprintf() */
  102. /*VARARGS1*/
  103. strfrerror(fmt, fd, va_alist)
  104.     int fmt;
  105.     FILE *fd;
  106.     va_dcl
  107. {
  108.     va_list    ap;
  109.     char buf[BUFLEN];
  110.  
  111.     errprep(fmt, buf);
  112.     va_start(ap);
  113.     vfprintf(fd, buf, ap);
  114.     va_end(ap);
  115. }
  116.  
  117. /* extracted string front end for perror() */
  118. strperror(fmt)
  119.     int fmt;
  120. {
  121.     char buf[BUFLEN];
  122.     register int saverr = errno;
  123.  
  124.     errprep(fmt, buf);
  125.     errno = saverr;
  126.     perror(buf);
  127. }
  128.  
  129. perror(str)
  130.     char    *str;
  131.     {
  132.  
  133.     printf("%s: errno %d\n", str, errno);
  134.     }
  135.  
  136. /*
  137.  * The following is needed _only_ on systems which do not have the C library
  138.  * stubs for the ctime() and getpw*() functions.  In 2.11BSD these are
  139.  * present in the libstubs.a library and accessed via "-lstubs" at link time.
  140.  *
  141.  * 2.10BSD's cpp has the BSD2_10 symbol builtin.  Other systems without
  142.  * libstubs.a will need to define (via a -D option in CFLAGS) 'BSD2_10'.
  143. */
  144.  
  145. #ifdef    BSD2_10
  146.  
  147. #include <sys/types.h>
  148. #include <sys/time.h>
  149. #include <pwd.h>
  150. #include <utmp.h>
  151.  
  152. #define    SEND_FD    W[1]
  153. #define    RECV_FD    R[0]
  154.  
  155. #define    CTIME    1
  156. #define    ASCTIME    2
  157. #define    TZSET    3
  158. #define    LOCALTIME 4
  159. #define    GMTIME    5
  160. #define    OFFTIME    6
  161.  
  162. #define GETPWENT        7
  163. #define GETPWNAM        8
  164. #define GETPWUID        9
  165. #define SETPASSENT      10
  166. #define ENDPWENT        11
  167.  
  168.     static    int    R[2], W[2], inited;
  169.     static    char    result[256 + 4];
  170.     static    struct    tm    tmtmp;
  171.     static    struct    passwd    _pw, *getandfixpw();
  172.  
  173. char    *
  174. ctime(t)
  175.     time_t    *t;
  176.     {
  177.     u_char    fnc = CTIME;
  178.  
  179.     sewer();
  180.     write(SEND_FD, &fnc, sizeof fnc);
  181.     write(SEND_FD, t, sizeof (*t));
  182.     getb(RECV_FD, result, 26);
  183.     return(result);
  184.     }
  185.  
  186. char    *
  187. asctime(tp)
  188.     struct    tm    *tp;
  189.     {
  190.     u_char    fnc = ASCTIME;
  191.  
  192.     sewer();
  193.     write(SEND_FD, &fnc, sizeof fnc);
  194.     write(SEND_FD, tp, sizeof (*tp));
  195.     getb(RECV_FD, result, 26);
  196.     return(result);
  197.     }
  198.  
  199. void
  200. tzset()
  201.     {
  202.     u_char    fnc = TZSET;
  203.  
  204.     sewer();
  205.     write(SEND_FD, &fnc, sizeof fnc);
  206.     }
  207.  
  208. struct    tm *
  209. localtime(tp)
  210.     time_t    *tp;
  211.     {
  212.     u_char    fnc = LOCALTIME;
  213.  
  214.     sewer();
  215.     write(SEND_FD, &fnc, sizeof fnc);
  216.     write(SEND_FD, tp, sizeof (*tp));
  217.     getb(RECV_FD, &tmtmp, sizeof tmtmp);
  218.     getb(RECV_FD, result, 24);
  219.     tmtmp.tm_zone = result;
  220.     return(&tmtmp);
  221.     }
  222.  
  223. struct    tm *
  224. gmtime(tp)
  225.     time_t    *tp;
  226.     {
  227.     u_char    fnc = GMTIME;
  228.  
  229.     sewer();
  230.     write(SEND_FD, &fnc, sizeof fnc);
  231.     write(SEND_FD, tp, sizeof (*tp));
  232.     getb(RECV_FD, &tmtmp, sizeof tmtmp);
  233.     getb(RECV_FD, result, 24);
  234.     tmtmp.tm_zone = result;
  235.     return(&tmtmp);
  236.     }
  237.  
  238. struct    tm *
  239. offtime(clock, offset)
  240.     time_t    *clock;
  241.     long    offset;
  242.     {
  243.     u_char    fnc = OFFTIME;
  244.  
  245.     sewer();
  246.     write(SEND_FD, &fnc, sizeof fnc);
  247.     write(SEND_FD, clock, sizeof (*clock));
  248.     write(SEND_FD, &offset, sizeof offset);
  249.     getb(RECV_FD, &tmtmp, sizeof tmtmp);
  250.     tmtmp.tm_zone = "";
  251.     return(&tmtmp);
  252.     }
  253.  
  254. struct passwd *
  255. getpwent()
  256.     {
  257.     u_char    fnc = GETPWENT;
  258.  
  259.     sewer();
  260.     write(SEND_FD, &fnc, sizeof fnc);
  261.     return(getandfixpw());
  262.     }
  263.  
  264. struct    passwd *
  265. getpwnam(nam)
  266.     char    *nam;
  267.     {
  268.     u_char    fnc = GETPWNAM;
  269.     char    lnam[UT_NAMESIZE + 1];
  270.     int    len;
  271.  
  272.     len = strlen(nam);
  273.     if    (len > UT_NAMESIZE)
  274.         len = UT_NAMESIZE;
  275.     bcopy(nam, lnam, len);
  276.     lnam[len] = '\0';
  277.  
  278.     sewer();
  279.     write(SEND_FD, &fnc, 1);
  280.     write(SEND_FD, &len, sizeof (int));
  281.     write(SEND_FD, lnam, len);
  282.     return(getandfixpw());
  283.     }
  284.  
  285. struct    passwd    *
  286. getpwuid(uid)
  287.     uid_t    uid;
  288.     {
  289.     u_char    fnc = GETPWUID;
  290.  
  291.     sewer();
  292.     write(SEND_FD, &fnc, sizeof fnc);
  293.     write(SEND_FD, &uid, sizeof (uid_t));
  294.     return(getandfixpw());
  295.     }
  296.  
  297. setpwent()
  298.     {
  299.     return(setpassent(0));
  300.     }
  301.  
  302. setpassent(stayopen)
  303.     int    stayopen;
  304.     {
  305.     u_char    fnc = SETPASSENT;
  306.     int    sts;
  307.  
  308.     sewer();
  309.     write(SEND_FD, &fnc, sizeof fnc);
  310.     write(SEND_FD, &stayopen, sizeof (int));
  311.     getb(RECV_FD, &sts, sizeof (int));
  312.     return(sts);
  313.     }
  314.  
  315. void
  316. endpwent()
  317.     {
  318.     u_char    fnc = ENDPWENT;
  319.  
  320.     sewer();
  321.     write(SEND_FD, &fnc, sizeof fnc);
  322.     return;
  323.     }
  324.  
  325. /* setpwfile() is deprecated */
  326. void
  327. setpwfile(file)
  328.     char    *file;
  329.     {
  330.     return;
  331.     }
  332.  
  333. struct passwd *
  334. getandfixpw()
  335.     {
  336.     short    sz;
  337.  
  338.     getb(RECV_FD, &sz, sizeof (int));
  339.     if    (sz == 0)
  340.         return(NULL);
  341.     getb(RECV_FD, &_pw, sizeof (_pw));
  342.     getb(RECV_FD, result, sz);
  343.     _pw.pw_name += (int)result;
  344.     _pw.pw_passwd += (int)result;
  345.     _pw.pw_class += (int)result;
  346.     _pw.pw_gecos += (int)result;
  347.     _pw.pw_dir += (int)result;
  348.     _pw.pw_shell += (int)result;
  349.     return(&_pw);
  350.     }
  351.  
  352. getb(f, p, n)
  353.     register int f, n;
  354.     register char *p;
  355.     {
  356.     int    i;
  357.  
  358.     while    (n)
  359.         {
  360.         i = read(f, p, n);
  361.         if    (i <= 0)
  362.             return;
  363.         p += i;
  364.         n -= i;
  365.         }
  366.     }
  367.  
  368. sewer()
  369.     {
  370.     register int    pid, ourpid = getpid();
  371.  
  372.     if    (inited == ourpid)
  373.         return;
  374.     if    (inited)
  375.         {
  376.         close(SEND_FD);
  377.         close(RECV_FD);
  378.         }
  379.     pipe(W);
  380.     pipe(R);
  381.     pid = vfork();
  382.     if    (pid == 0)
  383.         {            /* child */
  384.         alarm(0);        /* cancel alarms */
  385.         dup2(W[0], 0);        /* parent write side to our stdin */
  386.         dup2(R[1], 1);        /* parent read side to our stdout */
  387.         close(SEND_FD);        /* copies made, close the... */
  388.         close(RECV_FD);        /* originals now */
  389.         execl(_PATH_CTIMED, "ctimed", 0);
  390.         _exit(EX_OSFILE);
  391.         }
  392.     if    (pid == -1)
  393.         abort();        /* nothing else really to do */
  394.     close(W[0]);            /* close read side of SEND channel */
  395.     close(R[1]);            /* close write side of RECV channel */
  396.     inited = ourpid;        /* don't do this again in this proc */
  397.     }
  398.  
  399. XXctime()
  400.     {
  401.  
  402.     if    (SEND_FD)
  403.         close(SEND_FD);
  404.     if    (RECV_FD)
  405.         close(RECV_FD);
  406.     SEND_FD = RECV_FD = 0;
  407.     inited = 0;
  408.     }
  409. #endif    /* BSD2_10 */
  410.