1: #include <paths.h> 2: #include <stdio.h> 3: #include <sysexits.h> 4: #include <varargs.h> 5: 6: #include <sys/types.h> 7: #include <sys/time.h> 8: #include <pwd.h> 9: #include <utmp.h> 10: 11: #define SEND_FD W[1] 12: #define RECV_FD R[0] 13: 14: #define CTIME 1 15: #define ASCTIME 2 16: #define TZSET 3 17: #define LOCALTIME 4 18: #define GMTIME 5 19: #define OFFTIME 6 20: 21: #define GETPWENT 7 22: #define GETPWNAM 8 23: #define GETPWUID 9 24: #define SETPASSENT 10 25: #define ENDPWENT 11 26: 27: static int R[2], W[2], inited; 28: static char result[256 + 4]; 29: static struct tm tmtmp; 30: static struct passwd _pw, *getandfixpw(); 31: 32: char * 33: ctime(t) 34: time_t *t; 35: { 36: u_char fnc = CTIME; 37: 38: sewer(); 39: write(SEND_FD, &fnc, sizeof fnc); 40: write(SEND_FD, t, sizeof (*t)); 41: getb(RECV_FD, result, 26); 42: return(result); 43: } 44: 45: char * 46: asctime(tp) 47: struct tm *tp; 48: { 49: u_char fnc = ASCTIME; 50: 51: sewer(); 52: write(SEND_FD, &fnc, sizeof fnc); 53: write(SEND_FD, tp, sizeof (*tp)); 54: getb(RECV_FD, result, 26); 55: return(result); 56: } 57: 58: void 59: tzset() 60: { 61: u_char fnc = TZSET; 62: 63: sewer(); 64: write(SEND_FD, &fnc, sizeof fnc); 65: } 66: 67: struct tm * 68: localtime(tp) 69: time_t *tp; 70: { 71: u_char fnc = LOCALTIME; 72: 73: sewer(); 74: write(SEND_FD, &fnc, sizeof fnc); 75: write(SEND_FD, tp, sizeof (*tp)); 76: getb(RECV_FD, &tmtmp, sizeof tmtmp); 77: getb(RECV_FD, result, 24); 78: tmtmp.tm_zone = result; 79: return(&tmtmp); 80: } 81: 82: struct tm * 83: gmtime(tp) 84: time_t *tp; 85: { 86: u_char fnc = GMTIME; 87: 88: sewer(); 89: write(SEND_FD, &fnc, sizeof fnc); 90: write(SEND_FD, tp, sizeof (*tp)); 91: getb(RECV_FD, &tmtmp, sizeof tmtmp); 92: getb(RECV_FD, result, 24); 93: tmtmp.tm_zone = result; 94: return(&tmtmp); 95: } 96: 97: struct tm * 98: offtime(clock, offset) 99: time_t *clock; 100: long offset; 101: { 102: u_char fnc = OFFTIME; 103: 104: sewer(); 105: write(SEND_FD, &fnc, sizeof fnc); 106: write(SEND_FD, clock, sizeof (*clock)); 107: write(SEND_FD, &offset, sizeof offset); 108: getb(RECV_FD, &tmtmp, sizeof tmtmp); 109: tmtmp.tm_zone = ""; 110: return(&tmtmp); 111: } 112: 113: struct passwd * 114: getpwent() 115: { 116: u_char fnc = GETPWENT; 117: 118: sewer(); 119: write(SEND_FD, &fnc, sizeof fnc); 120: return(getandfixpw()); 121: } 122: 123: struct passwd * 124: getpwnam(nam) 125: char *nam; 126: { 127: u_char fnc = GETPWNAM; 128: char lnam[UT_NAMESIZE + 1]; 129: int len; 130: 131: len = strlen(nam); 132: if (len > UT_NAMESIZE) 133: len = UT_NAMESIZE; 134: bcopy(nam, lnam, len); 135: lnam[len] = '\0'; 136: 137: sewer(); 138: write(SEND_FD, &fnc, 1); 139: write(SEND_FD, &len, sizeof (int)); 140: write(SEND_FD, lnam, len); 141: return(getandfixpw()); 142: } 143: 144: struct passwd * 145: getpwuid(uid) 146: uid_t uid; 147: { 148: u_char fnc = GETPWUID; 149: 150: sewer(); 151: write(SEND_FD, &fnc, sizeof fnc); 152: write(SEND_FD, &uid, sizeof (uid_t)); 153: return(getandfixpw()); 154: } 155: 156: setpwent() 157: { 158: return(setpassent(0)); 159: } 160: 161: setpassent(stayopen) 162: int stayopen; 163: { 164: u_char fnc = SETPASSENT; 165: int sts; 166: 167: sewer(); 168: write(SEND_FD, &fnc, sizeof fnc); 169: write(SEND_FD, &stayopen, sizeof (int)); 170: getb(RECV_FD, &sts, sizeof (int)); 171: return(sts); 172: } 173: 174: void 175: endpwent() 176: { 177: u_char fnc = ENDPWENT; 178: 179: sewer(); 180: write(SEND_FD, &fnc, sizeof fnc); 181: return; 182: } 183: 184: /* setpwfile() is deprecated */ 185: void 186: setpwfile(file) 187: char *file; 188: { 189: return; 190: } 191: 192: struct passwd * 193: getandfixpw() 194: { 195: short sz; 196: 197: getb(RECV_FD, &sz, sizeof (int)); 198: if (sz == 0) 199: return(NULL); 200: getb(RECV_FD, &_pw, sizeof (_pw)); 201: getb(RECV_FD, result, sz); 202: _pw.pw_name += (int)result; 203: _pw.pw_passwd += (int)result; 204: _pw.pw_class += (int)result; 205: _pw.pw_gecos += (int)result; 206: _pw.pw_dir += (int)result; 207: _pw.pw_shell += (int)result; 208: return(&_pw); 209: } 210: 211: getb(f, p, n) 212: register int f, n; 213: register char *p; 214: { 215: int i; 216: 217: while (n) 218: { 219: i = read(f, p, n); 220: if (i <= 0) 221: return; 222: p += i; 223: n -= i; 224: } 225: } 226: 227: sewer() 228: { 229: register int pid, ourpid = getpid(); 230: 231: if (inited == ourpid) 232: return; 233: if (inited) 234: { 235: close(SEND_FD); 236: close(RECV_FD); 237: } 238: pipe(W); 239: pipe(R); 240: pid = vfork(); 241: if (pid == 0) 242: { /* child */ 243: alarm(0); /* cancel alarms */ 244: dup2(W[0], 0); /* parent write side to our stdin */ 245: dup2(R[1], 1); /* parent read side to our stdout */ 246: close(SEND_FD); /* copies made, close the... */ 247: close(RECV_FD); /* originals now */ 248: execl(_PATH_CTIMED, "ctimed", 0); 249: _exit(EX_OSFILE); 250: } 251: if (pid == -1) 252: abort(); /* nothing else really to do */ 253: close(W[0]); /* close read side of SEND channel */ 254: close(R[1]); /* close write side of RECV channel */ 255: inited = ourpid; /* don't do this again in this proc */ 256: } 257: 258: XXctime() 259: { 260: 261: if (SEND_FD) 262: close(SEND_FD); 263: if (RECV_FD) 264: close(RECV_FD); 265: SEND_FD = RECV_FD = 0; 266: inited = 0; 267: }