void print_pid_fsgid(struct text_object *obj, char *p, int p_max_size) { #define FSGIDNOTFOUND "Can't find the process file system gid in '%s'" char *begin, *end, *buf = NULL; int bytes_read; asprintf(&buf, PROCDIR "/%d/status", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { begin = strstr(buf, GID_ENTRY); if(begin != NULL) { begin = strchr(begin, '\t'); begin++; begin = strchr(begin, '\t'); begin++; begin = strchr(begin, '\t'); begin++; begin = strchr(begin, '\t'); begin++; end = strchr(begin, '\n'); if(end != NULL) { *(end) = 0; } snprintf(p, p_max_size, "%s", begin); } else { NORM_ERR(FSGIDNOTFOUND, obj->data.s); } free(buf); } }
void internal_print_pid_vm(char* pid, char *p, int p_max_size, const char* entry, const char* errorstring) { char *begin, *end, *buf = NULL; int bytes_read; asprintf(&buf, PROCDIR "/%d/status", strtopid(pid)); strcpy(pid, buf); free(buf); buf = readfile(pid, &bytes_read, 1); if(buf != NULL) { begin = strstr(buf, entry); if(begin != NULL) { begin += strlen(entry); while(*begin == '\t' || *begin == ' ') { begin++; } end = strchr(begin, '\n'); if(end != NULL) { *(end) = 0; } snprintf(p, p_max_size, "%s", begin); } else { NORM_ERR(errorstring, pid); } free(buf); } }
void print_pid_stdout(struct text_object *obj, char *p, int p_max_size) { char *buffer; asprintf(&buffer, PROCDIR "/%d/fd/1", strtopid(obj->data.s)); pid_readlink(buffer, p, p_max_size); free(buffer); }
void print_pid_threads(struct text_object *obj, char *p, int p_max_size) { #define THREADS_ENTRY "Threads:\t" #define THREADSNOTFOUND "Can't find the number of the threads of the process in '%s'" char *begin, *end, *buf = NULL; int bytes_read; asprintf(&buf, PROCDIR "/%d/status", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { begin = strstr(buf, THREADS_ENTRY); if(begin != NULL) { begin += strlen(THREADS_ENTRY); end = strchr(begin, '\n'); if(end != NULL) { *(end) = 0; } snprintf(p, p_max_size, "%s", begin); } else { NORM_ERR(THREADSNOTFOUND, obj->data.s); } free(buf); } }
void print_pid_state(struct text_object *obj, char *p, int p_max_size) { #define STATE_ENTRY "State:\t" #define STATENOTFOUND "Can't find the process state in '%s'" char *begin, *end, *buf = NULL; int bytes_read; asprintf(&buf, PROCDIR "/%d/status", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { begin = strstr(buf, STATE_ENTRY); if(begin != NULL) { begin += strlen(STATE_ENTRY) + 3; // +3 will strip the char representing the short state and the space and '(' that follow end = strchr(begin, '\n'); if(end != NULL) { *(end-1) = 0; // -1 strips the ')' } snprintf(p, p_max_size, "%s", begin); } else { NORM_ERR(STATENOTFOUND, obj->data.s); } free(buf); } }
void print_pid_openfiles(struct text_object *obj, char *p, int p_max_size) { DIR* dir; struct dirent *entry; char buf[p_max_size]; int length, totallength = 0; struct ll_string* files_front = NULL; struct ll_string* files_back = NULL; dir = opendir(obj->data.s); if(dir != NULL) { while ((entry = readdir(dir))) { if(entry->d_name[0] != '.') { snprintf(buf, p_max_size, "%d/%s", strtopid(obj->data.s), entry->d_name); length = readlink(buf, buf, p_max_size); buf[length] = 0; if(inlist(files_front, buf) == 0) { files_back = addnode(files_back, buf); snprintf(p + totallength, p_max_size - totallength, "%s; " , buf); totallength += length + strlen("; "); } if(files_front == NULL) { files_front = files_back; } } } closedir(dir); freelist(files_front); p[totallength - strlen("; ")] = 0; } else { p[0] = 0; } }
void print_pid_cwd(struct text_object *obj, char *p, int p_max_size) { char buf[p_max_size]; int bytes_read; sprintf(buf, PROCDIR "/%d/cwd", strtopid(obj->data.s)); strcpy(obj->data.s, buf); bytes_read = readlink(obj->data.s, buf, p_max_size); if(bytes_read != -1) { buf[bytes_read] = 0; snprintf(p, p_max_size, "%s", buf); } else { NORM_ERR(READERR, obj->data.s); } }
void print_pid_state_short(struct text_object *obj, char *p, int p_max_size) { char *begin, *buf = NULL; int bytes_read; asprintf(&buf, PROCDIR "/%d/status", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { begin = strstr(buf, STATE_ENTRY); if(begin != NULL) { snprintf(p, p_max_size, "%c", *begin); } else { NORM_ERR(STATENOTFOUND, obj->data.s); } free(buf); } }
void print_pid_time(struct text_object *obj, char *p, int p_max_size) { char *buf = NULL; int bytes_read; unsigned long int umtime, kmtime; if(*(obj->data.s) != 0) { asprintf(&buf, PROCDIR "/%d/stat", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %lu %lu", &umtime, &kmtime); snprintf(p, p_max_size, "%.2f", (float) (umtime + kmtime) / 100); free(buf); } } else { NORM_ERR("$pid_time didn't receive a argument"); } }
void print_pid_priority(struct text_object *obj, char *p, int p_max_size) { char *buf = NULL; int bytes_read; long int priority; if(*(obj->data.s) != 0) { asprintf(&buf, PROCDIR "/%d/stat", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { sscanf(buf, "%*d %*s %*c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*u %*u %*d %*d %ld", &priority); snprintf(p, p_max_size, "%ld", priority); free(buf); } } else { NORM_ERR("$pid_priority didn't receive a argument"); } }
void print_pid_write(struct text_object *obj, char *p, int p_max_size) { char *begin, *end, *buf = NULL; int bytes_read; asprintf(&buf, PROCDIR "/%d/io", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { begin = strstr(buf, WRITE_ENTRY); if(begin != NULL) { end = strchr(begin, '\n'); if(end != NULL) { *(end) = 0; } snprintf(p, p_max_size, "%s", begin); } else { NORM_ERR(WRITENOTFOUND, obj->data.s); } free(buf); } }
void print_pid_thread_list(struct text_object *obj, char *p, int p_max_size) { char *buf = NULL; DIR* dir; struct dirent *entry; int totallength = 0; asprintf(&buf, PROCDIR "/%d/task", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); dir = opendir(obj->data.s); if(dir != NULL) { while ((entry = readdir(dir))) { if(entry->d_name[0] != '.') { snprintf(p + totallength, p_max_size - totallength, "%s," , entry->d_name); totallength += strlen(entry->d_name)+1; } } closedir(dir); if(p[totallength - 1] == ',') p[totallength - 1] = 0; } else { p[0] = 0; } }
void print_pid_cmdline(struct text_object *obj, char *p, int p_max_size) { char* buf; int i, bytes_read; if(*(obj->data.s) != 0) { asprintf(&buf, PROCDIR "/%d/cmdline", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &bytes_read, 1); if(buf != NULL) { for(i = 0; i < bytes_read-1; i++) { if(buf[i] == 0) { buf[i] = ' '; } } snprintf(p, p_max_size, "%s", buf); free(buf); } } else { NORM_ERR("$pid_cmdline didn't receive a argument"); } }
void print_pid_environ_list(struct text_object *obj, char *p, int p_max_size) { char *buf = NULL; char *buf2; int bytes_read, total_read; int i = 0; asprintf(&buf, PROCDIR "/%d/environ", strtopid(obj->data.s)); strcpy(obj->data.s, buf); free(buf); buf = readfile(obj->data.s, &total_read, 1); if(buf != NULL) { for(bytes_read = 0; bytes_read < total_read; buf[i-1] = ';') { buf2 = strdup(buf+bytes_read); bytes_read += strlen(buf2)+1; sscanf(buf2, "%[^=]", buf+i); free(buf2); i = strlen(buf) + 1; } buf[i-1] = 0; snprintf(p, p_max_size, "%s", buf); free(buf); } }
int main(int argc, char *argv[]) { const char *errstr; char errbuf[_POSIX2_LINE_MAX], *kmem = NULL, *kernel = NULL; struct kinfo_proc *kproc; struct sum total_sum; int many, ch, rc; kvm_t *kd; pid_t pid = -1; gid_t gid; while ((ch = getopt(argc, argv, "AaD:dlmM:N:p:Prsvx")) != -1) { switch (ch) { case 'A': print_amap = 1; break; case 'a': print_all = 1; break; case 'd': print_ddb = 1; break; case 'D': debug = strtonum(optarg, 0, 0xf, &errstr); if (errstr) errx(1, "invalid debug mask"); break; case 'l': print_maps = 1; break; case 'm': print_map = 1; break; case 'M': kmem = optarg; break; case 'N': kernel = optarg; break; case 'p': pid = strtopid(optarg); break; case 'P': pid = getpid(); break; case 's': print_solaris = 1; break; case 'v': verbose = 1; break; case 'r': case 'x': errx(1, "-%c option not implemented, sorry", ch); /*NOTREACHED*/ default: usage(); } } /* * Discard setgid privileges if not the running kernel so that bad * guys can't print interesting stuff from kernel memory. */ gid = getgid(); if (kernel != NULL || kmem != NULL) if (setresgid(gid, gid, gid) == -1) err(1, "setresgid"); argc -= optind; argv += optind; /* more than one "process" to dump? */ many = (argc > 1 - (pid == -1 ? 0 : 1)) ? 1 : 0; /* apply default */ if (print_all + print_map + print_maps + print_solaris + print_ddb == 0) print_solaris = 1; /* start by opening libkvm */ kd = kvm_openfiles(kernel, kmem, NULL, O_RDONLY, errbuf); if (kernel == NULL && kmem == NULL) if (setresgid(gid, gid, gid) == -1) err(1, "setresgid"); if (kd == NULL) errx(1, "%s", errbuf); /* get "bootstrap" addresses from kernel */ load_symbols(kd); memset(&total_sum, 0, sizeof(total_sum)); do { struct sum sum; memset(&sum, 0, sizeof(sum)); if (pid == -1) { if (argc == 0) pid = getppid(); else { pid = strtopid(argv[0]); argv++; argc--; } } /* find the process id */ if (pid == 0) kproc = NULL; else { kproc = kvm_getprocs(kd, KERN_PROC_PID, pid, sizeof(struct kinfo_proc), &rc); if (kproc == NULL || rc == 0) { warnc(ESRCH, "%d", pid); pid = -1; continue; } } /* dump it */ if (many) { if (kproc) printf("process %d:\n", pid); else printf("kernel:\n"); } process_map(kd, pid, kproc, &sum); if (print_amap) print_sum(&sum, &total_sum); pid = -1; } while (argc > 0); if (print_amap) print_sum(&total_sum, NULL); /* done. go away. */ rc = kvm_close(kd); if (rc == -1) err(1, "kvm_close"); return (0); }