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:     }

Defined functions

checkppid defined in line 207; used 2 times
do_pw defined in line 215; used 3 times
getb defined in line 183; used 11 times
main defined in line 48; never used
packpwtobuf defined in line 233; used 1 times
timeout defined in line 200; used 2 times

Defined variables

cp defined in line 41; used 17 times
env defined in line 40; used 2 times
junk defined in line 42; used 11 times
l defined in line 44; used 17 times
off defined in line 43; used 4 times
tmtmp defined in line 46; used 3 times
tp defined in line 46; used 12 times

Defined macros

ASCTIME defined in line 26; never used
CTIME defined in line 25; never used
ENDPWENT defined in line 36; never used
GETPWENT defined in line 32; never used
GETPWNAM defined in line 33; never used
GETPWUID defined in line 34; never used
GMTIME defined in line 29; never used
LOCALTIME defined in line 28; never used
OFFTIME defined in line 30; never used
SETPASSENT defined in line 35; never used
TZSET defined in line 27; never used
Last modified: 1996-07-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3267
Valid CSS Valid XHTML 1.0 Strict