char *xmalloc_readlink_or_warn(const char *path) { char *buf = xmalloc_readlink(path); if (!buf) { /* EINVAL => "file: Invalid argument" => puzzled user */ bb_error_msg("%s: cannot read link (not a symlink?)", path); } return buf; }
char* FAST_FUNC xmalloc_readlink_or_warn(const char *path) { char *buf = xmalloc_readlink(path); if (!buf) { /* EINVAL => "file: Invalid argument" => puzzled user */ const char *errmsg = "not a symlink"; int err = errno; if (err != EINVAL) errmsg = strerror(err); bb_error_msg("%s: cannot read link: %s", path, errmsg); } return buf; }
/* * This routine is not the same as realpath(), which * canonicalizes the given path completely. This routine only * follows trailing symlinks until a real file is reached and * returns its name. If the path ends in a dangling link or if * the target doesn't exist, the path is returned in any case. * Intermediate symlinks in the path are not expanded -- only * those at the tail. * A malloced char* is returned, which must be freed by the caller. */ char* FAST_FUNC xmalloc_follow_symlinks(const char *path) { char *buf; char *lpc; char *linkpath; int bufsize; int looping = MAXSYMLINKS + 1; buf = xstrdup(path); goto jump_in; while (1) { linkpath = xmalloc_readlink(buf); if (!linkpath) { /* not a symlink, or doesn't exist */ if (errno == EINVAL || errno == ENOENT) return buf; goto free_buf_ret_null; } if (!--looping) { free(linkpath); free_buf_ret_null: free(buf); return NULL; } if (*linkpath != '/') { bufsize += strlen(linkpath); buf = xrealloc(buf, bufsize); lpc = bb_get_last_path_component_strip(buf); strcpy(lpc, linkpath); free(linkpath); } else { free(buf); buf = linkpath; jump_in: bufsize = strlen(buf) + 1; } } }
static int pid_is_exec(pid_t pid) { ssize_t bytes; char buf[sizeof("/proc/%u/cmdline") + sizeof(int)*3]; char *procname, *exelink; int match; procname = buf + sprintf(buf, "/proc/%u/exe", (unsigned)pid) - 3; exelink = xmalloc_readlink(buf); match = (exelink && strcmp(execname, exelink) == 0); free(exelink); if (match) return match; strcpy(procname, "cmdline"); bytes = open_read_close(buf, G.execname_cmpbuf, G.execname_sizeof); if (bytes > 0) { G.execname_cmpbuf[bytes] = '\0'; return strcmp(execname, G.execname_cmpbuf) == 0; } return 0; }
static smallint scan_recursive(const char *path) { DIR *d; struct dirent *d_ent; smallint stop_scan; smallint retval; d = opendir(path); if (d == NULL) return 0; G.recursion_depth++; retval = 0; stop_scan = 0; while (!stop_scan && (d_ent = readdir(d)) != NULL) { struct stat statbuf; pid_t pid; char *subpath; subpath = concat_subpath_file(path, d_ent->d_name); if (subpath == NULL) continue; /* . or .. */ switch (G.recursion_depth) { case PROC_DIR: pid = (pid_t)bb_strtou(d_ent->d_name, NULL, 10); if (errno != 0 || pid == G.mypid /* "this PID doesn't use specified FILEs or PORT/PROTO": */ || scan_recursive(subpath) == 0 ) { break; } if (option_mask32 & OPT_KILL) { if (kill(pid, G.killsig) != 0) { bb_perror_msg("kill pid %s", d_ent->d_name); G.kill_failed = 1; } } if (!(option_mask32 & OPT_SILENT)) printf("%s ", d_ent->d_name); retval = 1; break; case PROC_DIR_LINKS: switch ( index_in_substrings( "cwd" "\0" "exe" "\0" "root" "\0" "fd" "\0" "lib" "\0" "mmap" "\0" "maps" "\0", d_ent->d_name ) ) { enum { CWD_LINK, EXE_LINK, ROOT_LINK, FD_DIR_LINKS, LIB_DIR_LINKS, MMAP_DIR_LINKS, MAPS, }; case CWD_LINK: case EXE_LINK: case ROOT_LINK: goto scan_link; case FD_DIR_LINKS: case LIB_DIR_LINKS: case MMAP_DIR_LINKS: // change for ofgwrite retval = scan_recursive(subpath); break; case MAPS: // change for ofgwrite retval = scan_proc_net_or_maps(subpath, 0); default: break; } break; case PROC_SUBDIR_LINKS: scan_link: if (stat(subpath, &statbuf) < 0) break; // change for ofgwrite retval = search_dev_inode(&statbuf); if (retval) { if (strcmp(d_ent->d_name, "exe") == 0) { char* ln = xmalloc_readlink(subpath); if (ln != NULL) { // change for ofgwrite: Don't kill VU+ and GB specific processes if (strcmp(ln, "/oldroot/usr/bin/dvb_server") == 0 || strcmp(ln, "/oldroot/usr/bin/init_client") == 0 || strcmp(ln, "/oldroot/usr/bin/ntfs-3g") == 0 || strcmp(ln, "/oldroot/usr/share/platform/dvb_init") == 0 || strcmp(ln, "/oldroot/usr/bin/nxserver") == 0 || strcmp(ln, "/oldroot/usr/bin/init_driver") == 0 || strcmp(ln, "/oldroot/usr/share/platform/dvb_init.bin") == 0 || strcmp(ln, "/oldroot/usr/share/platform/nxserver") == 0 || strcmp(ln, "/oldroot/usr/bin/showiframe") == 0 || strcmp(ln, "/oldroot/usr/bin/libreader") == 0 || ( strncmp(ln, "/oldroot/lib/modules/", 21) == 0 && strstr(ln, "/extra/hi_play.ko") != NULL ) ) { my_printf("found vu or gb or octagon or ntfs process %s -> don't kill\n", ln); retval = 0; stop_scan=1; } free(ln); } } } default: break; } free(subpath); } closedir(d); G.recursion_depth--; return retval; }