exit FALSE;
}
-extern void errorMsg(char *s, ...)
+extern void errorMsg(const char *s, ...)
{
va_list p;
va_start(p, s);
fflush(stdout);
vfprintf(stderr, s, p);
- fprintf(stderr, "\n");
va_end(p);
+ fflush(stderr);
}
-extern void fatalError(char *s, ...)
+extern void fatalError(const char *s, ...)
{
va_list p;
va_start(p, s);
fflush(stdout);
vfprintf(stderr, s, p);
- fprintf(stderr, "\n");
va_end(p);
+ fflush(stderr);
exit( FALSE);
}
-#if defined (BB_INIT) || defined (BB_PS)
+#if defined BB_INIT
/* 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> }
+ * if (get_kernel_revision() <= 2*65536+2*256+11) { <stuff> }
*/
-int get_kernel_revision()
+extern int get_kernel_revision(void)
{
struct utsname name;
int major = 0, minor = 0, patch = 0;
sscanf(name.version, "%d.%d.%d", &major, &minor, &patch);
return major * 65536 + minor * 256 + patch;
}
-#endif /* BB_INIT || BB_PS */
+#endif /* BB_INIT */
#if defined (BB_CP_MV) || defined (BB_DU)
i = hash_inode(statbuf->st_ino);
s = name ? strlen(name) : 0;
- bucket = malloc(sizeof(ino_dev_hashtable_bucket_t) + s);
- if (bucket == NULL)
- fatalError("Not enough memory.");
+ bucket = xmalloc(sizeof(ino_dev_hashtable_bucket_t) + s);
bucket->ino = statbuf->st_ino;
bucket->dev = statbuf->st_dev;
if (name)
int recursiveAction(const char *fileName,
int recurse, int followLinks, int depthFirst,
int (*fileAction) (const char *fileName,
- struct stat * statbuf),
+ struct stat * statbuf,
+ void* userData),
int (*dirAction) (const char *fileName,
- struct stat * statbuf))
+ struct stat * statbuf,
+ void* userData),
+ void* userData)
{
int status;
struct stat statbuf;
if (fileAction == NULL)
return TRUE;
else
- return fileAction(fileName, &statbuf);
+ return fileAction(fileName, &statbuf, userData);
}
if (recurse == FALSE) {
if (S_ISDIR(statbuf.st_mode)) {
if (dirAction != NULL)
- return (dirAction(fileName, &statbuf));
+ return (dirAction(fileName, &statbuf, userData));
else
return TRUE;
}
return FALSE;
}
if (dirAction != NULL && depthFirst == FALSE) {
- status = dirAction(fileName, &statbuf);
+ status = dirAction(fileName, &statbuf, userData);
if (status == FALSE) {
perror(fileName);
return FALSE;
sprintf(nextFile, "%s/%s", fileName, next->d_name);
status =
recursiveAction(nextFile, TRUE, followLinks, depthFirst,
- fileAction, dirAction);
+ fileAction, dirAction, userData);
if (status < 0) {
closedir(dir);
return FALSE;
return FALSE;
}
if (dirAction != NULL && depthFirst == TRUE) {
- status = dirAction(fileName, &statbuf);
+ status = dirAction(fileName, &statbuf, userData);
if (status == FALSE) {
perror(fileName);
return FALSE;
if (fileAction == NULL)
return TRUE;
else
- return fileAction(fileName, &statbuf);
+ return fileAction(fileName, &statbuf, userData);
}
return TRUE;
}
-#if defined (BB_CHMOD_CHOWN_CHGRP) || defined (BB_PS)
+#if defined BB_CHMOD_CHOWN_CHGRP || defined BB_PS || defined BB_LS || defined BB_TAR
/* Use this to avoid needing the glibc NSS stuff
* This uses storage buf to hold things.
}
-#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS */
+#endif /* BB_CHMOD_CHOWN_CHGRP || BB_PS || BB_LS || BB_TAR */
if (strcmp(needle, newNeedle) == 0)
return FALSE;
- oldhayStack = (char *) malloc((unsigned) (strlen(haystack)));
+ oldhayStack = (char *) xmalloc((unsigned) (strlen(haystack)));
while (where != NULL) {
foundOne++;
strcpy(oldhayStack, haystack);
#endif /* BB_INIT BB_SYSLOGD */
-#if defined BB_KILLALL || defined BB_FEATURE_LINUXRC && ( defined BB_HALT || defined BB_REBOOT || defined BB_POWEROFF )
-
+#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>
#endif
* This finds the pid of the specified process,
* by using the /dev/ps device driver.
*
- * [return]
- * 0 failure
- * pid when the pid is found.
+ * Returns a list of all matching PIDs
*/
-extern pid_t findPidByName( char* pidName)
+extern pid_t* findPidByName( char* pidName)
{
- int fd, i;
+ int fd, i, j;
char device[] = "/dev/ps";
- pid_t thePid = 0;
pid_t num_pids;
pid_t* pid_array = NULL;
+ pid_t* pidList=NULL;
/* open device */
fd = open(device, O_RDONLY);
fatalError( "\nDEVPS_GET_PID_INFO: %s\n", strerror (errno));
if ((strstr(info.command_line, pidName) != NULL)) {
- thePid = info.pid;
- break;
+ pidList=realloc( pidList, sizeof(pid_t) * (j+2));
+ if (pidList==NULL)
+ fatalError("out of memory\n");
+ pidList[j++]=info.pid;
}
}
+ pidList[j]=0;
/* Free memory */
free( pid_array);
if (close (fd) != 0)
fatalError( "close failed for `%s': %s\n",device, strerror (errno));
- return thePid;
+ return pidList;
}
#else /* BB_FEATURE_USE_DEVPS_PATCH */
#if ! defined BB_FEATURE_USE_PROCFS
* Currently, it's implemented by rummaging through
* the proc filesystem.
*
- * [return]
- * 0 failure
- * pid when the pid is found.
+ * Returns a list of all matching PIDs
*/
-extern pid_t findPidByName( char* pidName)
+extern pid_t* findPidByName( char* pidName)
{
DIR *dir;
struct dirent *next;
+ pid_t* pidList=NULL;
+ int i=0;
dir = opendir("/proc");
if (!dir)
if (!isdigit(*next->d_name))
continue;
- /* Now open the command line file */
+ /* Now open the status file */
sprintf(filename, "/proc/%s/status", next->d_name);
status = fopen(filename, "r");
if (!status) {
fclose(status);
if ((strstr(buffer, pidName) != NULL)) {
- return strtol(next->d_name, NULL, 0);
+ pidList=realloc( pidList, sizeof(pid_t) * (i+2));
+ if (pidList==NULL)
+ fatalError("out of memory\n");
+ pidList[i++]=strtol(next->d_name, NULL, 0);
}
}
- return 0;
+ pidList[i]=0;
+ return pidList;
}
#endif /* BB_FEATURE_USE_DEVPS_PATCH */
-#endif /* BB_INIT || BB_HALT || BB_REBOOT || BB_KILLALL || BB_POWEROFF */
+#endif /* BB_KILLALL || ( BB_FEATURE_LINUXRC && ( BB_HALT || BB_REBOOT || BB_POWEROFF )) */
-#if defined BB_GUNZIP \
- || defined BB_GZIP \
- || defined BB_PRINTF \
- || defined BB_TAIL
+/* this should really be farmed out to libbusybox.a */
extern void *xmalloc(size_t size)
{
void *cp = malloc(size);
- if (cp == NULL) {
- errorMsg("out of memory");
- }
+ if (cp == NULL)
+ fatalError("out of memory\n");
return cp;
}
-#endif /* BB_GUNZIP || BB_GZIP || BB_PRINTF || BB_TAIL */
-
#if (__GLIBC__ < 2) && (defined BB_SYSLOGD || defined BB_INIT)
extern int vdprintf(int d, const char *format, va_list ap)
{
}
#endif /* BB_FEATURE_MOUNT_LOOP */
-#if defined BB_MTAB
-#define whine_if_fstab_is_missing() {}
-#else
-extern void whine_if_fstab_is_missing()
+#if defined BB_MOUNT || defined BB_DF
+extern int find_real_root_device_name(char* name)
{
- struct stat statBuf;
+ DIR *dir;
+ struct dirent *entry;
+ struct stat statBuf, rootStat;
+ char fileName[BUFSIZ];
- if (stat("/etc/fstab", &statBuf) < 0)
- fprintf(stderr,
- "/etc/fstab file missing -- install one to name /dev/root.\n\n");
+ if (stat("/", &rootStat) != 0) {
+ errorMsg("could not stat '/'\n");
+ return( FALSE);
+ }
+
+ dir = opendir("/dev");
+ if (!dir) {
+ errorMsg("could not open '/dev'\n");
+ return( FALSE);
+ }
+
+ while((entry = readdir(dir)) != NULL) {
+
+ /* Must skip ".." since that is "/", and so we
+ * would get a false positive on ".." */
+ if (strcmp(entry->d_name, "..") == 0)
+ continue;
+
+ sprintf( fileName, "/dev/%s", entry->d_name);
+
+ if (stat(fileName, &statBuf) != 0)
+ continue;
+ /* Some char devices have the same dev_t as block
+ * devices, so make sure this is a block device */
+ if (! S_ISBLK(statBuf.st_mode))
+ continue;
+ if (statBuf.st_rdev == rootStat.st_rdev) {
+ strcpy(name, fileName);
+ return ( TRUE);
+ }
+ }
+
+ return( FALSE);
}
#endif
+const unsigned int CSTRING_BUFFER_LENGTH = 128;
+/* recursive parser that returns cstrings of arbitrary length
+ * from a FILE*
+ */
+static char *
+cstring_alloc(FILE* f, int depth)
+{
+ char *cstring;
+ char buffer[CSTRING_BUFFER_LENGTH];
+ int target = CSTRING_BUFFER_LENGTH * depth;
+ int i, len;
+ int size;
+
+ /* fill buffer */
+ i = 0;
+ while ((buffer[i] = fgetc(f)) != EOF) {
+ if (buffer[i++] == 0x0a) { break; }
+ if (i == CSTRING_BUFFER_LENGTH) { break; }
+ }
+ len = i;
+
+ /* recurse or malloc? */
+ if (len == CSTRING_BUFFER_LENGTH) {
+ cstring = cstring_alloc(f, (depth + 1));
+ } else {
+ /* [special case] EOF */
+ if ((depth | len) == 0) { return NULL; }
+
+ /* malloc */
+ size = target + len + 1;
+ cstring = malloc(size);
+ if (!cstring) { return NULL; }
+ cstring[size - 1] = 0;
+ }
+
+ /* copy buffer */
+ if (cstring) {
+ memcpy(&cstring[target], buffer, len);
+ }
+ return cstring;
+}
+
+/*
+ * wrapper around recursive cstring_alloc
+ * it's the caller's responsibility to free the cstring
+ */
+char *
+cstring_lineFromFile(FILE *f)
+{
+ return cstring_alloc(f, 0);
+}
+
/* END CODE */
/*
Local Variables: