|
|
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.