/* * COMM2.C * * * (c)1986 Matthew Dillon Feb 1987 * * ABORTLINE * RETURN * STRHEAD * STRTAIL * IF * LABEL * GOTO * INC * INPUT * VER * CP * SHELLSTAT * SETENV * UNSETENV * IPC * CLDRES * */ #include "shell.h" #include #include #include typedef struct CommandLineInterface CLI; extern LOCK *CurrentDir(), *Lock(), *CreateDir(); extern IPCMSG *SendIPC(); do_cldres() { if (DResBase) CloseLibrary(DResBase); DResBase = NULL; } /* * do_ipc appname[.project] command */ do_ipc(command) char *command; { IPCMSG *msg; char *str = next_word(next_word(command)); char *ptr; char appname[64]; char *cmd; long result; if (!DResBase) DResBase = (long)OpenLibrary("dres.library", 0); if (!DResBase) { puts("Unable to open dres.library"); return(-1); } for (ptr = av[1]; *ptr && *ptr != '.'; ++ptr); if (*ptr == '.') { if (cmd = malloc(strlen(ptr+1)+strlen(str)+2)) { strcpy(cmd, ptr+1); strcpy(cmd + strlen(cmd) + 1, str); } } else { if (cmd = malloc(strlen(str)+2)) { cmd[0] = 0; strcpy(cmd+1, str); } } if (!cmd) return(-1); strcpy(appname, av[1]); appname[ptr - av[1]] = 0; strcat(appname, ".CMD"); msg = SendIPC(appname, cmd, strlen(cmd)+strlen(str)+2, 0); free(cmd); if (!msg) return(-1); WaitMsg(msg); if (msg->RFlags & IF_ERROR) { if (msg->RFlags & IF_NOAPP) printf("Application not found"); else printf("Operation Failed"); if (msg->RBuf) printf(": %s\n", msg->RBuf); puts(""); if (!msg->Error) msg->Error = 20; } else { if (msg->RBuf) Oputs(msg->RBuf); } result = msg->Error; FreeIPC(msg); return(result); } do_abortline() { Exec_abortline = 1; return (0); } do_return() { Exec_abortline = 1; if (Src_stack) { fseek (Src_base[Src_stack - 1], 0, 2); return ((ac < 2) ? 0 : atoi(av[1])); } else { main_exit ((ac < 2) ? 0 : atoi(av[1])); } } /* * STRHEAD * * place a string into a variable removing everything after and including * the 'break' character or until a space is found in the string. * * strhead varname breakchar string * */ do_strhead() { register char *str = av[3]; register char bc = *av[2]; while (*str && *str != bc) ++str; *str = '\0'; set_var (LEVEL_SET, av[1], av[3]); return (0); } do_strtail() { register char *str = av[3]; register char bc = *av[2]; while (*str && *str != bc) ++str; if (*str) ++str; set_var (LEVEL_SET, av[1], str); return (0); } /* * if A < B <, >, =, <=, >=, !=, where A and B are either: * nothing * a string * a value (begins w/ number) * * if -[!]f file * */ do_if(garbage, com) char *garbage; { register char *v1, *v2, *v3, result, num; register int n1, n2; switch (com) { case 0: if (If_stack && If_base[If_stack - 1]) { if (If_stack == MAXIF) { ierror(NULL, 510); } else { If_base[If_stack++] = 1; } break; } result = num = 0; v1 = av[1]; switch(ac) { case 2: /* if $var; */ if (v1[0] == 0 || (v1[1] == 0 && v1[0] == ' ')) goto do_result; result = 1; /* fall through */ case 1: /* if */ goto do_result; case 3: /* if -flag name */ if (*v1 == '-') ++v1; if (*v1 == '!') { ++v1; result = 1 - result; } switch(*v1) { case 'f': { LOCK *lock; mountrequest(0); if (lock = Lock(av[2], SHARED_LOCK)) { result = 1 - result; UnLock(lock); } mountrequest(1); } break; default: goto splug; } goto do_result; case 4: goto cond; } splug: ierror(NULL, 500); goto do_result; cond: v1 = av[1]; v2 = av[2]; v3 = av[3]; while (*v1 == ' ') ++v1; while (*v2 == ' ') ++v2; while (*v3 == ' ') ++v3; if (*v1 >= '0' && *v1 <= '9') { num = 1; n1 = atoi(v1); n2 = atoi(v3); } while (*v2) { switch (*v2++) { case '>': result |= (num) ? (n1 > n2) : (strcmp(v1, v3) > 0); break; case '<': result |= (num) ? (n1 < n2) : (strcmp(v1, v3) < 0); break; case '=': result |= (num) ? (n1 == n2) : (strcmp(v1, v3) ==0); break; default: ierror (NULL, 503); break; } } do_result: if (If_stack == MAXIF) ierror(NULL,510); else If_base[If_stack++] = !result; break; case 1: if (If_stack > 1 && If_base[If_stack - 2]) break; if (If_stack) If_base[If_stack - 1] ^= 1; break; case 2: if (If_stack) --If_stack; break; } SDisable = (If_stack) ? If_base[If_stack - 1] : 0; return (0); } do_label() { char aseek[32]; if (Src_stack == 0) { ierror (NULL, 502); return (-1); } sprintf (aseek, "%ld %ld", Src_pos[Src_stack-1], If_stack); set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek); return (0); } do_goto() { register long new; register long pos; register char *lab; if (Src_stack == 0) { ierror (NULL, 502); } else { lab = get_var (LEVEL_LABEL + Src_stack - 1, av[1]); if (lab == NULL) { ierror (NULL, 501); } else { pos = atoi(lab); fseek (Src_base[Src_stack - 1], pos, 0); Src_pos[Src_stack - 1] = pos; new = atoi(next_word(lab)); if (new > MAXIF) new = MAXIF; for (; If_stack < new; ++If_stack) If_base[If_stack] = 0; If_stack = new; } } Exec_abortline = 1; return (0); /* Don't execute rest of this line */ } do_inc(garbage, com) char *garbage; { register char *var; char num[32]; if (ac == 3) com = atoi(av[2]); var = get_var (LEVEL_SET, av[1]); if (var) { sprintf (num, "%ld", atoi(var)+com); set_var (LEVEL_SET, av[1], num); } return (0); } do_input() { char in[256]; if (Ogets(in)) set_var (LEVEL_SET, av[1], in); return (0); } do_ver() { Oputs (VERSION); return (0); } /* * CP file (to current directory) * CP [-r] dir (to current directory) * CP file file * CP file file file... destdir * CP [-r] dir dir dir... destdir */ do_cp() { register short recur, i, ierr; register char *destname; register char destisdir; register FIB *fib; char copysilent = (get_var(LEVEL_SET, V_COPYSILENT) != NULL); if (get_var(LEVEL_SET, V_COPYDATE) != NULL) copysilent |= 2; ierr = 0; fib = (FIB *)AllocMem(sizeof(FIB), 0); recur = (strncmp(av[1], "-r", 2)) ? 0 : 1; destname = av[ac - 1]; if (ac < recur + 3) { ++ac; destname = ""; } /* * ierr = 500; * goto done; */ destisdir = isdir(destname); if (ac > recur + 3 && !destisdir) { ierr = 507; goto done; } /* * copy set: reduce to: * file to file file to file * dir to file (NOT ALLOWED) * file to dir dir to dir * dir to dir dir to dir * */ for (i = recur + 1; i < ac - 1; ++i) { short srcisdir = isdir(av[i]); if (srcisdir) { struct FileLock *srcdir, *destdir; if (!destisdir) { /* disallow dir to file */ ierr = 507; goto done; } if (!(destdir = Lock(destname, ACCESS_READ))) { ierr = 205; goto done; } if (!(srcdir = Lock(av[i], ACCESS_READ))) { ierr = 205; UnLock(destdir); goto done; } ierr = copydir(srcdir, destdir, recur, copysilent, 1); UnLock(srcdir); UnLock(destdir); if (ierr) break; } else { /* FILE to DIR, FILE to FILE */ struct FileLock *destdir, *srcdir, *tmp; char *destfilename; srcdir = (struct FileLock *)((PROC *)FindTask(NULL))->pr_CurrentDir; if (destisdir) { if ((tmp = Lock(av[i], ACCESS_READ)) == NULL || !Examine(tmp,fib)){ if (tmp) UnLock(tmp); ierr = 205; goto done; } UnLock(tmp); destdir = Lock(destname, ACCESS_READ); destfilename = fib->fib_FileName; } else { destdir = srcdir; destfilename = destname; copysilent |= 1; } ierr = copyfile(av[i], srcdir, destfilename, destdir, copysilent, 0); if (destisdir) UnLock(destdir); if (ierr) break; } } done: FreeMem(fib, sizeof(*fib)); if (ierr) { ierror("cp", ierr); return(20); } return(0); } copydir(srcdir, destdir, recur, silent, tab) register struct FileLock *srcdir, *destdir; { LOCK *cwd; register FIB *srcfib; register LOCK *destlock, *srclock; DATESTAMP DS; int ierr; ierr = 0; srcfib = (FIB *)AllocMem(sizeof(FIB), 0); if (Examine(srcdir, srcfib)) { DS = srcfib->fib_Date; if (!(silent & 1)) printf("%*s%s (DIR)\n", tab, "", srcfib->fib_FileName); while (ExNext(srcdir, srcfib)) { if (srcfib->fib_DirEntryType < 0) { ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir,silent,tab+4); if (ierr) break; } else { if (recur) { cwd = CurrentDir(srcdir); if (srclock = Lock(srcfib->fib_FileName, ACCESS_READ)) { CurrentDir(destdir); if (!(destlock = Lock(srcfib->fib_FileName, ACCESS_READ))) { if (destlock = CreateDir(srcfib->fib_FileName)) { UnLock(destlock); if (silent & 2) { setfiledate(srcfib->fib_FileName, &DS); if (srcfib->fib_Comment[0]) SetComment(srcfib->fib_FileName, srcfib->fib_Comment); } destlock = Lock(srcfib->fib_FileName, ACCESS_READ); } } if (destlock) { ierr = copydir(srclock, destlock, recur, silent, tab+4); UnLock(destlock); } else { ierr = IoErr(); } UnLock(srclock); } else { ierr = IoErr(); } CurrentDir(cwd); if (ierr) break; } } } } else { ierr = IoErr(); } FreeMem(srcfib, sizeof(FIB)); return(ierr); } copyfile(srcname, srcdir, destname, destdir, silent, tab) char *srcname, *destname; struct FileLock *srcdir, *destdir; { LOCK *cwd; DATESTAMP DS; int i, ierr; char *buf; char *com = NULL; long buflen; long fhs, fhd; if (!(silent&1)) printf("%*s%s\n", tab, "", srcname); for (buflen = 65536; buflen; buflen >>= 1) { if (buf = AllocMem(buflen, MEMF_PUBLIC)) break; } if (buf == NULL) return(103); /* ERROR_NO_FREE_STORE */ ierr = 0; cwd = (LOCK *)CurrentDir(srcdir); if (silent & 2) { register FIB *fib = (FIB *)AllocMem(sizeof(FIB), MEMF_PUBLIC); register LOCK *lock = Lock(srcname, ACCESS_READ); if (lock && fib && Examine(lock, fib)) { if (fib->fib_Comment[0]) { com = malloc(strlen(fib->fib_Comment)+1); strcpy(com, fib->fib_Comment); } DS = fib->fib_Date; } else { silent &= ~2; } if (lock) UnLock(lock); if (fib) FreeMem(fib, sizeof(FIB)); } fhs = Open(srcname, 1005); if (fhs == NULL) { ierr = 205; goto fail; } CurrentDir(destdir); fhd = Open(destname, 1006); if (fhd == NULL) { ierr = IoErr(); Close(fhs); goto fail; } while ((i = Read(fhs, buf, buflen)) > 0) { if (CHECKBREAK()) { ierr = 509; break; } if (Write(fhd, buf, i) != i) { ierr = IoErr(); break; } if (CHECKBREAK()) { ierr = 509; break; } } if (i < 0) ierr = IoErr(); Close(fhd); Close(fhs); if (!ierr && (silent & 2)) { setfiledate(destname, &DS); if (com) SetComment(destname, com); } fail: if (com) free(com); FreeMem(buf, buflen); CurrentDir(cwd); return(ierr); } do_shellstat() { { register short i = 0; register unsigned long mask = ((TASK *)FindTask(NULL))->tc_SigAlloc; printf("Signals: %08lx ", mask); while (mask) { if (mask & 1) ++i; mask >>= 1; } printf("(%ld)\n", i); } /* { register PROC *proc = (PROC *)FindTask(NULL); register CLI *cli = (CLI *)((long)proc->pr_CLI << 2); if (proc) { long stack; printf("pr_TaskNum: %ld\n", proc->pr_TaskNum); printf("pr_CIS: %08lx\n", proc->pr_CIS); printf("pr_COS: %08lx\n", proc->pr_COS); printf("cli_standardinput : %08lx\n", cli->cli_StandardInput); printf("cli_standardoutput: %08lx\n", cli->cli_StandardOutput); printf("cli_currentinput : %08lx\n", cli->cli_CurrentInput); printf("cli_currentoutput : %08lx\n", cli->cli_CurrentOutput); printf("cli_Module : %08lx\n", cli->cli_Module); printf("STACK: %ld bytes, %08lx %08lx %08lx (%ld Free)\n", cli->cli_DefaultStack*4, proc->pr_ReturnAddr - cli->cli_DefaultStack*4, &stack, proc->pr_ReturnAddr, (long)&stack - (long)proc->pr_ReturnAddr + cli->cli_DefaultStack*4 ); } } */ return(0); } do_printenv() { register long lock; register FIB *fib = (FIB *)malloc(sizeof(FIB)); register short i; char buf[256]; long fh; if (lock = (long)Lock("ENV:", SHARED_LOCK)) { if (Examine(lock, fib)) { while (ExNext(lock, fib)) { sprintf(buf, "%-10s ", fib->fib_FileName); Write(Cout, buf, strlen(buf)); sprintf(buf, "ENV:%s", fib->fib_FileName); if (fh = Open(buf, 1005)) { while ((i = Read(fh, buf, sizeof(buf))) > 0) { Write(Cout, buf, i); } Close(fh); Oputs(""); } else { Oputs(""); } } } UnLock(lock); } free(fib); return(0); } do_setenv(command) char *command; { long fh; char buf[256]; short ierr = 0; if (ac <= 2) return(0); strcpy(buf, "ENV:"); strcat(buf, av[1]); if (fh = Open(buf, 1006)) { register char *str = next_word(next_word(command)); Write(fh, str, strlen(str)); Close(fh); } else { ierr = IoErr(); } return(ierr); } do_unsetenv() { char buf[256]; short i; for (i = 1; i < ac; ++i) { strcpy(buf, "ENV:"); strcat(buf, av[i]); DeleteFile(buf); } return(0); }