home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / panix / k95source.tar.gz / k95source.tar / cku2tm.c < prev    next >
C/C++ Source or Header  |  1999-11-27  |  9KB  |  266 lines

  1. /*
  2.  * Steven Schultz - sms@moe.2bsd.com
  3.  *
  4.  *      @(#)ctimed.c    1.0 (2.11BSD) 1996/6/25
  5.  *
  6.  * ctimed - the daemon that supports the ctime() and getpw*() stubs
  7.  *          in 'libcstubs.a'.
  8. */
  9.  
  10. #include        <signal.h>
  11. #include        <stdio.h>
  12. #include        <setjmp.h>
  13. #include        <sys/ioctl.h>
  14. #include        <sys/types.h>
  15. #include        <sys/time.h>
  16. #include        <pwd.h>
  17. #include        <utmp.h>
  18.  
  19. /*
  20.  * These should probably be placed in an include file.  If you add anything
  21.  * here then you will also have to modify /usr/src/usr.lib/libstubs/stubs.c
  22.  * (if for no other reason than to add the stub code).
  23. */
  24.  
  25. #define CTIME   1
  26. #define ASCTIME 2
  27. #define TZSET   3
  28. #define LOCALTIME 4
  29. #define GMTIME  5
  30. #define OFFTIME 6
  31.  
  32. #define GETPWENT        7
  33. #define GETPWNAM        8
  34. #define GETPWUID        9
  35. #define SETPASSENT      10
  36. #define ENDPWENT        11
  37.  
  38. extern  struct  tm      *offtime();
  39.  
  40.         jmp_buf env;
  41.         char    *cp;
  42.         char    junk[256 + sizeof (struct passwd) + 4];
  43.         long    off;
  44.         time_t  l;
  45.         void    timeout(), checkppid();
  46.         struct  tm      tmtmp, *tp;
  47.  
  48. main()
  49.         {
  50.         register int i;
  51.         register struct passwd *pw;
  52.         struct  itimerval it;
  53.         u_char  c, xxx;
  54.         int     len, tosslen;
  55.         uid_t   uid;
  56.  
  57.         signal(SIGPIPE, SIG_DFL);
  58.         for     (i = getdtablesize(); --i > 2; )
  59.                 close(i);
  60. /*
  61.  * Need a timer running while we disassociate from the control terminal
  62.  * in case of a modem line which has lost carrier.
  63. */
  64.         timerclear(&it.it_interval);
  65.         it.it_value.tv_sec = 5;
  66.         it.it_value.tv_usec = 0;
  67.         signal(SIGALRM, timeout);
  68.         setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
  69.         if      (setjmp(env) == 0)
  70.                 {
  71.                 i = open("/dev/tty", 0);
  72.                 if      (i >= 0)
  73.                         {
  74.                         ioctl(i, TIOCNOTTY, NULL);
  75.                         close(i);
  76.                         }
  77.                 }
  78. /*
  79.  * Now start a timer with one minute refresh.  In the signal service
  80.  * routine, check the parent process id to see if this process has
  81.  * been orphaned and if so exit.  This is primarily aimed at removing
  82.  * the 'ctimed' process left behind by 'sendmail's multi-fork startup
  83.  * but may prove useful in preventing accumulation of 'ctimed' processes
  84.  * in other circumstances as well.  Normally this process is short
  85.  * lived.
  86. */
  87.         it.it_interval.tv_sec = 60;
  88.         it.it_interval.tv_usec = 0;
  89.         it.it_value.tv_sec = 60;
  90.         it.it_value.tv_usec = 0;
  91.         signal(SIGALRM, checkppid);
  92.         setitimer(ITIMER_REAL, &it, (struct itimerval *) NULL);
  93.  
  94.         while   (read(fileno(stdin), &c, 1) == 1)
  95.                 {
  96.                 switch  (c)
  97.                         {
  98.                         case    CTIME:
  99.                                 l = 0L;
  100.                                 getb(fileno(stdin), &l, sizeof l);
  101.                                 cp = ctime(&l);
  102.                                 write(fileno(stdout), cp, 26);
  103.                                 break;
  104.                         case    ASCTIME:
  105.                                 getb(fileno(stdin), &tmtmp, sizeof tmtmp);
  106.                                 cp = asctime(&tmtmp);
  107.                                 write(fileno(stdout), cp, 26);
  108.                                 break;
  109.                         case    TZSET:
  110.                                 (void) tzset();
  111.                                 break;
  112.                         case    LOCALTIME:
  113.                                 l = 0L;
  114.                                 getb(fileno(stdin), &l, sizeof l);
  115.                                 tp = localtime(&l);
  116.                                 write(fileno(stdout), tp, sizeof (*tp));
  117.                                 strcpy(junk, tp->tm_zone);
  118.                                 junk[24] = '\0';
  119.                                 write(fileno(stdout), junk, 24);
  120.                                 break;
  121.                         case    GMTIME:
  122.                                 l = 0L;
  123.                                 getb(fileno(stdin), &l, sizeof l);
  124.                                 tp = gmtime(&l);
  125.                                 write(fileno(stdout), tp, sizeof (*tp));
  126.                                 strcpy(junk, tp->tm_zone);
  127.                                 junk[24] = '\0';
  128.                                 write(fileno(stdout), junk, 24);
  129.                                 break;
  130.                         case    OFFTIME:
  131.                                 getb(fileno(stdin), &l, sizeof l);
  132.                                 getb(fileno(stdin), &off, sizeof off);
  133. #ifdef  __bsdi__
  134.                                 l += off;
  135.                                 tp = localtime(&l);
  136. #else
  137.                                 tp = offtime(&l, off);
  138. #endif
  139.                                 write(fileno(stdout), tp, sizeof (*tp));
  140.                                 break;
  141.                         case    GETPWENT:
  142.                                 pw = getpwent();
  143.                                 do_pw(pw);
  144.                                 break;
  145.                         case    GETPWNAM:
  146.                                 getb(fileno(stdin), &len, sizeof (int));
  147.                                 if      (len > UT_NAMESIZE)
  148.                                         {
  149.                                         tosslen = len - UT_NAMESIZE;
  150.                                         len = UT_NAMESIZE;
  151.                                         }
  152.                                 else
  153.                                         tosslen = 0;
  154.                                 getb(fileno(stdin), junk, len);
  155.                                 for     (;tosslen; tosslen--)
  156.                                         getb(fileno(stdin), &xxx, 1);
  157.                                 junk[len] = '\0';
  158.                                 pw = getpwnam(junk);
  159.                                 do_pw(pw);
  160.                                 break;
  161.                         case    GETPWUID:
  162.                                 getb(fileno(stdin), &uid, sizeof (uid_t));
  163.                                 pw = getpwuid(uid);
  164.                                 do_pw(pw);
  165.                                 break;
  166.                         case    SETPASSENT:
  167.                                 getb(fileno(stdin), &len, sizeof (int));
  168.                                 if      (setpassent(len))
  169.                                         len = 1;
  170.                                 else
  171.                                         len = 0;
  172.                                 write(fileno(stdout), &len, sizeof (int));
  173.                                 break;
  174.                         case    ENDPWENT:
  175.                                 endpwent();
  176.                                 break;
  177.                         default:
  178.                                 abort("switch");
  179.                         }
  180.                 }
  181.         }
  182.  
  183. getb(f, p, n)
  184.         int     f;
  185.         register char   *p;
  186.         register int    n;
  187.         {
  188.         register int    i;
  189.  
  190.         while   (n)
  191.                 {
  192.                 i = read(f, p, n);
  193.                 if      (i <= 0)
  194.                         return;
  195.                 p += i;
  196.                 n -= i;
  197.                 }
  198.         }
  199.  
  200. void
  201. timeout()
  202.         {
  203.  
  204.         longjmp(env, 1);
  205.         }
  206.  
  207. void
  208. checkppid()
  209.         {
  210.  
  211.         if      (getppid() == 1)
  212.                 exit(0);
  213.         }
  214.  
  215. do_pw(pw)
  216.         struct passwd *pw;
  217.         {
  218.         int     len;
  219.  
  220.         if      (!pw)
  221.                 {
  222.                 len = 0;
  223.                 write(fileno(stdout), &len, sizeof (int));
  224.                 return;
  225.                 }
  226.         len = packpwtobuf(pw, junk);
  227.         write(fileno(stdout), &len, sizeof (int));
  228.         write(fileno(stdout), pw, sizeof (*pw));
  229.         write(fileno(stdout), junk, len);
  230.         return;
  231.         }
  232.  
  233. packpwtobuf(pw, buf)
  234.         register struct passwd *pw;
  235.         char    *buf;
  236.         {
  237.         register char *cp = buf;
  238.         register char *dp;
  239.  
  240.         dp = pw->pw_name;
  241.         pw->pw_name = (char*) 0;
  242.         while   (*cp++ = *dp++)
  243.                 ;
  244.         dp = pw->pw_passwd;
  245.         pw->pw_passwd = (char*) (cp - buf);
  246.         while   (*cp++ = *dp++)
  247.                 ;
  248.         dp = pw->pw_class;
  249.         pw->pw_class = (char*) (cp - buf);
  250.         while   (*cp++ = *dp++)
  251.                 ;
  252.         dp = pw->pw_gecos;
  253.         pw->pw_gecos = (char*) (cp - buf);
  254.         while   (*cp++ = *dp++)
  255.                 ;
  256.         dp = pw->pw_dir;
  257.         pw->pw_dir = (char*) (cp - buf);
  258.         while   (*cp++ = *dp++)
  259.                 ;
  260.         dp = pw->pw_shell;
  261.         pw->pw_shell = (char*) (cp - buf);
  262.         while   (*cp++ = *dp++)
  263.                 ;
  264.         return(cp - buf);
  265.         }
  266.