home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / c-kermit / cku2tm.c < prev    next >
C/C++ Source or Header  |  2020-01-01  |  5KB  |  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.