Made ps work. Fixed some stuff.
No binary (build failed)
—
(log yok)
| @@ -5,7 +5,7 @@ BUILDTIME=$(shell date "+%Y%m%d-%H%M") | |
| # Comment out the following to make a debuggable build | |
| # Leave this off for production use. | |
| - | DODEBUG=true |
| + | #DODEBUG=true |
| #This will choke on a non-debian system | |
| ARCH=`uname -m | sed -e 's/i.86/i386/' | sed -e 's/sparc.*/sparc/'` | |
| @@ -21,7 +21,7 @@ | |
| #define BB_GREP | |
| #define BB_HALT | |
| #define BB_INIT | |
| - | //#define BB_KILL // Supplied by ash |
| + | #define BB_KILL |
| //#define BB_LENGTH | |
| #define BB_LN | |
| #define BB_LOADFONT | |
| @@ -48,56 +48,6 @@ static const char chmod_usage[] = "[-R] MODE[,MODE]... FILE...\n" | |
| "\t-R\tchange files and directories recursively.\n"; | |
| - | uid_t my_getid(const char *filename, const char *name) |
| - | { |
| - | FILE *stream; |
| - | char *rname, *start, *end, buf[128]; |
| - | uid_t rid; |
| - | |
| - | stream=fopen(filename,"r"); |
| - | |
| - | while (fgets (buf, 128, stream) != NULL) { |
| - | if (buf[0] == '#') |
| - | continue; |
| - | |
| - | start = buf; |
| - | end = strchr (start, ':'); |
| - | if (end == NULL) |
| - | continue; |
| - | *end = '\0'; |
| - | rname = start; |
| - | |
| - | start = end + 1; |
| - | end = strchr (start, ':'); |
| - | if (end == NULL) |
| - | continue; |
| - | |
| - | start = end + 1; |
| - | rid = (uid_t) strtol (start, &end, 10); |
| - | if (end == start) |
| - | continue; |
| - | |
| - | if (name) { |
| - | if (0 == strcmp(rname, name)) |
| - | return( rid); |
| - | } |
| - | } |
| - | fclose(stream); |
| - | return (-1); |
| - | } |
| - | |
| - | uid_t |
| - | my_getpwnam(char *name) |
| - | { |
| - | return my_getid("/etc/passwd", name); |
| - | } |
| - | |
| - | gid_t |
| - | my_getgrnam(char *name) |
| - | { |
| - | return my_getid("/etc/group", name); |
| - | } |
| - | |
| static int fileAction(const char *fileName, struct stat* statbuf) | |
| { | |
| switch (whichApp) { | |
| @@ -194,19 +194,6 @@ set_free_pages() | |
| fclose(f); | |
| } | |
| - | static int |
| - | get_kernel_revision() |
| - | { |
| - | FILE *f; |
| - | int major=0, minor=0, patch=0; |
| - | |
| - | f = fopen("/proc/sys/kernel/osrelease","r"); |
| - | fscanf(f,"%d.%d.%d",&major,&minor,&patch); |
| - | fclose(f); |
| - | return major*65536 + minor*256 + patch; |
| - | } |
| - | |
| - | |
| static void | |
| shutdown_system(void) | |
| { | |
| @@ -194,19 +194,6 @@ set_free_pages() | |
| fclose(f); | |
| } | |
| - | static int |
| - | get_kernel_revision() |
| - | { |
| - | FILE *f; |
| - | int major=0, minor=0, patch=0; |
| - | |
| - | f = fopen("/proc/sys/kernel/osrelease","r"); |
| - | fscanf(f,"%d.%d.%d",&major,&minor,&patch); |
| - | fclose(f); |
| - | return major*65536 + minor*256 + patch; |
| - | } |
| - | |
| - | |
| static void | |
| shutdown_system(void) | |
| { | |
| @@ -138,6 +138,12 @@ extern void createPath (const char *name, int mode); | |
| extern int parse_mode( const char* s, mode_t* theMode); | |
| extern volatile void usage(const char *usage); | |
| + | extern uid_t my_getpwnam(char *name); |
| + | extern gid_t my_getgrnam(char *name); |
| + | extern void my_getpwuid(char* name, uid_t uid); |
| + | extern void my_getgrgid(char* group, gid_t gid); |
| + | extern int get_kernel_revision(); |
| + | |
| #if defined (BB_FSCK_MINIX) || defined (BB_MKFS_MINIX) | |
| @@ -23,16 +23,82 @@ | |
| #include <unistd.h> | |
| #include <dirent.h> | |
| #include <stdio.h> | |
| + | #include <fcntl.h> |
| + | #include <ctype.h> |
| + | |
| + | |
| + | typedef struct proc_s { |
| + | char |
| + | cmd[16]; /* basename of executable file in call to exec(2) */ |
| + | int |
| + | ruid, rgid, /* real only (sorry) */ |
| + | pid, /* process id */ |
| + | ppid; /* pid of parent process */ |
| + | char |
| + | state; /* single-char code for process state (S=sleeping) */ |
| + | } proc_t; |
| + | |
| + | |
| + | |
| + | static int file2str(char *filename, char *ret, int cap) |
| + | { |
| + | int fd, num_read; |
| + | |
| + | if ( (fd = open(filename, O_RDONLY, 0)) == -1 ) return -1; |
| + | if ( (num_read = read(fd, ret, cap - 1)) <= 0 ) return -1; |
| + | ret[num_read] = 0; |
| + | close(fd); |
| + | return num_read; |
| + | } |
| + | |
| + | |
| + | static void parse_proc_status(char* S, proc_t* P) |
| + | { |
| + | char* tmp; |
| + | memset(P->cmd, 0, sizeof P->cmd); |
| + | sscanf (S, "Name:\t%15c", P->cmd); |
| + | tmp = strchr(P->cmd,'\n'); |
| + | if (tmp) |
| + | *tmp='\0'; |
| + | tmp = strstr (S,"State"); |
| + | sscanf (tmp, "State:\t%c", &P->state); |
| + | |
| + | tmp = strstr (S,"Pid:"); |
| + | if(tmp) sscanf (tmp, |
| + | "Pid:\t%d\n" |
| + | "PPid:\t%d\n", |
| + | &P->pid, |
| + | &P->ppid |
| + | ); |
| + | else fprintf(stderr, "Internal error!\n"); |
| + | |
| + | /* For busybox, ignoring effecting, saved, etc */ |
| + | tmp = strstr (S,"Uid:"); |
| + | if(tmp) sscanf (tmp, |
| + | "Uid:\t%d", &P->ruid); |
| + | else fprintf(stderr, "Internal error!\n"); |
| + | |
| + | tmp = strstr (S,"Gid:"); |
| + | if(tmp) sscanf (tmp, |
| + | "Gid:\t%d", &P->rgid); |
| + | else fprintf(stderr, "Internal error!\n"); |
| + | |
| + | } |
| extern int ps_main(int argc, char **argv) | |
| { | |
| + | proc_t p; |
| DIR *dir; | |
| FILE *file; | |
| struct dirent *entry; | |
| + | char path[32], sbuf[512]; |
| + | char uidName[10]=""; |
| + | char groupName[10]=""; |
| + | int i, c; |
| if ( argc>1 && **(argv+1) == '-' ) { | |
| - | usage ("ps\n"); |
| + | usage ("ps - report process status\nThis version of ps accepts no options.\n"); |
| } | |
| dir = opendir("/proc"); | |
| @@ -41,28 +107,44 @@ extern int ps_main(int argc, char **argv) | |
| exit(FALSE); | |
| } | |
| - | fprintf(stdout, "PID\tUid\tGid\tState\tName\n"); |
| + | fprintf(stdout, "%5s %-8s %-3s %5s %s\n", "PID", "Uid", "Gid", "State", "Command"); |
| while ((entry = readdir(dir)) != NULL) { | |
| - | char psStatus[NAME_MAX]; |
| - | char psName[NAME_MAX]=""; |
| - | char psState[NAME_MAX]=""; |
| - | int psPID=0, psPPID=0, psUid=0, psGid=0; |
| - | //if (match(entry->d_name, "[0-9]") == FALSE) |
| - | // continue; |
| - | sprintf(psStatus, "/proc/%s/status", entry->d_name); |
| - | file = fopen( psStatus, "r"); |
| - | if (file == NULL) { |
| + | uidName[0]='\0'; |
| + | groupName[0]='\0'; |
| + | |
| + | if (! isdigit(*entry->d_name)) |
| continue; | |
| - | //perror(psStatus); |
| - | //exit( FALSE); |
| + | sprintf(path, "/proc/%s/status", entry->d_name); |
| + | if ((file2str(path, sbuf, sizeof sbuf)) != -1 ) { |
| + | parse_proc_status(sbuf, &p); |
| } | |
| - | fscanf(file, "Name:\t%s\nState:\t%s\nPid:\t%d\nPPid:\t%d\nUid:\t%d\nGid:\t%d", |
| - | psName, psState, &psPID, &psPPID, &psUid, &psGid); |
| - | fclose(file); |
| - | fprintf(stdout, "%d\t%d\t%d\t%s\t%s\n", psPID, psUid, psGid, psState, psName); |
| + | /* Make some adjustments as needed */ |
| + | my_getpwuid( uidName, p.ruid); |
| + | my_getgrgid( groupName, p.rgid); |
| + | if (*uidName == '\0') |
| + | sprintf( uidName, "%d", p.ruid); |
| + | if (*groupName == '\0') |
| + | sprintf( groupName, "%d", p.rgid); |
| + | |
| + | fprintf(stdout, "%5d %-8s %-8s %c ", p.pid, uidName, groupName, p.state); |
| + | sprintf(path, "/proc/%s/cmdline", entry->d_name); |
| + | file = fopen(path, "r"); |
| + | if (file == NULL) { |
| + | perror(path); |
| + | exit(FALSE); |
| + | } |
| + | i=0; |
| + | while (((c = getc(file)) != EOF) && (i < 53)) { |
| + | i++; |
| + | if (c == '\0') |
| + | c = ' '; |
| + | putc(c, stdout); |
| + | } |
| + | if (i==0) |
| + | fprintf(stdout, "%s", p.cmd); |
| + | fprintf(stdout, "\n"); |
| } | |
| closedir(dir); | |
| exit(TRUE); | |
| } | |
| - | |
| @@ -23,16 +23,82 @@ | |
| #include <unistd.h> | |
| #include <dirent.h> | |
| #include <stdio.h> | |
| + | #include <fcntl.h> |
| + | #include <ctype.h> |
| + | |
| + | |
| + | typedef struct proc_s { |
| + | char |
| + | cmd[16]; /* basename of executable file in call to exec(2) */ |
| + | int |
| + | ruid, rgid, /* real only (sorry) */ |
| + | pid, /* process id */ |
| + | ppid; /* pid of parent process */ |
| + | char |
| + | state; /* single-char code for process state (S=sleeping) */ |
| + | } proc_t; |
| + | |
| + | |
| + | |
| + | static int file2str(char *filename, char *ret, int cap) |
| + | { |
| + | int fd, num_read; |
| + | |
| + | if ( (fd = open(filename, O_RDONLY, 0)) == -1 ) return -1; |
| + | if ( (num_read = read(fd, ret, cap - 1)) <= 0 ) return -1; |
| + | ret[num_read] = 0; |
| + | close(fd); |
| + | return num_read; |
| + | } |
| + | |
| + | |
| + | static void parse_proc_status(char* S, proc_t* P) |
| + | { |
| + | char* tmp; |
| + | memset(P->cmd, 0, sizeof P->cmd); |
| + | sscanf (S, "Name:\t%15c", P->cmd); |
| + | tmp = strchr(P->cmd,'\n'); |
| + | if (tmp) |
| + | *tmp='\0'; |
| + | tmp = strstr (S,"State"); |
| + | sscanf (tmp, "State:\t%c", &P->state); |
| + | |
| + | tmp = strstr (S,"Pid:"); |
| + | if(tmp) sscanf (tmp, |
| + | "Pid:\t%d\n" |
| + | "PPid:\t%d\n", |
| + | &P->pid, |
| + | &P->ppid |
| + | ); |
| + | else fprintf(stderr, "Internal error!\n"); |
| + | |
| + | /* For busybox, ignoring effecting, saved, etc */ |
| + | tmp = strstr (S,"Uid:"); |
| + | if(tmp) sscanf (tmp, |
| + | "Uid:\t%d", &P->ruid); |
| + | else fprintf(stderr, "Internal error!\n"); |
| + | |
| + | tmp = strstr (S,"Gid:"); |
| + | if(tmp) sscanf (tmp, |
| + | "Gid:\t%d", &P->rgid); |
| + | else fprintf(stderr, "Internal error!\n"); |
| + | |
| + | } |
| extern int ps_main(int argc, char **argv) | |
| { | |
| + | proc_t p; |
| DIR *dir; | |
| FILE *file; | |
| struct dirent *entry; | |
| + | char path[32], sbuf[512]; |
| + | char uidName[10]=""; |
| + | char groupName[10]=""; |
| + | int i, c; |
| if ( argc>1 && **(argv+1) == '-' ) { | |
| - | usage ("ps\n"); |
| + | usage ("ps - report process status\nThis version of ps accepts no options.\n"); |
| } | |
| dir = opendir("/proc"); | |
| @@ -41,28 +107,44 @@ extern int ps_main(int argc, char **argv) | |
| exit(FALSE); | |
| } | |
| - | fprintf(stdout, "PID\tUid\tGid\tState\tName\n"); |
| + | fprintf(stdout, "%5s %-8s %-3s %5s %s\n", "PID", "Uid", "Gid", "State", "Command"); |
| while ((entry = readdir(dir)) != NULL) { | |
| - | char psStatus[NAME_MAX]; |
| - | char psName[NAME_MAX]=""; |
| - | char psState[NAME_MAX]=""; |
| - | int psPID=0, psPPID=0, psUid=0, psGid=0; |
| - | //if (match(entry->d_name, "[0-9]") == FALSE) |
| - | // continue; |
| - | sprintf(psStatus, "/proc/%s/status", entry->d_name); |
| - | file = fopen( psStatus, "r"); |
| - | if (file == NULL) { |
| + | uidName[0]='\0'; |
| + | groupName[0]='\0'; |
| + | |
| + | if (! isdigit(*entry->d_name)) |
| continue; | |
| - | //perror(psStatus); |
| - | //exit( FALSE); |
| + | sprintf(path, "/proc/%s/status", entry->d_name); |
| + | if ((file2str(path, sbuf, sizeof sbuf)) != -1 ) { |
| + | parse_proc_status(sbuf, &p); |
| } | |
| - | fscanf(file, "Name:\t%s\nState:\t%s\nPid:\t%d\nPPid:\t%d\nUid:\t%d\nGid:\t%d", |
| - | psName, psState, &psPID, &psPPID, &psUid, &psGid); |
| - | fclose(file); |
| - | fprintf(stdout, "%d\t%d\t%d\t%s\t%s\n", psPID, psUid, psGid, psState, psName); |
| + | /* Make some adjustments as needed */ |
| + | my_getpwuid( uidName, p.ruid); |
| + | my_getgrgid( groupName, p.rgid); |
| + | if (*uidName == '\0') |
| + | sprintf( uidName, "%d", p.ruid); |
| + | if (*groupName == '\0') |
| + | sprintf( groupName, "%d", p.rgid); |
| + | |
| + | fprintf(stdout, "%5d %-8s %-8s %c ", p.pid, uidName, groupName, p.state); |
| + | sprintf(path, "/proc/%s/cmdline", entry->d_name); |
| + | file = fopen(path, "r"); |
| + | if (file == NULL) { |
| + | perror(path); |
| + | exit(FALSE); |
| + | } |
| + | i=0; |
| + | while (((c = getc(file)) != EOF) && (i < 53)) { |
| + | i++; |
| + | if (c == '\0') |
| + | c = ' '; |
| + | putc(c, stdout); |
| + | } |
| + | if (i==0) |
| + | fprintf(stdout, "%s", p.cmd); |
| + | fprintf(stdout, "\n"); |
| } | |
| closedir(dir); | |
| exit(TRUE); | |
| } | |
| - | |
| @@ -42,6 +42,27 @@ volatile void usage(const char *usage) | |
| } | |
| + | #if defined (BB_INIT) || defined (BB_PS) |
| + | |
| + | /* Returns kernel version encoded as major*65536 + minor*256 + patch, |
| + | * so, for example, to check if the kernel is greater than 2.2.11: |
| + | * if (get_kernel_revision() <= 2*65536+2*256+11) { <stuff> } |
| + | */ |
| + | int |
| + | get_kernel_revision() |
| + | { |
| + | FILE *f; |
| + | int major=0, minor=0, patch=0; |
| + | |
| + | f = fopen("/proc/sys/kernel/osrelease","r"); |
| + | fscanf(f,"%d.%d.%d",&major,&minor,&patch); |
| + | fclose(f); |
| + | return major*65536 + minor*256 + patch; |
| + | } |
| + | |
| + | #endif |
| + | |
| + | |
| #if defined (BB_CP) || defined (BB_MV) | |
| /* | |
| @@ -659,4 +680,84 @@ parse_mode( const char* s, mode_t* theMode) | |
| + | |
| + | |
| + | |
| + | |
| + | #if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_PS) |
| + | |
| + | /* Use this to avoid needing the glibc NSS stuff |
| + | * This uses storage buf to hold things. |
| + | * */ |
| + | uid_t |
| + | my_getid(const char *filename, char *name, uid_t id) |
| + | { |
| + | FILE *stream; |
| + | char *rname, *start, *end, buf[128]; |
| + | uid_t rid; |
| + | |
| + | stream=fopen(filename,"r"); |
| + | |
| + | while (fgets (buf, 128, stream) != NULL) { |
| + | if (buf[0] == '#') |
| + | continue; |
| + | |
| + | start = buf; |
| + | end = strchr (start, ':'); |
| + | if (end == NULL) |
| + | continue; |
| + | *end = '\0'; |
| + | rname = start; |
| + | |
| + | start = end + 1; |
| + | end = strchr (start, ':'); |
| + | if (end == NULL) |
| + | continue; |
| + | |
| + | start = end + 1; |
| + | rid = (uid_t) strtol (start, &end, 10); |
| + | if (end == start) |
| + | continue; |
| + | |
| + | if (name) { |
| + | if (0 == strcmp(rname, name)) |
| + | return( rid); |
| + | } |
| + | if ( id != -1 && id == rid ) { |
| + | strncpy(name, rname, 8); |
| + | return( TRUE); |
| + | } |
| + | } |
| + | fclose(stream); |
| + | return (-1); |
| + | } |
| + | |
| + | uid_t |
| + | my_getpwnam(char *name) |
| + | { |
| + | return my_getid("/etc/passwd", name, -1); |
| + | } |
| + | |
| + | gid_t |
| + | my_getgrnam(char *name) |
| + | { |
| + | return my_getid("/etc/group", name, -1); |
| + | } |
| + | |
| + | void |
| + | my_getpwuid(char* name, uid_t uid) |
| + | { |
| + | my_getid("/etc/passwd", name, uid); |
| + | } |
| + | |
| + | void |
| + | my_getgrgid(char* group, gid_t gid) |
| + | { |
| + | my_getid("/etc/group", group, gid); |
| + | } |
| + | |
| + | |
| + | #endif |
| + | |
| + | |
| /* END CODE */ | |