/* * COMM2.C * * * (c)1986 Matthew Dillon 9 October 1986 * * ABORTLINE * RETURN * STRHEAD * STRTAIL * IF * LABEL * GOTO * INC * INPUT * VER * CP * */ #include "shell.h" #include #include typedef struct FileInfoBlock FIB; typedef struct FileLock LOCK; extern LOCK *CurrentDir(), *Lock(), *CreateDir(); do_abortline() { Exec_abortline = 1; return (0); } do_return() { Exec_abortline = 1; if (Src_stack) { xseek (Src_base[Src_stack - 1], 0, 1); 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) */ 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_base[If_stack++] = 1; break; } result = num = 0; if (ac <= 2) { /* if $var; */ if (ac == 1 || strlen(av[1]) == 0 || (strlen(av[1]) == 1 && *av[1] == ' ')) goto do_result; result = 1; goto do_result; } if (ac != 4) { ierror(NULL, 500); break; } 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_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; } Disable = (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); xseek (Src_base[Src_stack - 1], pos, -1); Src_pos[Src_stack - 1] = pos; new = atoi(next_word(lab)); 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 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; ierr = 0; fib = (FIB *)AllocMem(sizeof(FIB), 0); recur = (strncmp(av[1], "-r", 2)) ? 0 : 1; destname = av[ac - 1]; if (ac < recur + 3) { 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); UnLock(srcdir); UnLock(destdir); if (ierr) break; } else { /* FILE to DIR, FILE to FILE */ struct FileLock *destdir, *srcdir, *tmp; char *destfilename; srcdir = (struct FileLock *)((struct Process *)FindTask(0))->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; } ierr = copyfile(av[i], srcdir, destfilename, destdir); 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) register struct FileLock *srcdir, *destdir; { LOCK *cwd; register FIB *srcfib; register LOCK *destlock, *srclock; int ierr; ierr = 0; srcfib = (FIB *)AllocMem(sizeof(FIB), 0); if (Examine(srcdir, srcfib)) { while (ExNext(srcdir, srcfib)) { if (srcfib->fib_DirEntryType < 0) { ierr = copyfile(srcfib->fib_FileName,srcdir,srcfib->fib_FileName,destdir); 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))) destlock = CreateDir(srcfib->fib_FileName); if (destlock) { ierr = copydir(srclock, destlock, recur); 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) char *srcname, *destname; struct FileLock *srcdir, *destdir; { struct FileLock *cwd; long f1, f2; int i, ierr; char buf[256]; ierr = 0; cwd = (LOCK *)CurrentDir(srcdir); f1 = xopen(srcname, "r", 8192); if (f1 == NULL) { ierr = 205; goto fail; } CurrentDir(destdir); f2 = xopen(destname, "w", 8192); if (f2 == NULL) { xclose(f1); ierr = IoErr(); goto fail; } while (i = xread(f1, buf, 256)) xwrite(f2, buf, i); xclose(f2); xclose(f1); fail: CurrentDir(cwd); return(ierr); }