diff --git a/ChangeLog b/ChangeLog index 0505c87d..540129cf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,8 @@ v0.51.3 22-Mar-2003 mbtask: Fixed crash on NetBSD Sparc when getsysinfo was called. + Fixed disk search check when /opt/mbse is a symlink on a non- + root disk to display the correct partition. mblogin: Changed some defines for NetBSD 1.6.2 diff --git a/mbtask/taskdisk.c b/mbtask/taskdisk.c index 9f15b401..c67c68a6 100644 --- a/mbtask/taskdisk.c +++ b/mbtask/taskdisk.c @@ -56,6 +56,7 @@ pthread_mutex_t a_mutex = PTHREAD_MUTEX_INITIALIZER; /* * Internal prototypes */ +char *mbt_realpath(const char *, char *); void tidy_mfslist(mfs_list **); int in_mfslist(char *, mfs_list **); void fill_mfslist(mfs_list **, char *, char *); @@ -63,6 +64,122 @@ void update_diskstat(void); void add_path(char *); +/* + * realpath.c -- canonicalize pathname by removing symlinks + * Copyright (C) 1993 Rick Sladkey + */ + +#define HAVE_GETCWD + +/* + * This routine is part of libc. We include it nevertheless, + * since the libc version has some security flaws. + */ +#define MAX_READLINKS 32 + +char *mbt_realpath(const char *path, char *resolved_path) +{ + char copy_path[PATH_MAX], link_path[PATH_MAX], *new_path = resolved_path, *max_path; + int readlinks = 0, n; + + /* Make a copy of the source path since we may need to modify it. */ + if (strlen(path) >= PATH_MAX) { + errno = ENAMETOOLONG; + return NULL; + } + strcpy(copy_path, path); + path = copy_path; + max_path = copy_path + PATH_MAX - 2; + + /* If it's a relative pathname use getwd for starters. */ + if (*path != '/') { + getcwd(new_path, PATH_MAX - 1); + new_path += strlen(new_path); + if (new_path[-1] != '/') + *new_path++ = '/'; + } else { + *new_path++ = '/'; + path++; + } + /* Expand each slash-separated pathname component. */ + while (*path != '\0') { + /* Ignore stray "/". */ + if (*path == '/') { + path++; + continue; + } + if (*path == '.') { + /* Ignore ".". */ + if (path[1] == '\0' || path[1] == '/') { + path++; + continue; + } + if (path[1] == '.') { + if (path[2] == '\0' || path[2] == '/') { + path += 2; + /* Ignore ".." at root. */ + if (new_path == resolved_path + 1) + continue; + /* Handle ".." by backing up. */ + while ((--new_path)[-1] != '/') + ; + continue; + } + } + } + /* Safely copy the next pathname component. */ + while (*path != '\0' && *path != '/') { + if (path > max_path) { + errno = ENAMETOOLONG; + return NULL; + } + *new_path++ = *path++; + } +#ifdef S_IFLNK + /* Protect against infinite loops. */ + if (readlinks++ > MAX_READLINKS) { + errno = ELOOP; + return NULL; + } + /* See if latest pathname component is a symlink. */ + *new_path = '\0'; + n = readlink(resolved_path, link_path, PATH_MAX - 1); + if (n < 0) { + /* EINVAL means the file exists but isn't a symlink. */ + if (errno != EINVAL) + return NULL; + } else { + /* Note: readlink doesn't add the null byte. */ + link_path[n] = '\0'; + if (*link_path == '/') + /* Start over for an absolute symlink. */ + new_path = resolved_path; + else + /* Otherwise back up over this component. */ + while (*(--new_path) != '/') + ; + /* Safe sex check. */ + if (strlen(path) + n >= PATH_MAX) { + errno = ENAMETOOLONG; + return NULL; + } + /* Insert symlink contents into path. */ + strcat(link_path, path); + strcpy(copy_path, link_path); + path = copy_path; + } +#endif /* S_IFLNK */ + *new_path++ = '/'; + } + /* Delete trailing slash but don't whomp a lone slash. */ + if (new_path != resolved_path + 1 && new_path[-1] == '/') + new_path--; + /* Make sure it's null terminated. */ + *new_path = '\0'; + return resolved_path; +} + + /* * Reset mounted filesystems array @@ -285,7 +402,7 @@ void add_path(char *lpath) } rpath = calloc(PATH_MAX, sizeof(char)); - realpath(lpath, rpath); + mbt_realpath(lpath, rpath); Syslog('d', "realpath %s", MBSE_SS(rpath)); if (lstat(rpath, &sb) == 0) { diff --git a/mbtask/taskinfo.c b/mbtask/taskinfo.c index 059faaf7..231ddb2a 100644 --- a/mbtask/taskinfo.c +++ b/mbtask/taskinfo.c @@ -39,31 +39,31 @@ */ char *get_sysinfo(void) { - FILE *fp; - static char buf[SS_BUFSIZE]; - char *temp; - time_t startdate; + FILE *fp; + static char buf[SS_BUFSIZE]; + char *temp; + time_t startdate; - sprintf(buf, "201:1,16;"); - temp = calloc(PATH_MAX, sizeof(char)); - sprintf(temp, "%s/etc/sysinfo.data", getenv("MBSE_ROOT")); + sprintf(buf, "201:1,16;"); + temp = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s/etc/sysinfo.data", getenv("MBSE_ROOT")); - if ((fp = fopen(temp, "r")) == NULL) { - free(temp); - return buf; - } + if ((fp = fopen(temp, "r")) == NULL) { free(temp); + return buf; + } + free(temp); - if (fread(&SYSINFO, sizeof(SYSINFO), 1, fp) == 1) { - startdate = SYSINFO.StartDate; - sprintf(buf, "100:7,%ld,%ld,%ld,%ld,%ld,%s,%s;", SYSINFO.SystemCalls, + if (fread(&SYSINFO, sizeof(SYSINFO), 1, fp) == 1) { + startdate = SYSINFO.StartDate; + sprintf(buf, "100:7,%ld,%ld,%ld,%ld,%ld,%s,%s;", SYSINFO.SystemCalls, SYSINFO.Pots, SYSINFO.ISDN, SYSINFO.Network, SYSINFO.Local, ctime(&startdate), SYSINFO.LastCaller); - } + } - fclose(fp); + fclose(fp); - return buf; + return buf; }