|
|
1.1 ! root 1: /* osk.c */ ! 2: ! 3: /* ------------------------------------------------------------------- * ! 4: | ! 5: | OS9Lib: stat(), fstat() ! 6: | ! 7: | ! 8: | Copyright (c) 1988 by Wolfgang Ocker, Puchheim, ! 9: | Ulli Dessauer, Germering and ! 10: | Reimer Mellin, Muenchen ! 11: | (W-Germany) ! 12: | ! 13: | This programm can be copied and distributed freely for any ! 14: | non-commercial purposes. It can only be incorporated into ! 15: | commercial software with the written permission of the authors. ! 16: | ! 17: | If you should modify this program, the authors would appreciate ! 18: | a notice about the changes. Please send a (context) diff or the ! 19: | complete source to: ! 20: | ! 21: | address: Wolfgang Ocker ! 22: | Lochhauserstrasse 35a ! 23: | D-8039 Puchheim ! 24: | West Germany ! 25: | ! 26: | e-mail: [email protected], [email protected], [email protected] ! 27: | pyramid!tmpmbx!recco!weo ! 28: | pyramid!tmpmbx!nitmar!ud ! 29: | pyramid!tmpmbx!ramsys!ram ! 30: | ! 31: * ----------------------------------------------------------------- */ ! 32: ! 33: #ifdef OSK ! 34: ! 35: #define PATCHLEVEL 1 ! 36: ! 37: #include <module.h> ! 38: #include <sgstat.h> ! 39: #include <sg_codes.h> ! 40: #include <direct.h> ! 41: #ifndef ELVPRSV ! 42: #include <stdio.h> ! 43: #include <errno.h> ! 44: #include <modes.h> ! 45: #include <signal.h> ! 46: #include "config.h" ! 47: #endif ! 48: #include "osk.h" ! 49: ! 50: #define TIME(secs) (((secs << 8) / 10) | 0x80000000) ! 51: ! 52: /* ! 53: * f s t a t ! 54: */ ! 55: int fstat(fd, buff) ! 56: int fd; ! 57: struct stat *buff; ! 58: { ! 59: struct fildes ftmp; ! 60: struct tm ttmp; ! 61: struct _sgr fopt; ! 62: ! 63: if (_gs_gfd(fd, &ftmp, 16) < 0) /* 16 insteat of sizeof(struct fildes) */ ! 64: return(-1); /* used due to a bug in stupid os9net */ ! 65: ! 66: if (_gs_opt(fd, &fopt) < 0) ! 67: return(-1); ! 68: ! 69: ttmp.tm_year = (int) ftmp.fd_date[0]; ! 70: ttmp.tm_mon = (int) ftmp.fd_date[1] - 1; ! 71: ttmp.tm_mday = (int) ftmp.fd_date[2]; ! 72: ttmp.tm_hour = (int) ftmp.fd_date[3]; ! 73: ttmp.tm_min = (int) ftmp.fd_date[4]; ! 74: ttmp.tm_sec = 0; ! 75: ttmp.tm_isdst = -1; ! 76: ! 77: buff->st_atime = buff->st_mtime = mktime(&ttmp); ! 78: ! 79: ttmp.tm_year = (int) ftmp.fd_dcr[0]; ! 80: ttmp.tm_mon = (int) ftmp.fd_dcr[1] - 1; ! 81: ttmp.tm_mday = (int) ftmp.fd_dcr[2]; ! 82: ttmp.tm_hour = ttmp.tm_min = ttmp.tm_sec = 0; ! 83: ttmp.tm_isdst = -1; ! 84: ! 85: buff->st_ctime = mktime(&ttmp); ! 86: ! 87: memcpy(&(buff->st_size), ftmp.fd_fsize, sizeof(long)); /* misalignment! */ ! 88: buff->st_uid = ftmp.fd_own[1]; ! 89: buff->st_gid = ftmp.fd_own[0]; ! 90: buff->st_mode = ftmp.fd_att; ! 91: buff->st_nlink = ftmp.fd_link; ! 92: ! 93: buff->st_ino = fopt._sgr_fdpsn; ! 94: buff->st_dev = fopt._sgr_dvt; ! 95: ! 96: return(0); ! 97: } ! 98: ! 99: /* ! 100: * s t a t ! 101: */ ! 102: int stat(filename, buff) ! 103: char *filename; ! 104: struct stat *buff; ! 105: { ! 106: register int i, ret; ! 107: ! 108: if ((i = open(filename, S_IREAD)) < 0) ! 109: if ((i = open(filename, S_IFDIR | S_IREAD)) < 0) ! 110: return(-1); ! 111: ! 112: ret = fstat(i, buff); ! 113: close(i); ! 114: ! 115: return(ret); ! 116: } ! 117: ! 118: /* ! 119: unix library functions mist in OSK ! 120: Author: Peter Reinig ! 121: */ ! 122: ! 123: ! 124: typedef (*procref)(); ! 125: #define MAX_SIGNAL 10 ! 126: ! 127: extern exit(); ! 128: ! 129: static int (*sig_table[MAX_SIGNAL])(); ! 130: static int _sig_install = 0; ! 131: ! 132: sig_handler(sig) ! 133: int sig; ! 134: { ! 135: if ((int) sig_table[sig] > MAX_SIGNAL) ! 136: sig_table[sig](sig); ! 137: } ! 138: ! 139: procref signal(sig,func) ! 140: int sig; ! 141: int (*func)(); ! 142: { ! 143: int i, (*sav)(); ! 144: ! 145: if (!_sig_install) { ! 146: for (i=0; i < MAX_SIGNAL; i++) ! 147: sig_table[i] = exit; ! 148: _sig_install = 1; ! 149: intercept(sig_handler); ! 150: } ! 151: sav = sig_table[sig]; ! 152: switch ((int) func) { ! 153: case SIG_DFL : sig_table[sig] = exit; ! 154: break; ! 155: case SIG_IGN : sig_table[sig] = 0; ! 156: break; ! 157: default : sig_table[sig] = func; ! 158: break; ! 159: } ! 160: return sav; ! 161: } ! 162: ! 163: perror(str) ! 164: char *str; ! 165: { ! 166: static int path = 0; ! 167: if (!path && (path = open("/dd/sys/Errmsg", S_IREAD)) == -1) { ! 168: fprintf(stderr,"Can\'t open error message file\n"); ! 169: path = 0; ! 170: } ! 171: if (str && *str) { ! 172: fprintf(stderr,"%s: ",str); ! 173: fflush(stderr); ! 174: } ! 175: prerr(path,(short) errno); ! 176: } ! 177: ! 178: isatty(fd) ! 179: int fd; ! 180: { ! 181: struct sgbuf buffer; ! 182: char type; ! 183: ! 184: _gs_opt(fd,&buffer); ! 185: type = buffer.sg_class; ! 186: if (type == DT_SCF) ! 187: return 1; ! 188: else ! 189: return 0; ! 190: } ! 191: ! 192: static struct passwd pw; ! 193: static char line[128]; ! 194: ! 195: struct passwd *getpwuid(uid) ! 196: int uid; ! 197: { ! 198: FILE *fp; ! 199: register char *p, *q; ! 200: ! 201: if ((fp = fopen(PASSWD, "r")) == NULL) ! 202: return (struct passwd *) NULL; ! 203: while (fgets(line, sizeof(line), fp)) { ! 204: p = q = line; ! 205: while (*p && *p != ',') p++; ! 206: if (!*p) ! 207: continue; ! 208: *p = '\0'; ! 209: pw.pw_name = q; ! 210: q = ++p; ! 211: while (*p && *p != ',') p++; ! 212: if (!*p) ! 213: continue; ! 214: *p = '\0'; ! 215: pw.pw_passwd = q; ! 216: q = ++p; ! 217: while (*p && *p != '.') p++; ! 218: if (!*p) ! 219: continue; ! 220: *p = '\0'; ! 221: pw.pw_gid = atoi(q); ! 222: q = ++p; ! 223: while (*p && *p != ',') p++; ! 224: if (!*p) ! 225: continue; ! 226: *p = '\0'; ! 227: pw.pw_uid = atoi(q); ! 228: q = ++p; ! 229: if (uid != pw.pw_uid) ! 230: continue; ! 231: while (*p && *p != ',') p++; ! 232: if (!*p) ! 233: return (struct passwd *) NULL; ! 234: *p = '\0'; ! 235: pw.pw_prio = atoi(q); ! 236: q = ++p; ! 237: while (*p && *p != ',') p++; ! 238: if (!*p) ! 239: return (struct passwd *) NULL; ! 240: *p = '\0'; ! 241: pw.pw_xdir = q; ! 242: q = ++p; ! 243: while (*p && *p != ',') p++; ! 244: if (!*p) ! 245: return (struct passwd *) NULL; ! 246: *p = '\0'; ! 247: pw.pw_dir = q; ! 248: p++; ! 249: if (!*p) ! 250: return (struct passwd *) NULL; ! 251: pw.pw_shell = p; ! 252: while (*p++) ; ! 253: *(--p) = '\0'; ! 254: return &pw; ! 255: } ! 256: return (struct passwd *) NULL; ! 257: } ! 258: ! 259: /* This function is used to catch the alarm signal */ ! 260: static int dummy() ! 261: { ! 262: } ! 263: ! 264: /* This function implements read-with-timeout from the keyboard.*/ ! 265: int ttyread(buf, len, time) ! 266: char *buf; /* where to store the gotten characters */ ! 267: int len; /* maximum number of characters to read */ ! 268: int time; /* maximum time to allow for reading characters */ ! 269: { ! 270: REG int i; ! 271: int alrmid; ! 272: ! 273: /* are some characters available in the type-ahead buffer? */ ! 274: if ((i = _gs_rdy(0)) > 0) ! 275: { ! 276: /* some characters are available -- read them immediately */ ! 277: len = read(0, buf, i < len ? i : len); ! 278: } ! 279: else if (!time) /* reading with no timeout? */ ! 280: { ! 281: /* do a blocking read, with no timeout */ ! 282: do ! 283: len = read(0, buf, 1); ! 284: while (len < 0); ! 285: } ! 286: else ! 287: { ! 288: /* set an alarm and then do a blocking read */ ! 289: signal(SIGQUIT, dummy); ! 290: alrmid = alm_set(SIGQUIT, TIME(time)); ! 291: len = read(0, buf, 1); ! 292: alm_delete(alrmid); ! 293: } ! 294: return len; ! 295: } ! 296: ! 297: /* The code of getcwd, popen and pclose is taken from blarslib from Bob Larson */ ! 298: ! 299: /* Internet: [email protected] */ ! 300: /* StG: blarson@zog */ ! 301: /* Compuserve: [email protected] */ ! 302: ! 303: char *getcwd(p, n) ! 304: char *p; ! 305: int n; ! 306: { ! 307: register char *cp; ! 308: register struct dirent *dp; ! 309: register int l, olddot = 0, i, d, dot, dotdot; ! 310: struct dirent db[8]; ! 311: char buf[1024]; ! 312: ! 313: if(p==NULL) { ! 314: p = (char *)malloc((unsigned)n); ! 315: if(p==NULL) return NULL; ! 316: } ! 317: cp = &buf[1024-1]; ! 318: *cp = '\0'; ! 319: for(;;) { ! 320: if((d = open(".", S_IREAD | S_IFDIR)) < 0) { ! 321: if(*cp) chdir(cp+1); ! 322: return NULL; ! 323: } ! 324: if((i = read(d, (char *)db, sizeof(db))) == 0) { ! 325: if(*cp) chdir(cp+1); ! 326: close(d); ! 327: return NULL; ! 328: } ! 329: dotdot = db[0].dir_addr; ! 330: dot = db[1].dir_addr; ! 331: if(olddot) { ! 332: i -= 2 * sizeof(struct dirent); ! 333: dp = &db[2]; ! 334: for(;;) { ! 335: if(i <= 0) { ! 336: if((i = read(d, (char *)db, sizeof(db))) == 0) { ! 337: if(*cp) chdir(cp+1); ! 338: close(d); ! 339: return NULL; ! 340: } ! 341: dp = &db[0]; ! 342: } ! 343: if(olddot == dp->dir_addr) { ! 344: l = strlen(dp->dir_name); ! 345: /* last character has parity bit set... */ ! 346: *--cp = dp->dir_name[--l] & 0x7f; ! 347: while(l) *--cp = dp->dir_name[--l]; ! 348: *--cp = '/'; ! 349: break; ! 350: } ! 351: i -= sizeof(struct dirent); ! 352: dp++; ! 353: } ! 354: } ! 355: if(dot==dotdot) { ! 356: if(*cp) chdir(cp+1); ! 357: *p = '/'; ! 358: if(_gs_devn(d, p+1) < 0) { ! 359: close(d); ! 360: return NULL; ! 361: } ! 362: close(d); ! 363: if(n < (strlen(p) + strlen(cp))) return NULL; ! 364: strcat(p, cp); ! 365: return p; ! 366: } ! 367: close(d); ! 368: if(chdir("..") != 0) { ! 369: if(*cp) chdir(cp+1); ! 370: return NULL; ! 371: } ! 372: olddot = dot; ! 373: } ! 374: } ! 375: ! 376: extern char *environ; ! 377: extern int os9forkc(); ! 378: ! 379: static int proc[_NFILE]; ! 380: ! 381: /* This version of popen is derived from Robert B. Larson library blarslib * ! 382: /* and was modified by Peter Reinig to meet the needs of elvis */ ! 383: ! 384: FILE *popen(command, mode) ! 385: char *command; ! 386: char *mode; ! 387: { ! 388: int pipe; ! 389: ! 390: if (pipe = osk_popen(command, mode, 0, 1)) ! 391: return (fdopen(pipe, mode)); ! 392: else ! 393: return ((FILE*) NULL); ! 394: } ! 395: ! 396: mod_exec *mp = -1; ! 397: ! 398: int osk_popen(command, mode, in, as_popen) ! 399: char *command; ! 400: char *mode; ! 401: int in, as_popen; ! 402: { ! 403: int temp, fd, stdinp; ! 404: int pipe, pid; ! 405: char *argv[4]; ! 406: register char *cp; ! 407: static char namebuffer[128]; ! 408: static char module[128]; ! 409: ! 410: if(mode[1]!='\0' || (*mode!='r' && *mode!='w')) ! 411: return 0; ! 412: fd = (*mode=='r'); ! 413: if((temp = dup(fd)) <= 0) ! 414: return 0; ! 415: if((pipe = creat("/pipe", S_IREAD | S_IWRITE)) < 0) { ! 416: close(temp); ! 417: return 0; ! 418: } ! 419: close(fd); ! 420: dup(pipe); ! 421: if (in != 0) { ! 422: stdinp = dup(0); ! 423: close(0); ! 424: dup(in); ! 425: close(in); ! 426: } ! 427: argv[0] = "shell"; ! 428: argv[1] = "ex"; ! 429: argv[2] = command; ! 430: argv[3] = (char *)NULL; ! 431: strcpy(module, command); ! 432: cp = module; ! 433: while (*cp && *cp != ' ' && *cp != '\t') cp++; ! 434: *cp = '\0'; ! 435: mp = (mod_exec *)modloadp(module, (MT_PROGRAM << 8) + ML_ANY, namebuffer); ! 436: if((mp == (mod_exec*)-1) ! 437: || ((pid = os9exec(os9forkc, argv[0], argv, environ, 0, 0, 3)) < 0)) { ! 438: if (mp > 0) ! 439: munlink(mp); ! 440: mp = (mod_exec *) -1; ! 441: close(fd); ! 442: close(pipe); ! 443: dup(temp); ! 444: close(temp); ! 445: if (in != 0) { ! 446: close(0); ! 447: dup(stdinp); ! 448: } ! 449: return 0; ! 450: } ! 451: if (as_popen) ! 452: proc[pipe] = pid; ! 453: close(fd); ! 454: dup(temp); ! 455: close(temp); ! 456: if (in != 0) { ! 457: close(0); ! 458: dup(stdinp); ! 459: } ! 460: return pipe; ! 461: } ! 462: ! 463: int pclose(pipe) ! 464: FILE *pipe; ! 465: { ! 466: int p, stat, w; ! 467: ! 468: if((p = proc[fileno(pipe)]) <= 0) return -1; ! 469: proc[fileno(pipe)] = 0; ! 470: fflush(pipe); ! 471: fclose(pipe); ! 472: while((w = wait(&stat)) != -1 && w != p) ; ! 473: if (mp > 0) ! 474: munlink(mp); ! 475: mp = (mod_exec *) -1; ! 476: return w == -1 ? -1 : stat; ! 477: } ! 478: #endif /* OSK */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.