home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / archives / k95source.tar.gz / k95source.tar / ckustr.c < prev    next >
C/C++ Source or Header  |  2002-01-22  |  9KB  |  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.