home *** CD-ROM | disk | FTP | other *** search
- /*
- * xfs.c -- extended file system for master v5.7
- * Author : Edgar Röder
- * Created On : Mon Apr 30 13:18:06 1990
- * Last Modified By: Edgar Roeder
- * Last Modified On: Mon Sep 3 19:25:16 1990
- * Update Count : 134
- * Status : should work now, needs some speedup
- *
- * HISTORY
- * 25-May-1990 Edgar Röder
- * Last Modified: Fri May 25 22:31:12 1990 #127 (Edgar Röder)
- * removed almost all debug output and canonicalize()-calls
- * put dta_getname in module_header, so other programs (!= Master)
- * can find it there
- *
- * 8-May-1990 Edgar Röder
- * Last Modified: Tue May 8 21:11:36 1990 #114 (Edgar Röder)
- * disable dta_getname while dispatcher is active
- *
- * 8-May-1990 Edgar Röder
- * Last Modified: Tue May 8 15:29:08 1990 #107 (Edgar Röder)
- * reset magic number in dta at the end of Fsnext
- * add glob to do filename matching
- * removed some debugging output and made cacheing configurable
- *
- * 7-May-1990 Edgar Röder
- * Last Modified: Sun May 6 23:04:48 1990 #91 (Edgar Röder)
- * added Fforce and Fdup support
- *
- * 6-May-1990 Edgar Röder
- * Last Modified: Sun May 6 00:21:32 1990 #90 (Edgar Röder)
- * added _unx2dos call in xfs_opendir to get an absolute path
- * use XFSMODE environment variable to allow different unixmodes
- * for xfs and application programs (they could use mode == "cu")
- *
- * 4-May-1990 Edgar Röder
- * Last Modified: Fri May 4 14:55:46 1990 #74 (Edgar Röder)
- * added rewinddir if directory was already open
- * added read/write/lseek for device manipulation
- *
- * 4-May-1990 Edgar Röder
- * Last Modified: Fri May 4 02:13:34 1990 #71 (Edgar Röder)
- * if directory was already open, use that structure
- *
- * 4-May-1990 Edgar Röder
- * Last Modified: Fri May 4 01:57:04 1990 #69 (Edgar Röder)
- * added special case for deleted files (pattern is 0xE5)
- *
- * 4-May-1990 Edgar Röder
- * changed data structure to record pattern and search attribute
- *
- */
- #include <signal.h>
- #include <stdlib.h>
- #include <basepage.h>
- #include <string.h>
- #include <osbind.h>
- #include <xbra.h>
- #include <sysvars.h>
- #include <errno.h>
- #include <dirent.h>
- #include <stdio.h>
- #include <setjmp.h>
- #include <stat.h>
- #include <device.h>
-
- /* to enable debug output define TRACING to 1 */
- #define TRACING 1 /* enable debug output */
- /* if you use the GNU-malloc */
- /*undef GNU_MALLOC /* enable malloc statistics */
- /* directory cacheing might interfere with Ddelete and Fdelete */
- /*undef DIR_CACHE /* enable directory cacheing */
- /* if we don't use glob, we pretend that Fsfirst is either called with */
- /* a full filename or with *.* */
- #define USE_GLOB /* enable complex search patterns */
-
- #ifdef bool
- #undef bool
- #endif
-
- typedef short bool;
-
- BASEPAGE *master = (BASEPAGE *) 0;
- char *master_var;
-
- #define kByte * 1024L
-
- static char __patch_stack[] = "{PatchVar}stack = %ld bytes";
- extern long _initial_stack = 100 kByte;
- static char __patch_var_format[] = "{PatchVar}default for unixmode = %15s";
- static char __default_unixmode[16] = "/.,LAHdb\0\0\0\0\0\0\0";
- extern char *_default_unixmode = __default_unixmode;
- extern char _tCASE;
- extern char _tDOTS;
- extern char _tSLASH;
- extern char _tUNLIMITED;
- extern char *_ltoa();
- extern long modul(const char *);
- extern char *dta_getname(struct _dta *);
-
- typedef struct {
- char *master_name;
- short function_type;
- long (*function_entry)(const char *cmdline);
- } func;
-
- func module_entries[] = {
- { "XFS", 0, modul }
- };
-
- #define _MODUL_MAGIC 0x58465332L /* 'XFS1' */
- #define _MMX_MAGIC 0x4D4D5845L /* 'MMXE' */
- #define _XFS_VERSION 2
-
- typedef char *(dta_func)(struct _dta *);
-
- struct head {
- char *module_description;
- short module_version;
- short number_of_functions;
- func *jump_table;
- long module_magic;
- long xbra_magic; /* 'XBRA' */
- long mmx_magic; /* 'MMXE' */
- xptr next;
- short jump;
- dta_func *this;
- } module_header = {
- " Master-Module-eXtension eXtended File System V1.1 ("
- __DATE__ " " __TIME__ ")\r\n"
- "\n"
- " Usage | Explanation\r\n"
- " ------------------------+--------------------------\r\n"
- " xfs help | print this help message\r\n"
- #ifdef GNU_MALLOC
- " xfs stat | show memory statistics\r\n"
- #endif
- #if TRACING
- " xfs debug | enable/disable debug\r\n"
- #endif
- " xfs start | start new file system\r\n"
- " | and read $XFSMODE\r\n"
- " xfs stop | stop new file system\r\n"
- " xfs ln <new> <old> | install a symbolic link\r\n"
- "\n"
- " You should enable the file system with 'virgin 64'!\r\n"
- "",
- _XFS_VERSION,
- 1,
- module_entries,
- _MODUL_MAGIC,
- _XBRA_MAGIC,
- _MMX_MAGIC,
- (xptr) 0,
- _JMP_OPCODE,
- dta_getname
- };
-
- static char dospath[FILENAME_MAX];
- static char dospath2[FILENAME_MAX];
-
- #define WRITE(f, text) write(f, text, strlen(text))
-
- #ifdef GNU_MALLOC
- /* Statistics available to the user. */
- struct mstats
- {
- size_t bytes_total; /* Total size of the heap. */
- size_t chunks_used; /* Chunks allocated by the user. */
- size_t bytes_used; /* Byte total of user-allocated chunks. */
- size_t chunks_free; /* Chunks in the free list. */
- size_t bytes_free; /* Byte total of chunks in the free list. */
- };
-
- /* Pick up the current statistics. */
- extern struct mstats mstats();
-
- void
- memory_statistics()
- {
- struct mstats ms;
- char output[30];
-
- ms = mstats();
- WRITE(1, "Memory-Statistics:\r\n\theapsize\t= ");
- _ltoa(ms.bytes_total, output, 10);
- WRITE(1, output);
- WRITE(1, "\r\n\tchunks used\t= ");
- _ltoa(ms.chunks_used, output, 10);
- WRITE(1, output);
- WRITE(1, "\r\n\tbytes used\t= ");
- _ltoa(ms.bytes_used, output, 10);
- WRITE(1, output);
- WRITE(1, "\r\n\tchunks free\t= ");
- _ltoa(ms.chunks_free, output, 10);
- WRITE(1, output);
- WRITE(1, "\r\n\tbytes free\t= ");
- _ltoa(ms.bytes_free, output, 10);
- WRITE(1, output);
- write(1, "\r\n", 2);
- }
- #endif
-
- #if TRACING
- /* use BIOS i/o for debugging output since we might get called from GEM */
- static short debugging = 0;
- static char output[80];
-
- void
- Bconws(const char *str)
- {
- if(!debugging) return;
- while(*str) {
- if(*str == '\n') Bconout(CON, '\r');
- Bconout(CON, *str++);
- }
- }
- #endif
-
- #define DIR_MAGIC 0x4653 /* 'FS' */
- #define DIR_STRUCT 0
- #define SINGLE_FILE 1
-
- struct Directory {
- short magic;
- char type;
- unsigned char search_attribute;
- char *path;
- char *pattern;
- union {
- DIR *dir;
- struct stat *statbuf;
- } contents;
- };
-
- static bool dispatcher_active = 1;
-
- /*
- * The reserved part of the dta buffer is used to pass information
- * from Fsfirst to Fsnext and dta_getname.
- * The layout is as follows:
- *
- * 0 +--------+
- * | 'XFS1' | ---> validate information
- * 4 +--------+
- * | DIRECT | ---> pointer to directory structure
- * 8 +--------+
- * | |
- * 12 +--------+
- * | OFFSET | ---> current position in directory
- * 16 +--------+
- * :
- * 43 +--------+
- * | 'x' | ---> validate information
- * 44 +--------+
- *
- * All other fields are unchanged.
- */
-
- char *
- dta_getname(struct _dta *dta)
- {
- struct Directory *dir;
- off_t dirpos;
- struct dirent *file;
-
- if(dispatcher_active & 1) return(dta->dta_name);
- #if TRACING
- if(*((long *) &(dta->dta_buf[0])) != _MODUL_MAGIC) {
- Bconws("dta_getname: magic num XFS1 not found\n");
- goto go_out;
- }
- if(dta->dta_name[13] != 'x') {
- Bconws("dta_getname: name[13] != 'x'\n");
- goto go_out;
- }
- if(!(dir = *((struct Directory **) &(dta->dta_buf[4])))) {
- Bconws("dta_getname: no Directory struct\n");
- goto go_out;
- }
- if(dir->magic != DIR_MAGIC) {
- Bconws("dta_getname: magic num FS not found\n");
- go_out:
- return(dta->dta_name);
- }
- #else
- if(*((long *) &(dta->dta_buf[0])) != _MODUL_MAGIC ||
- (dta->dta_name[13] != 'x') ||
- !(dir = *((struct Directory **) &(dta->dta_buf[4]))) ||
- (dir->magic != DIR_MAGIC))
- return(dta->dta_name);
- #endif
- if(dir->type == SINGLE_FILE) return(dir->pattern);
- dirpos = *((short *) &(dta->dta_buf[12]));
- seekdir(dir->contents.dir, dirpos);
- file = readdir(dir->contents.dir);
- if(!file) return(dta->dta_name);
- return(file->d_name);
- }
-
- extern xptr m_set_dtaname(void (*)());
- extern char *m_getenv(const char *);
-
- void
- start_xfs()
- {
- char *unixmode = m_getenv("XFSMODE");
-
- if(unixmode) _set_unixmode(unixmode);
- else if(errno == EINVAL) _set_unixmode(_default_unixmode);
- errno = ENOERR;
- if(!dispatcher_active) return;
- module_header.next = m_set_dtaname(_XBRA_VEC(module_header));
- dispatcher_active = 0;
- }
-
- void
- stop_xfs()
- {
- if(dispatcher_active) return;
- dispatcher_active = 1;
- m_set_dtaname((void (*)()) module_header.next);
- }
-
- long
- modul(const char *cmdlin)
- {
- int retval;
-
- if(!*cmdlin) {
- return(0);
- } else if(!strcmp(cmdlin, "help")) {
- WRITE(1, module_header.module_description);
- #ifdef GNU_MALLOC
- } else if(!strcmp(cmdlin, "stat")) {
- memory_statistics();
- #endif
- #if TRACING
- } else if(!strcmp(cmdlin, "debug")) {
- debugging = !debugging;
- #endif
- } else if(!strcmp(cmdlin, "start")) {
- start_xfs();
- } else if(!strcmp(cmdlin, "stop")) {
- stop_xfs();
- } else if(!strcmp(cmdlin, "ln")) {
- char *old, *new;
-
- strcpy(dospath, cmdlin);
- new = strtok(dospath, " \t");
- old = strtok(NULL, " \t");
- if(!old || !new) return(1);
- if(symlink(old, new)) {
- retval = -errno;
- errno = ENOERR;
- return(retval);
- }
- }
- return(0);
- }
-
- struct head *current;
-
- static long my_cookies[16] = {
- _MODUL_MAGIC, (long) &module_header,
- 0L, 8L
- };
-
- void
- remove_cookies()
- {
- set_sysvar_to_long(_p_cookies, 0L);
- }
-
- void
- remove_cookie()
- {
- long *cp;
-
- if(cp = (long *) get_sysvar(_p_cookies)) {
- while(*cp && *cp != _MODUL_MAGIC) cp += 2;
- while(*cp) {
- cp[0] = cp[2];
- cp[1] = cp[3];
- cp += 2;
- }
- }
- }
-
- #define SUPERBIT (1L << 13)
- #define DCREATE 57
- #define DDELETE 58
- #define DSETPATH 59
- #define FCREATE 60
- #define FOPEN 61
- #define FCLOSE 62
- #define FREAD 63
- #define FWRITE 64
- #define FDELETE 65
- #define FSEEK 66
- #define FATTRIB 67
- #define FDUP 69
- #define FFORCE 70
- #define DGETPATH 71
- #define PEXEC 75
- #define FSFIRST 78
- #define FSNEXT 79
- #define FRENAME 86
- #define FDATIME 87
-
- static long trap1_dispatcher(char *);
- static long new_trap1(long);
-
- static xbra_struct Trap1 = _TRAP_INIT(new_trap1);
-
- static jmp_buf oldTrap;
-
- static long
- new_trap1(long arg)
- {
- char *sp;
- register long ret;
-
- if(dispatcher_active & 1) goto old_trap1;
- /* ATTENTION: setjmp uses trap #1, so we have to disable this now */
- dispatcher_active = 1;
- if(setjmp(oldTrap)) {
- dispatcher_active = 0;
- old_trap1:
- asm("movel %0, sp" :: "g" (&arg));
- asm("jmp %0@" :: "a" (Trap1.next));
- }
- if(*((short *) &arg) & SUPERBIT) {
- sp = ((char *) &arg) + 6;
- } else {
- asm("movel usp, %0" : "=a" (sp));
- }
- /* now sp points to our argument list */
- ret = trap1_dispatcher(sp);
- dispatcher_active = 0;
- asm("movel %0, sp" :: "g" (&arg));
- /* for the next asm to work,*/
- /* ret should better not be */
- /* addressed relative to sp */
- asm("movel %0, d0" :: "d" (ret));
- asm("rte");
- }
-
- extern int _unx2dos(const char * const, char * const);
- extern int _dos2unx(const char * const, char * const);
-
- #ifdef strcpy
- #undef strcpy
- #endif
-
- extern DIR *__opendir_chain;
-
- static void
- xfs_closedir(struct Directory *dir)
- {
- if(!dir || dir->magic != DIR_MAGIC) return;
- free(dir->path);
- free(dir->pattern);
- if(dir->type == SINGLE_FILE) free(dir->contents.statbuf);
- else closedir(dir->contents.dir);
- }
-
- static inline struct Directory *
- xfs_opendir(const char *path, struct Directory *old_dir)
- {
- char *pattern;
- struct Directory *dd;
- struct stat *st;
-
- if((!(dd = old_dir) || (old_dir->magic != DIR_MAGIC)) &&
- !(dd = malloc((size_t)sizeof(struct Directory)))) {
- errno = ENOMEM;
- return NULL;
- }
- strcpy(dospath, path);
- do {
- if(!(pattern = strrchr(dospath, '\\')) &&
- !(pattern = strrchr(dospath, '/'))) {
- pattern = dospath;
- } else {
- *pattern++ = '\0';
- }
- } while(pattern != dospath && !*pattern);
- #ifdef CACHE_DIR
- /* this cacheing of open directories is problematic, since */
- /* deleted files will still be listed */
- if((dd == old_dir) && !strcmp(dospath, dd->path)
- && !strcmp(pattern, dd->pattern)) {
- if(dd->type == DIR_STRUCT) rewinddir(dd->contents.dir);
- return(dd);
- } else
- #endif
- xfs_closedir(old_dir);
- dd->magic = DIR_MAGIC;
- dd->path = strdup(dospath);
- dd->pattern = strdup(pattern);
- #ifdef USE_GLOB
- /* look for glob-metacharacters in pattern */
- if(glob(pattern, "*[*?[\\]{}]*"))
- #else
- if(!strcmp(pattern, "*.*"))
- #endif
- {
- if(pattern == dospath) strcpy(dospath, ".");
- if(!*dospath) strcpy(dospath, "\\");
- dd->type = DIR_STRUCT;
- if(!(dd->contents.dir = opendir(dospath))) {
- xfs_closedir(dd);
- free(dd);
- return(NULL);
- }
- } else {
- #ifndef USE_GLOB
- /* FIXME: for now assume that pattern is either *.* or */
- /* a normal filename (exclude things like a*.b), could */
- /* be done with glob() */
- #endif
- dd->type = SINGLE_FILE;
- if(!(st = malloc((size_t)sizeof(struct stat)))) {
- errno = ENOMEM;
- free(dd->path);
- free(dd->pattern);
- free(dd);
- return NULL;
- }
- dd->contents.statbuf = st;
- if(pattern != dospath) pattern[-1] = '\\';
- if(stat(dospath, st) < 0) {
- errno = ENOENT;
- xfs_closedir(dd);
- return NULL;
- }
- }
- return(dd);
- }
-
- static dev_t forced_standard_handle[3];
-
- static long
- trap1_dispatcher(char *sp)
- {
- long ret;
- int save_errno;
- char *path;
- char save_tSLASH;
- struct _device *device;
- struct _dta *dtabuf;
-
- save_errno = errno;
- errno = ENOERR;
- path = *((char **) &sp[2]);
- switch(*((short *) sp)) {
- case DCREATE :
- ret = mkdir(path);
- break;
- case DDELETE :
- ret = rmdir(path);
- break;
- case DSETPATH :
- ret = chdir(path);
- break;
- case FCREATE :
- ret = creat(path, 0644);
- break; /* does not support file modes */
- case FOPEN :
- ret = open(path, *((short *) &sp[6]));
- break;
- case FCLOSE : {
- short fd;
-
- fd = *((short *) &sp[2]);
- if(fd >= 0 && fd <= 2 && forced_standard_handle[fd])
- fd = forced_standard_handle[fd];
- ret = close(fd);
- break;
- }
- case FREAD : {
- short fd;
-
- fd = *((short *) &sp[2]);
- if(fd >= 0 && fd <= 2 && forced_standard_handle[fd])
- fd = forced_standard_handle[fd];
- ret = read(fd, *((void **) &sp[8]), *((long *) &sp[4]));
- break;
- }
- case FWRITE : {
- short fd;
-
- fd = *((short *) &sp[2]);
- if(fd >= 0 && fd <= 2 && forced_standard_handle[fd])
- fd = forced_standard_handle[fd];
- ret = write(fd, *((void **) &sp[8]), *((long *) &sp[4]));
- break;
- }
- case FDELETE : /* may get trouble if file is open */
- ret = unlink(path);
- break;
- case FSEEK : {
- short fd;
-
- fd = *((short *) &sp[2]);
- if(fd >= 0 && fd <= 2 && forced_standard_handle[fd])
- fd = forced_standard_handle[fd];
- ret = lseek(*((short *) &sp[6]), fd,
- *((short *) &sp[8]));
- break;
- }
- case FATTRIB :
- _unx2dos(path, dospath);
- *((char **) &sp[2]) = dospath;
- goto do_old_trap;
- case FDUP : {
- short fd;
-
- fd = *((short *) &sp[2]);
- if(fd >= 0 && fd <= 2 &&
- (ret = forced_standard_handle[fd])) break;
- goto do_old_trap;
- }
- case FFORCE : {
- short std_fd = *((short *) &sp[2]);
- short nstd_fd = *((short *) &sp[4]);
-
- if(std_fd == 0) {
- if((device = _dev_devnum(nstd_fd)) &&
- device->d_read) {
- forced_standard_handle[0] = nstd_fd;
- ret = 0;
- break;
- } else {
- forced_standard_handle[0] = 0;
- goto do_old_trap;
- }
- } else if(std_fd == 1 || std_fd == 2) {
- if((device = _dev_devnum(nstd_fd)) &&
- device->d_write) {
- forced_standard_handle[std_fd] = nstd_fd;
- ret = 0;
- break;
- } else {
- forced_standard_handle[std_fd] = 0;
- goto do_old_trap;
- }
- }
- goto do_old_trap;
- }
- case DGETPATH : {
- short drive;
- short save_drive;
-
- drive = *((short *) &sp[6]);
- if (!drive) dospath[0] = Dgetdrv() + 'A';
- else dospath[0] = drive - 1 + 'A';
- dospath[1] = ':';
- ret = Dgetpath(dospath+2, drive);
- save_tSLASH = _tSLASH;
- _tSLASH = 0;
- _dos2unx(dospath, dospath2);
- _tSLASH = save_tSLASH;
- if (dospath2[0] && dospath2[1] == ':')
- strcpy(path, dospath2+2);
- else
- strcpy(path, dospath2);
- break;
- }
- case PEXEC : {
- char *path;
-
- path = *((char **) &sp[4]);
- _unx2dos(path, dospath);
- *((char **) &sp[4]) = dospath;
- goto do_old_trap;
- }
- case FSFIRST : {
- struct Directory *dir;
-
- if((*path == '\345') || (*((short *) &sp[6]) & 0x08))
- goto do_old_trap;
- dtabuf = (struct _dta *) Fgetdta();
- if(*((long *) &(dtabuf->dta_buf[0])) == _MODUL_MAGIC)
- dir = *((struct Directory **)
- &(dtabuf->dta_buf[4]));
- else dir = NULL;
- if(!(dir = xfs_opendir(path, dir))) break;
- dir->search_attribute = (*((short *) &sp[6]) | 0x21)
- & 0xFF;
- dtabuf = (struct _dta *) Fgetdta();
- *((long *) &(dtabuf->dta_buf[0])) = _MODUL_MAGIC;
- *((struct Directory **) &(dtabuf->dta_buf[4])) = dir;
- if(dir->type == DIR_STRUCT)
- *((long *) &(dtabuf->dta_buf[12])) =
- telldir(dir->contents.dir);
- }
- case FSNEXT : {
- struct Directory *dir;
- long dirpos;
-
- dtabuf = (struct _dta *) Fgetdta();
- if(*((long *) &(dtabuf->dta_buf[0])) != _MODUL_MAGIC) {
- #if TRACING
- Bconws("Fsnext: magic num XFS1 not found\n");
- #endif
- errno = EINVAL;
- break;
- }
- dir = *((struct Directory **) &(dtabuf->dta_buf[4]));
- if(!dir || (dir->magic != DIR_MAGIC)) {
- #if TRACING
- Bconws("Fsnext: directory struct invalid\n");
- #endif
- errno = EINVAL;
- break;
- }
- if(dir->type == SINGLE_FILE) {
- union {
- DOSTIME dt;
- time_t tt;
- } ft;
-
- path = dir->pattern;
- ft.tt = dostime(dir->contents.statbuf->st_mtime);
- dtabuf->dta_attribute =
- dir->contents.statbuf->st_attr;
- dtabuf->dta_time = ft.dt.time;
- dtabuf->dta_date = ft.dt.date;
- dtabuf->dta_size =
- dir->contents.statbuf->st_size;
- } else {
- struct dirent *file;
-
- if(!dir->contents.dir) {
- #if TRACING
- Bconws("Fsnext: DIR not open\n");
- #endif
- errno = EINVAL;
- break;
- }
- dirpos = *((short *) &(dtabuf->dta_buf[14]));
- if(dirpos != telldir(dir->contents.dir))
- seekdir(dir->contents.dir, dirpos);
- #ifdef USE_GLOB
- do {
- #endif
- file = readdir(dir->contents.dir);
- #ifdef USE_GLOB
- /* we try as long as we have a valid */
- /* file, but no matching file */
- } while(
- file
- && !(
- /* a matching file would be any file */
- /* with attribute 0 or an attribute */ (!file->d_attribute
- /* matching the search attribute and */ || (file->d_attribute &
- dir->search_attribute))
- /* a name matching the searchpattern */ && (!strcmp(dir->pattern, "*.*") ||
- glob(file->d_name, dir->pattern)
- )
- )
- );
- #endif
- if(!file) {
- errno = ENMFILES;
- break;
- }
- path = file->d_name;
- dtabuf->dta_attribute = file->d_attribute;
- dtabuf->dta_time = file->d_time;
- dtabuf->dta_date = file->d_date;
- dtabuf->dta_size = file->d_size;
- }
- if(!strcmp(path, ".") || !strcmp(path, "..")) {
- strcpy(dtabuf->dta_name, path);
- } else {
- _unx2dos(path, dospath);
- strcpy(dtabuf->dta_name,
- strrchr(dospath, '\\') + 1);
- }
- *((long *) &(dtabuf->dta_buf[0])) = _MODUL_MAGIC;
- *((struct Directory **) &(dtabuf->dta_buf[4])) = dir;
- if(dir->type == DIR_STRUCT) {
- dirpos = (dirpos << 16) |
- telldir(dir->contents.dir) & 0x0000FFFFL;
- /* offset 12 used to make st_inode() happy */
- *((long *) &(dtabuf->dta_buf[12])) = dirpos;
- }
- dtabuf->dta_name[13] = 'x';
- ret = 0;
- errno = ENOERR;
- break;
- }
- case FRENAME :
- ret = rename(path, *((char **) &sp[6]));
- break;
- default :
- do_old_trap: errno = save_errno;
- longjmp(oldTrap, 1);
- }
- if(errno) ret = - errno;
- errno = save_errno;
- return(ret);
- }
-
- #define TRAP1 33
-
- void
- init_module(void)
- {
- signal(SIGINT, SIG_IGN);
- signal(SIGQUIT, SIG_IGN);
- signal(SIGTSTP, SIG_IGN);
- Trap1.gnuc_magic = _MODUL_MAGIC;
- Trap1.next = (xptr) Setexc(TRAP1, _TRAP_VEC(TRAP1, Trap1));
- }
-
- void
- finish_module(void)
- {
- stop_xfs();
- unlink_handler(&Trap1, TRAP1);
- }
-
- void
- install_cookie(int resident)
- {
- long *cp;
- long cookies_used = 0;
- long tmp;
-
- if(!(cp = (long *) get_sysvar(_p_cookies))) {
- if(!resident) {
- write(2, "Unable to install cookie!\r\n", 27);
- exit(1);
- }
- signal(SIGRESET, remove_cookies);
- set_sysvar_to_long(_p_cookies, (long)(cp = my_cookies));
- }
- while(*cp && *cp != _MODUL_MAGIC) {
- cp += 2;
- cookies_used++;
- }
- if(*cp) {
- current = (struct head *) cp[1];
- if(current == &module_header) init_module();
- return;
- }
- if(!(cp[1] - cookies_used - 1)) {
- write(2, "No room for cookie!\r\n", 21);
- exit(1);
- }
- *cp++ = _MODUL_MAGIC;
- tmp = *cp;
- *cp++ = (long) (current = &module_header);
- *cp++ = 0L;
- *cp = tmp;
- init_module();
- return;
- }
-
- void
- install_module(int resident, char *firstcmd)
- {
- long keep;
-
- install_cookie(resident);
- if(master) {
- strcpy(master_var, "Master-Module ");
- _ltoa(current, master_var+14, 10);
- }
- if(current != &module_header) {
- (*(current->jump_table[0].function_entry))(firstcmd);
- exit(0);
- }
- if(!*firstcmd) modul("help");
- else modul(firstcmd);
- if(!resident) return;
- keep = _base->p_tlen + _base->p_dlen + _base->p_blen
- + sizeof(BASEPAGE) + _initial_stack;
- _base -= 2;
- Ptermres(keep, 0);
- }
-
- void
- remove_module()
- {
- finish_module();
- remove_cookie();
- }
-
- void
- usage(char *prog)
- {
- write(2, "Usage: [ module ] ", 18);
- WRITE(2, prog);
- write(2, " [ <cmd> ]\r\n", 12);
- exit(2);
- }
-
- main(int argc, char *argv[])
- {
- char *mmx;
- BASEPAGE *caller;
- char *prog;
- char *firstcmd;
-
- if(**argv) prog = *argv;
- else prog = "xfs";
- argc--;
- argv++;
- if(argc) {
- firstcmd = *argv;
- argc--;
- argv++;
- } else firstcmd = "";
- if(argc) usage(prog);
- if(mmx = getenv("MMX")) {
- if(strncmp(mmx, "Master-Call", 11)) exit(1);
- mmx += 11;
- if(!(master = (BASEPAGE *) strtol(mmx, &mmx, 10)) ||
- !(master_var = (char *) strtol(mmx, &mmx, 10)) ||
- !(caller = (BASEPAGE *) strtol(mmx, &mmx, 10)) ||
- (caller != _base->p_parent))
- exit(1);
- install_module(1, firstcmd);
- } else if(!system(NULL)) install_module(1, firstcmd);
- install_module(0, firstcmd);
- system("-i");
- remove_module();
- }
-