1: /* 2: Copyright (C) 1985, 1996, Trustees of Columbia University in the City of New 3: York. The C-Kermit software may not be, in whole or in part, licensed or 4: sold for profit as a software product itself, nor may it be included in or 5: distributed with commercial products or otherwise distributed by commercial 6: concerns to their clients or customers without written permission of the 7: Office of Kermit Development and Distribution, Columbia University. This 8: copyright notice must not be removed, altered, or obscured. 9: */ 10: 11: /* 12: * ckustr.c - string extraction/restoration routines 13: */ 14: 15: #include <stdio.h> 16: #include <sysexits.h> 17: #include <varargs.h> 18: #include <paths.h> 19: 20: /* 21: STR_FILE must be defined as a quoted string on the cc command line, 22: for example: 23: 24: -DSTR_FILE=\\\"/usr/local/lib/kermit5.sr\\\" 25: 26: This is the file where the strings go, and where C-Kermit looks for them 27: at runtime. 28: */ 29: 30: #ifdef STR_FILE 31: char *StringFile = STR_FILE; 32: #else 33: char *StringFile = "/usr/local/lib/kermit5.sr"; 34: #endif /* STR_FILE */ 35: 36: /* 37: * If _PATH_CTIMED is defined (in <paths.h>) then use that definition. 2.11BSD 38: * has this defined but 2.10BSD and other systems do not. 39: */ 40: 41: #ifndef _PATH_CTIMED 42: #define _PATH_CTIMED STR_CTIMED 43: #endif 44: 45: extern int errno; 46: static int strfile = -1, ourpid = 0; 47: 48: #define BUFLEN 256 49: 50: errprep(offset, buf) 51: unsigned short offset; 52: char *buf; 53: { 54: register int pid = getpid(); 55: 56: if (pid != ourpid) { 57: ourpid = pid; 58: if (strfile >= 0) { 59: close(strfile); 60: strfile = -1; 61: } 62: } 63: if (strfile < 0) { 64: char *p, *getenv(); 65: if (p = getenv("KSTR")) 66: if (strlen(p)) 67: StringFile = p; 68: strfile = open(StringFile, 0); 69: if (strfile < 0) { 70: oops: 71: fprintf(stderr, "Cannot find %s\r\n", StringFile); 72: exit(EX_OSFILE); 73: } 74: } 75: if (lseek(strfile, (long) offset, 0) < 0 76: || read(strfile, buf, BUFLEN) <= 0) 77: goto oops; 78: } 79: 80: /* extracted string front end for printf() */ 81: /*VARARGS1*/ 82: strprerror(fmt, va_alist) 83: int fmt; 84: va_dcl 85: { 86: va_list ap; 87: char buf[BUFLEN]; 88: 89: errprep(fmt, buf); 90: va_start(ap); 91: vprintf(buf, ap); 92: va_end(ap); 93: } 94: 95: /* extracted string front end for sprintf() */ 96: /*VARARGS1*/ 97: strsrerror(fmt, obuf, va_alist) 98: int fmt; 99: char *obuf; 100: va_dcl 101: { 102: char buf[BUFLEN]; 103: va_list ap; 104: 105: errprep(fmt, buf); 106: va_start(ap); 107: vsprintf(obuf, buf, ap); 108: va_end(ap); 109: } 110: 111: /* extracted string front end for fprintf() */ 112: /*VARARGS1*/ 113: strfrerror(fmt, fd, va_alist) 114: int fmt; 115: FILE *fd; 116: va_dcl 117: { 118: va_list ap; 119: char buf[BUFLEN]; 120: 121: errprep(fmt, buf); 122: va_start(ap); 123: vfprintf(fd, buf, ap); 124: va_end(ap); 125: } 126: 127: /* extracted string front end for perror() */ 128: strperror(fmt) 129: int fmt; 130: { 131: char buf[BUFLEN]; 132: register int saverr = errno; 133: 134: errprep(fmt, buf); 135: errno = saverr; 136: perror(buf); 137: } 138: 139: perror(str) 140: char *str; 141: { 142: 143: printf("%s: errno %d\n", str, errno); 144: } 145: 146: /* 147: * The following is needed _only_ on systems which do not have the C library 148: * stubs for the ctime() and getpw*() functions. In 2.11BSD these are 149: * present in the libstubs.a library and accessed via "-lstubs" at link time. 150: * 151: * 2.10BSD's cpp has the BSD2_10 symbol builtin. Other systems without 152: * libstubs.a will need to define (via a -D option in CFLAGS) 'BSD2_10'. 153: */ 154: 155: #ifdef BSD2_10 156: 157: #include <sys/types.h> 158: #include <sys/time.h> 159: #include <pwd.h> 160: #include <utmp.h> 161: 162: #define SEND_FD W[1] 163: #define RECV_FD R[0] 164: 165: #define CTIME 1 166: #define ASCTIME 2 167: #define TZSET 3 168: #define LOCALTIME 4 169: #define GMTIME 5 170: #define OFFTIME 6 171: 172: #define GETPWENT 7 173: #define GETPWNAM 8 174: #define GETPWUID 9 175: #define SETPASSENT 10 176: #define ENDPWENT 11 177: 178: static int R[2], W[2], inited; 179: static char result[256 + 4]; 180: static struct tm tmtmp; 181: static struct passwd _pw, *getandfixpw(); 182: 183: char * 184: ctime(t) 185: time_t *t; 186: { 187: u_char fnc = CTIME; 188: 189: sewer(); 190: write(SEND_FD, &fnc, sizeof fnc); 191: write(SEND_FD, t, sizeof (*t)); 192: getb(RECV_FD, result, 26); 193: return(result); 194: } 195: 196: char * 197: asctime(tp) 198: struct tm *tp; 199: { 200: u_char fnc = ASCTIME; 201: 202: sewer(); 203: write(SEND_FD, &fnc, sizeof fnc); 204: write(SEND_FD, tp, sizeof (*tp)); 205: getb(RECV_FD, result, 26); 206: return(result); 207: } 208: 209: void 210: tzset() 211: { 212: u_char fnc = TZSET; 213: 214: sewer(); 215: write(SEND_FD, &fnc, sizeof fnc); 216: } 217: 218: struct tm * 219: localtime(tp) 220: time_t *tp; 221: { 222: u_char fnc = LOCALTIME; 223: 224: sewer(); 225: write(SEND_FD, &fnc, sizeof fnc); 226: write(SEND_FD, tp, sizeof (*tp)); 227: getb(RECV_FD, &tmtmp, sizeof tmtmp); 228: getb(RECV_FD, result, 24); 229: tmtmp.tm_zone = result; 230: return(&tmtmp); 231: } 232: 233: struct tm * 234: gmtime(tp) 235: time_t *tp; 236: { 237: u_char fnc = GMTIME; 238: 239: sewer(); 240: write(SEND_FD, &fnc, sizeof fnc); 241: write(SEND_FD, tp, sizeof (*tp)); 242: getb(RECV_FD, &tmtmp, sizeof tmtmp); 243: getb(RECV_FD, result, 24); 244: tmtmp.tm_zone = result; 245: return(&tmtmp); 246: } 247: 248: struct tm * 249: offtime(clock, offset) 250: time_t *clock; 251: long offset; 252: { 253: u_char fnc = OFFTIME; 254: 255: sewer(); 256: write(SEND_FD, &fnc, sizeof fnc); 257: write(SEND_FD, clock, sizeof (*clock)); 258: write(SEND_FD, &offset, sizeof offset); 259: getb(RECV_FD, &tmtmp, sizeof tmtmp); 260: tmtmp.tm_zone = ""; 261: return(&tmtmp); 262: } 263: 264: struct passwd * 265: getpwent() 266: { 267: u_char fnc = GETPWENT; 268: 269: sewer(); 270: write(SEND_FD, &fnc, sizeof fnc); 271: return(getandfixpw()); 272: } 273: 274: struct passwd * 275: getpwnam(nam) 276: char *nam; 277: { 278: u_char fnc = GETPWNAM; 279: char lnam[UT_NAMESIZE + 1]; 280: int len; 281: 282: len = strlen(nam); 283: if (len > UT_NAMESIZE) 284: len = UT_NAMESIZE; 285: bcopy(nam, lnam, len); 286: lnam[len] = '\0'; 287: 288: sewer(); 289: write(SEND_FD, &fnc, 1); 290: write(SEND_FD, &len, sizeof (int)); 291: write(SEND_FD, lnam, len); 292: return(getandfixpw()); 293: } 294: 295: struct passwd * 296: getpwuid(uid) 297: uid_t uid; 298: { 299: u_char fnc = GETPWUID; 300: 301: sewer(); 302: write(SEND_FD, &fnc, sizeof fnc); 303: write(SEND_FD, &uid, sizeof (uid_t)); 304: return(getandfixpw()); 305: } 306: 307: setpwent() 308: { 309: return(setpassent(0)); 310: } 311: 312: setpassent(stayopen) 313: int stayopen; 314: { 315: u_char fnc = SETPASSENT; 316: int sts; 317: 318: sewer(); 319: write(SEND_FD, &fnc, sizeof fnc); 320: write(SEND_FD, &stayopen, sizeof (int)); 321: getb(RECV_FD, &sts, sizeof (int)); 322: return(sts); 323: } 324: 325: void 326: endpwent() 327: { 328: u_char fnc = ENDPWENT; 329: 330: sewer(); 331: write(SEND_FD, &fnc, sizeof fnc); 332: return; 333: } 334: 335: /* setpwfile() is deprecated */ 336: void 337: setpwfile(file) 338: char *file; 339: { 340: return; 341: } 342: 343: struct passwd * 344: getandfixpw() 345: { 346: short sz; 347: 348: getb(RECV_FD, &sz, sizeof (int)); 349: if (sz == 0) 350: return(NULL); 351: getb(RECV_FD, &_pw, sizeof (_pw)); 352: getb(RECV_FD, result, sz); 353: _pw.pw_name += (int)result; 354: _pw.pw_passwd += (int)result; 355: _pw.pw_class += (int)result; 356: _pw.pw_gecos += (int)result; 357: _pw.pw_dir += (int)result; 358: _pw.pw_shell += (int)result; 359: return(&_pw); 360: } 361: 362: getb(f, p, n) 363: register int f, n; 364: register char *p; 365: { 366: int i; 367: 368: while (n) 369: { 370: i = read(f, p, n); 371: if (i <= 0) 372: return; 373: p += i; 374: n -= i; 375: } 376: } 377: 378: sewer() 379: { 380: register int pid, ourpid = getpid(); 381: 382: if (inited == ourpid) 383: return; 384: if (inited) 385: { 386: close(SEND_FD); 387: close(RECV_FD); 388: } 389: pipe(W); 390: pipe(R); 391: pid = vfork(); 392: if (pid == 0) 393: { /* child */ 394: alarm(0); /* cancel alarms */ 395: dup2(W[0], 0); /* parent write side to our stdin */ 396: dup2(R[1], 1); /* parent read side to our stdout */ 397: close(SEND_FD); /* copies made, close the... */ 398: close(RECV_FD); /* originals now */ 399: execl(_PATH_CTIMED, "ctimed", 0); 400: _exit(EX_OSFILE); 401: } 402: if (pid == -1) 403: abort(); /* nothing else really to do */ 404: close(W[0]); /* close read side of SEND channel */ 405: close(R[1]); /* close write side of RECV channel */ 406: inited = ourpid; /* don't do this again in this proc */ 407: } 408: 409: XXctime() 410: { 411: 412: if (SEND_FD) 413: close(SEND_FD); 414: if (RECV_FD) 415: close(RECV_FD); 416: SEND_FD = RECV_FD = 0; 417: inited = 0; 418: } 419: #endif /* BSD2_10 */