/* * COMM2.C * * (c)1986 Matthew Dillon 9 October 1986 * * version 2.05M (Manx Version and Additions) by Steve Drew 20-Jan-87 * */ #include "shell.h" #define BPTR_TO_C(strtag, var) ((struct strtag *)(BADDR( (ULONG) var))) #define TO_ASC(n) ((n) + '0') /* make it printable! */ /* Casting conveniences */ #define PROC(task) ((struct Process *)task) #define ROOTNODE ((struct RootNode *)DOSBase->dl_Root) #define CLI(proc) (BPTR_TO_C(CommandLineInterface, proc->pr_CLI)) /* Externs */ extern struct DosLibrary *DOSBase; /* dos library base pointer */ 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]; 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]; 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; { char *v1, *v2, *v3, result, num; 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 %d", Src_pos[Src_stack-1], If_stack); set_var (LEVEL_LABEL + Src_stack - 1, av[1], aseek); return (0); } do_goto() { int new; long pos; 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)); 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; { char *var; char num[32]; if (ac == 3) com = atoi(av[2]); var = get_var (LEVEL_SET, av[1]); if (var) { sprintf (num, "%d", atoi(var)+com); set_var (LEVEL_SET, av[1], num); } return (0); } do_input() { char in[256]; if ((gets(in)) != 0) set_var (LEVEL_SET, av[1], in); return (0); } do_ver() { puts (VERSION); return (0); } do_ps() { /* this code fragment based on ps.c command by Dewi Williams */ register ULONG *tt; /* References TaskArray */ register int count; /* loop variable */ register UBYTE *port; /* msgport & ptr arith */ register struct Task *task; /* EXEC descriptor */ char strbuf[64]; /* scratch for btocstr() */ char *btocstr(); /* BCPL BSTR to ASCIIZ */ tt = (unsigned long *)(BADDR(ROOTNODE->rn_TaskArray)); printf("Proc Command Name CLI Type Pri. Address Directory\n"); Forbid(); /* need linked list consistency */ for (count = 1; count <= (int)tt[0] ; count++) {/* or just assume 20?*/ if (tt[count] == 0) continue; /* nobody home */ /* Start by pulling out MsgPort addresses from the TaskArray * area. By making unwarranted assumptions about the layout * of Process and Task structures, we can derive these * descriptors. Every task has an associated process, since * this loop drives off a CLI data area. */ port = (UBYTE *)tt[count]; task = (struct Task *)(port - sizeof(struct Task)); /* Sanity check just in case */ if (PROC(task)->pr_TaskNum == 0 || PROC(task)->pr_CLI == 0) continue; /* or complain? */ btocstr(CLI(PROC(task))->cli_CommandName, strbuf); printf("%2d %-21s",count,strbuf); strcpy(strbuf,task->tc_Node.ln_Name); strbuf[11] = '\0'; printf("%-11s",strbuf); printf(" %3d %8lx %s\n", task->tc_Node.ln_Pri,task, btocstr(CLI(PROC(task))->cli_SetName, strbuf)); } Permit(); /* outside critical region */ return(0); } char * btocstr(b, buf) ULONG b; char *buf; { register char *s; s = (char *)BADDR(b); /* Shift & get length-prefixed str */ bmov(s +1, buf, s[0]); buf[s[0]] = '\0'; return buf; }