/* stat.c An enhanced version of the AmigaDOS command STATUS. * * Copyright 1986 by James M Synge. Sept. 2, 1986. * Permission is granted for unlimited non-commercial use. * * Compiled using Aztec C, but it shouldn't be that hard to change * for Lattice C * * The makefile file is very short: *------------------------------ * stat: stat.o * ln -v stat.o -lc *------------------------------ * UUCP: uw-beaver!geops!uw-atm!james */ #include #include #include #include char buf1[32], buf2[32]; /* DOSBase is already set up (by _main?) */ extern struct DosLibrary *DOSBase; /* Need a macro to translate a BPTR to an APTR */ #ifdef BADDR #undef BADDR #endif #define BADDR(bptr) (((long)bptr) << 2) /* By experimentation I determined that the command line arguments are */ /* located at (tc_SPLower + 0x280). This may change in the future. */ /* If STAT starts printing garbage for the args, just comment out this: */ #define ARGS_OFFSET 0x280 main(argc, argv) int argc; char *argv[]; { int i, tasknum, pri, strncmp(); char *msg, *index(); long process, processes, *ta; struct Process *pr; struct RootNode *rn; struct CommandLineInterface *cli; /* Find the RootNode */ rn = (struct RootNode *)(DOSBase->dl_Root); /* ta points to the array of tasks. The first location is the */ /* maximum number of processes, followed by that many pointers. */ /* Each pointer points to the MsgPort within the Process data */ /* structure of each AmigaDos process, otherwise its value is 0L. */ /* The AmigaDOS Technical Reference Manual calls these pointers */ /* process ids. */ ta = (long *) BADDR(rn->rn_TaskArray); /* How many AmigaDOS processes are there? */ processes = *ta++; /* Print the title line. */ printf("Task Pri Address Command\t\t\t Directory\n"); /* Loop through each live process, printing info. */ for (process = 0; process < processes; process++ ) { /* Get the next process id (i.e. struct MsgPort *) */ msg = (char *)(*ta++); if (!msg) continue; /* No associated Process? */ /* Pointer to struct Process */ pr = (struct Process *)(msg - sizeof(struct Task)); /* CLIs have small positive task numbers */ tasknum = (int)(pr->pr_TaskNum); /* The priority of the task is in the Node structure */ pri = (int)(pr->pr_Task.tc_Node.ln_Pri); cli = (struct CommandLineInterface *) BADDR(pr->pr_CLI); if (cli) { moveBSTR(cli->cli_CommandName, buf1, 32); if (!buf1[0]) strcpy(buf1, "Waiting for a command"); #ifdef ARGS_OFFSET else { msg = (char *)(pr->pr_Task.tc_SPLower) + ARGS_OFFSET; if (*msg && *msg != '\n') { strncat(buf1, " ", 32); strncat(buf1, msg, 32); msg = index(buf1, '\n'); /* Look for a \n */ if (msg) *msg = '\0'; } } #endif moveBSTR(cli->cli_SetName, buf2, 32); } else { strcpy(buf1, "Not a CLI"); buf2[0] = 0; } printf("%3d %4d %8lx %-32s %s\n", tasknum, pri, pr, buf1, buf2); } exit(0); } /* moveBSTR copies a BSTR to a C char string. */ moveBSTR(bptr, buffer, maxlen) BSTR bptr; char *buffer; int maxlen; /* size of buffer[] */ { register char *ptr; register unsigned int len, i; unsigned char l; ptr = (char *) BADDR(bptr); /* Make a char* to the length */ l = (unsigned int) (*ptr++); /* Get the length and increment ptr */ if (!(len = l)) { *buffer = '\0'; /* Mark the end of the string. */ return; } if (len > maxlen) len = maxlen; for(i = 0; i < len; i++) *buffer++ = *ptr++; /* Copy it. */ if (i < maxlen) *buffer = '\0'; /* If there is room, mark the end */ return; }