+ if (stat(name, &s) != 0)
+ return 0;
+
+ if ((s.st_mode & S_IFMT) == S_IFBLK)
+ mountDevice = s.st_rdev;
+ else
+ mountDevice = s.st_dev;
+
+
+ if ((mountTable = setmntent(table, "r")) == 0)
+ return 0;
+
+ while ((mountEntry = getmntent(mountTable)) != 0) {
+ if (strcmp(name, mountEntry->mnt_dir) == 0
+ || strcmp(name, mountEntry->mnt_fsname) == 0) /* String match. */
+ break;
+ if (stat(mountEntry->mnt_fsname, &s) == 0 && s.st_rdev == mountDevice) /* Match the device. */
+ break;
+ if (stat(mountEntry->mnt_dir, &s) == 0 && s.st_dev == mountDevice) /* Match the directory's mount point. */
+ break;
+ }
+ endmntent(mountTable);
+ return mountEntry;
+}
+#endif /* BB_DF || BB_MTAB */
+
+
+
+#if defined BB_DD || defined BB_TAIL
+/*
+ * Read a number with a possible multiplier.
+ * Returns -1 if the number format is illegal.
+ */
+extern long getNum(const char *cp)
+{
+ long value;
+
+ if (!isDecimal(*cp))
+ return -1;
+
+ value = 0;
+
+ while (isDecimal(*cp))
+ value = value * 10 + *cp++ - '0';
+
+ switch (*cp++) {
+ case 'M':
+ case 'm': /* `tail' uses it traditionally */
+ value *= 1048576;
+ break;
+
+ case 'k':
+ value *= 1024;
+ break;
+
+ case 'b':
+ value *= 512;
+ break;
+
+ case 'w':
+ value *= 2;
+ break;
+
+ case '\0':
+ return value;
+
+ default:
+ return -1;
+ }
+
+ if (*cp)
+ return -1;
+
+ return value;
+}
+#endif /* BB_DD || BB_TAIL */
+
+
+#if defined BB_INIT || defined BB_SYSLOGD
+/* try to open up the specified device */
+extern int device_open(char *device, int mode)
+{
+ int m, f, fd = -1;
+
+ m = mode | O_NONBLOCK;
+
+ /* Retry up to 5 times */
+ for (f = 0; f < 5; f++)
+ if ((fd = open(device, m, 0600)) >= 0)
+ break;
+ if (fd < 0)
+ return fd;
+ /* Reset original flags. */
+ if (m != mode)
+ fcntl(fd, F_SETFL, mode);
+ return fd;
+}
+#endif /* BB_INIT BB_SYSLOGD */
+
+
+#if defined BB_KILLALL || ( defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF ))
+#ifdef BB_FEATURE_USE_DEVPS_PATCH
+#include <linux/devps.h> /* For Erik's nifty devps device driver */
+#endif
+
+#if defined BB_FEATURE_USE_DEVPS_PATCH
+/* findPidByName()
+ *
+ * This finds the pid of the specified process,
+ * by using the /dev/ps device driver.
+ *
+ * Returns a list of all matching PIDs
+ */
+extern pid_t* findPidByName( char* pidName)
+{
+ int fd, i, j;
+ char device[] = "/dev/ps";
+ pid_t num_pids;
+ pid_t* pid_array = NULL;
+ pid_t* pidList=NULL;
+
+ /* open device */
+ fd = open(device, O_RDONLY);
+ if (fd < 0)
+ fatalError( "open failed for `%s': %s\n", device, strerror (errno));
+
+ /* Find out how many processes there are */
+ if (ioctl (fd, DEVPS_GET_NUM_PIDS, &num_pids)<0)
+ fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+
+ /* Allocate some memory -- grab a few extras just in case
+ * some new processes start up while we wait. The kernel will
+ * just ignore any extras if we give it too many, and will trunc.
+ * the list if we give it too few. */
+ pid_array = (pid_t*) calloc( num_pids+10, sizeof(pid_t));
+ pid_array[0] = num_pids+10;
+
+ /* Now grab the pid list */
+ if (ioctl (fd, DEVPS_GET_PID_LIST, pid_array)<0)
+ fatalError( "\nDEVPS_GET_PID_LIST: %s\n", strerror (errno));
+
+ /* Now search for a match */
+ for (i=1, j=0; i<pid_array[0] ; i++) {
+ char* p;
+ struct pid_info info;
+
+ info.pid = pid_array[i];
+ if (ioctl (fd, DEVPS_GET_PID_INFO, &info)<0)
+ fatalError( "\nDEVPS_GET_PID_INFO: %s\n", strerror (errno));
+
+ /* Make sure we only match on the process name */
+ p=info.command_line+1;
+ while ((*p != 0) && !isspace(*(p)) && (*(p-1) != '\\')) {
+ (p)++;
+ }
+ if (isspace(*(p)))
+ *p='\0';
+
+ if ((strstr(info.command_line, pidName) != NULL)
+ && (strlen(pidName) == strlen(info.command_line))) {
+ pidList=realloc( pidList, sizeof(pid_t) * (j+2));
+ if (pidList==NULL)
+ fatalError(memory_exhausted, "");
+ pidList[j++]=info.pid;
+ }
+ }
+ if (pidList)
+ pidList[j]=0;
+
+ /* Free memory */
+ free( pid_array);
+
+ /* close device */
+ if (close (fd) != 0)
+ fatalError( "close failed for `%s': %s\n",device, strerror (errno));
+
+ return pidList;
+}
+#else /* BB_FEATURE_USE_DEVPS_PATCH */
+#if ! defined BB_FEATURE_USE_PROCFS
+#error Sorry, I depend on the /proc filesystem right now.
+#endif
+
+/* findPidByName()
+ *
+ * This finds the pid of the specified process.
+ * Currently, it's implemented by rummaging through
+ * the proc filesystem.
+ *
+ * Returns a list of all matching PIDs
+ */
+extern pid_t* findPidByName( char* pidName)
+{
+ DIR *dir;
+ struct dirent *next;
+ pid_t* pidList=NULL;
+ int i=0;
+
+ dir = opendir("/proc");
+ if (!dir)
+ fatalError( "Cannot open /proc: %s\n", strerror (errno));
+
+ while ((next = readdir(dir)) != NULL) {
+ FILE *status;
+ char filename[256];
+ char buffer[256];
+ char* p;
+
+ /* If it isn't a number, we don't want it */
+ if (!isdigit(*next->d_name))
+ continue;
+
+ /* Now open the status file */
+ sprintf(filename, "/proc/%s/status", next->d_name);
+ status = fopen(filename, "r");
+ if (!status) {
+ continue;
+ }
+ fgets(buffer, 256, status);
+ fclose(status);
+
+ /* Make sure we only match on the process name */
+ p=buffer+5; /* Skip the name */
+ while ((p)++) {
+ if (*p==0 || *p=='\n') {
+ *p='\0';
+ break;
+ }
+ }
+ p=buffer+6; /* Skip the "Name:\t" */
+
+ if ((strstr(p, pidName) != NULL)
+ && (strlen(pidName) == strlen(p))) {
+ pidList=realloc( pidList, sizeof(pid_t) * (i+2));
+ if (pidList==NULL)
+ fatalError(memory_exhausted, "");
+ pidList[i++]=strtol(next->d_name, NULL, 0);
+ }
+ }
+ if (pidList)
+ pidList[i]=0;
+ return pidList;
+}
+#endif /* BB_FEATURE_USE_DEVPS_PATCH */
+#endif /* BB_KILLALL || ( BB_FEATURE_LINUXRC && ( BB_HALT || BB_REBOOT || BB_POWEROFF )) */
+
+/* this should really be farmed out to libbusybox.a */
+extern void *xmalloc(size_t size)
+{
+ void *cp = malloc(size);
+
+ if (cp == NULL)
+ fatalError(memory_exhausted, "");
+ return cp;
+}
+
+#if defined BB_FEATURE_NFSMOUNT
+extern char * xstrdup (const char *s) {
+ char *t;
+
+ if (s == NULL)
+ return NULL;
+
+ t = strdup (s);
+
+ if (t == NULL)
+ fatalError(memory_exhausted, "");
+
+ return t;
+}
+
+extern char * xstrndup (const char *s, int n) {
+ char *t;