.
OBS-URL: https://build.opensuse.org/package/show/Base:System/sysvinit?expand=0&rev=88
This commit is contained in:
parent
6b6b81c704
commit
5962f1a6dc
@ -1,21 +1,95 @@
|
||||
--- libinit.c
|
||||
+++ libinit.c 2011-01-21 18:25:49.019926024 +0000
|
||||
@@ -307,15 +307,16 @@ static void init_mounts(void)
|
||||
+++ libinit.c 2011-01-27 12:58:48.944425833 +0000
|
||||
@@ -218,6 +218,26 @@ static struct _sys_signals {
|
||||
{ 0, "EXIT" }
|
||||
};
|
||||
|
||||
+/*
|
||||
+ * Calculate the depth of a directory, root has zero depth.
|
||||
+ */
|
||||
+static size_t dirdepth(const char *const path)
|
||||
+{
|
||||
+ const char *ptr = path;
|
||||
+ size_t cnt = 0;
|
||||
+
|
||||
+ do {
|
||||
+ const size_t off = strcspn(ptr, "/");
|
||||
+ ptr += off;
|
||||
+ if (*ptr++ != '/')
|
||||
+ break;
|
||||
+ if (*ptr)
|
||||
+ cnt++;
|
||||
+ } while (*ptr);
|
||||
+
|
||||
+ return cnt;
|
||||
+}
|
||||
+
|
||||
typedef struct _mntinfo_
|
||||
{
|
||||
struct _mntinfo_ *next;
|
||||
@@ -226,6 +246,7 @@ typedef struct _mntinfo_
|
||||
int id, parid;
|
||||
dev_t dev;
|
||||
size_t nlen;
|
||||
+ size_t deep;
|
||||
char * point;
|
||||
} MNTINFO;
|
||||
|
||||
@@ -253,6 +274,7 @@ static void init_mounts(void)
|
||||
p->point = ((char*)p)+alignof(MNTINFO);
|
||||
strcpy(p->point, point);
|
||||
p->nlen = nlen;
|
||||
+ p->deep = dirdepth(point);
|
||||
p->parid = parid;
|
||||
p->dev = makedev(maj, min);
|
||||
p->id = mid;
|
||||
@@ -262,20 +284,20 @@ static void init_mounts(void)
|
||||
p->prev = (MNTINFO*)0;
|
||||
p->parent = p;
|
||||
mounts = p;
|
||||
- if (mid > max)
|
||||
- max = mid;
|
||||
+ if (p->id > max)
|
||||
+ max = p->id;
|
||||
}
|
||||
fclose(mnt);
|
||||
|
||||
- /* Sort mount points accordingly to the reverse mount order */
|
||||
+ /* Sort mount points accordingly to their reverse directory depth */
|
||||
save = (MNTINFO*)0;
|
||||
- for (mid = 1; mid <= max; mid++) {
|
||||
+ for (mid = 0; mounts; mid++) {
|
||||
MNTINFO *m, *n, *l;
|
||||
n = mounts;
|
||||
l = (MNTINFO*)0;
|
||||
for (m = mounts; n; m = n) {
|
||||
n = m->next;
|
||||
- if (m->id != mid)
|
||||
+ if (m->deep != mid)
|
||||
continue;
|
||||
l = m->prev;
|
||||
if (m == mounts) {
|
||||
@@ -290,7 +312,6 @@ static void init_mounts(void)
|
||||
m->next = save;
|
||||
m->prev = (MNTINFO*)0;
|
||||
save = m;
|
||||
- break;
|
||||
}
|
||||
}
|
||||
mounts = save;
|
||||
@@ -307,15 +328,14 @@ static void init_mounts(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static MNTINFO *find_mount(const char * path)
|
||||
+static int find_mount(const char * path, MNTINFO *s)
|
||||
{
|
||||
- MNTINFO *m;
|
||||
+ MNTINFO *m, *p = s->parent;
|
||||
MNTINFO *m;
|
||||
for (m = mounts; m; m = m->next) {
|
||||
- if (strncmp(path, m->point, m->nlen))
|
||||
- continue;
|
||||
- break;
|
||||
+ if (s == m && strncmp(path, m->point, m->nlen) == 0)
|
||||
+ return 1;
|
||||
+ if (p == m && strncmp(path, p->point, p->nlen) == 0)
|
||||
+ if (s == m)
|
||||
+ return 1;
|
||||
}
|
||||
- return m;
|
||||
@ -23,10 +97,43 @@
|
||||
}
|
||||
|
||||
extern inline char * handl_buf(char *restrict buf)
|
||||
@@ -728,19 +729,21 @@ int pidof (const char * inname, const ch
|
||||
@@ -627,6 +647,7 @@ int pidof (const char * inname, const ch
|
||||
pid_t pid;
|
||||
char *swapname = NULL;
|
||||
char *fullname = (char *)inname;
|
||||
+ char *realname = NULL;
|
||||
MNTINFO *prefix = NULL;
|
||||
PROC *p, *n;
|
||||
|
||||
@@ -659,12 +680,17 @@ int pidof (const char * inname, const ch
|
||||
warn("cannot stat %s: %s\n", fullname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
- init_mounts();
|
||||
- for (m = mounts; m; m = m->next) {
|
||||
- if (m->dev != full_st.st_dev)
|
||||
- continue;
|
||||
- prefix = m;
|
||||
- break;
|
||||
+ realname = expandpath(fullname);
|
||||
+ if (realname) {
|
||||
+ init_mounts();
|
||||
+ for (m = mounts; m; m = m->next) {
|
||||
+ if (m->dev != full_st.st_dev)
|
||||
+ continue;
|
||||
+ if (strncmp(realname, m->point, m->nlen) != 0)
|
||||
+ continue;
|
||||
+ prefix = m;
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -727,20 +753,21 @@ int pidof (const char * inname, const ch
|
||||
*/
|
||||
if (!(flags & (KTHREAD|KSHORT)) && !isscrpt) {
|
||||
char entry[PATH_MAX+1];
|
||||
char *realname = NULL;
|
||||
- char *realname = NULL;
|
||||
- const char *name;
|
||||
+ const char *name = NULL;
|
||||
boolean found;
|
||||
@ -55,7 +162,7 @@
|
||||
|
||||
if (fstatat(dfd, here(d->d_name, "exe"), &pid_st, 0) < 0) {
|
||||
if (errno != EPERM && errno != EACCES)
|
||||
@@ -765,12 +768,22 @@ int pidof (const char * inname, const ch
|
||||
@@ -765,18 +792,24 @@ int pidof (const char * inname, const ch
|
||||
if (strlen(fullname) > PATH_MAX)
|
||||
continue;
|
||||
|
||||
@ -75,7 +182,194 @@
|
||||
}
|
||||
|
||||
- if ((realname = realpath(name, NULL)) == (char*)0)
|
||||
+ if ((realname = realpath(fullname, NULL)) == (char*)0)
|
||||
continue;
|
||||
- continue;
|
||||
-
|
||||
- if (strncmp(realname, name, PATH_MAX) == 0)
|
||||
+ if (realname && strncmp(realname, name, PATH_MAX) == 0)
|
||||
found = true;
|
||||
|
||||
if (strncmp(realname, name, PATH_MAX) == 0)
|
||||
- free(realname);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -896,6 +929,7 @@ int verify_pidfile (const char * pid_fil
|
||||
pid_t pid;
|
||||
char *swapname = NULL, *bufp;
|
||||
char *fullname = (char *)inname;
|
||||
+ char *realname = NULL;
|
||||
struct stat pid_st, full_st;
|
||||
char buf[BUFSIZ];
|
||||
|
||||
@@ -958,6 +992,7 @@ int verify_pidfile (const char * pid_fil
|
||||
warn("cannot stat %s: %s\n", fullname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
+ realname = expandpath(fullname);
|
||||
}
|
||||
|
||||
if (flags & (KTHREAD|KSHORT)) {
|
||||
@@ -997,7 +1032,6 @@ int verify_pidfile (const char * pid_fil
|
||||
|
||||
char entry[PATH_MAX+1];
|
||||
const char *name;
|
||||
- char *realname;
|
||||
boolean found;
|
||||
ssize_t rll;
|
||||
|
||||
@@ -1028,14 +1062,9 @@ int verify_pidfile (const char * pid_fil
|
||||
break;
|
||||
}
|
||||
|
||||
- if ((realname = realpath(fullname, NULL)) == (char*)0)
|
||||
- goto out;
|
||||
-
|
||||
- if (strncmp(realname, name, PATH_MAX) == 0)
|
||||
+ if (realname && strncmp(realname, name, PATH_MAX) == 0)
|
||||
found = true;
|
||||
|
||||
- free(realname);
|
||||
-
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1115,6 +1144,7 @@ int check_pids (const char * inname, con
|
||||
boolean isscrpt = false;
|
||||
char *swapname = (char*)0;
|
||||
char *fullname = (char *)inname;
|
||||
+ char *realname = (char*)0;
|
||||
const char *pid;
|
||||
struct stat pid_st, full_st;
|
||||
PROC *p, *n, *l;
|
||||
@@ -1132,6 +1162,7 @@ int check_pids (const char * inname, con
|
||||
warn("cannot stat %s: %s\n", fullname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
+ realname = expandpath(fullname);
|
||||
}
|
||||
|
||||
if (flags & (KTHREAD|KSHORT)) {
|
||||
@@ -1191,7 +1222,6 @@ int check_pids (const char * inname, con
|
||||
|
||||
char entry[PATH_MAX+1];
|
||||
const char *name;
|
||||
- char *realname;
|
||||
ssize_t rll;
|
||||
|
||||
if (pid_st.st_dev != full_st.st_dev)
|
||||
@@ -1218,14 +1248,8 @@ int check_pids (const char * inname, con
|
||||
if (strncmp(fullname, name, PATH_MAX) == 0)
|
||||
continue; /* Found */
|
||||
|
||||
- if ((realname = realpath(fullname, NULL)) == (char*)0)
|
||||
- goto ignore; /* Bogus */
|
||||
-
|
||||
- if (strncmp(realname, name, PATH_MAX) == 0) {
|
||||
- free(realname);
|
||||
+ if (realname && strncmp(realname, name, PATH_MAX) == 0)
|
||||
continue; /* Found */
|
||||
- }
|
||||
- free(realname);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -1807,4 +1831,100 @@ void clear_nfs(void)
|
||||
}
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * Somehow the realpath(3) glibc function call, nevertheless
|
||||
+ * it avoids lstat(2) system calls.
|
||||
+ */
|
||||
+static char real[PATH_MAX+1];
|
||||
+char* expandpath(const char * path)
|
||||
+{
|
||||
+ char tmpbuf[PATH_MAX+1];
|
||||
+ const char *start, *end;
|
||||
+ char *curr, *dest;
|
||||
+ int deep = MAXSYMLINKS;
|
||||
+
|
||||
+ if (!path || *path == '\0')
|
||||
+ return (char*)0;
|
||||
+
|
||||
+ curr = &real[0];
|
||||
+
|
||||
+ if (*path != '/') {
|
||||
+ if (!getcwd(curr, PATH_MAX))
|
||||
+ return (char*)0;
|
||||
+ dest = rawmemchr(curr, '\0');
|
||||
+ } else {
|
||||
+ *curr = '/';
|
||||
+ dest = curr + 1;
|
||||
+ }
|
||||
+
|
||||
+ for (start = end = path; *start; start = end) {
|
||||
+
|
||||
+ while (*start == '/')
|
||||
+ ++start;
|
||||
+
|
||||
+ for (end = start; *end && *end != '/'; ++end)
|
||||
+ ;
|
||||
+
|
||||
+ if (end - start == 0)
|
||||
+ break;
|
||||
+ else if (end - start == 1 && start[0] == '.') {
|
||||
+ ;
|
||||
+ } else if (end - start == 2 && start[0] == '.' && start[1] == '.') {
|
||||
+ if (dest > curr + 1)
|
||||
+ while ((--dest)[-1] != '/')
|
||||
+ ;
|
||||
+ } else {
|
||||
+ char lnkbuf[PATH_MAX+1];
|
||||
+ size_t len;
|
||||
+ ssize_t n;
|
||||
+
|
||||
+ if (dest[-1] != '/')
|
||||
+ *dest++ = '/';
|
||||
+
|
||||
+ if (dest + (end - start) > curr + PATH_MAX) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ return (char*)0;
|
||||
+ }
|
||||
+
|
||||
+ dest = mempcpy(dest, start, end - start);
|
||||
+ *dest = '\0';
|
||||
+
|
||||
+ if (deep-- < 0) {
|
||||
+ errno = ELOOP;
|
||||
+ return (char*)0;
|
||||
+ }
|
||||
+
|
||||
+ errno = 0;
|
||||
+ if ((n = readlink(curr, lnkbuf, PATH_MAX)) < 0) {
|
||||
+ deep = MAXSYMLINKS;
|
||||
+ if (errno == EINVAL)
|
||||
+ continue; /* Not a symlink */
|
||||
+ return (char*)0;
|
||||
+ }
|
||||
+ lnkbuf[n] = '\0'; /* Don't be fooled by readlink(2) */
|
||||
+
|
||||
+ len = strlen(end);
|
||||
+ if ((n + len) > PATH_MAX) {
|
||||
+ errno = ENAMETOOLONG;
|
||||
+ return (char*)0;
|
||||
+ }
|
||||
+
|
||||
+ memmove(&tmpbuf[n], end, len + 1);
|
||||
+ path = end = memcpy(tmpbuf, lnkbuf, n);
|
||||
+
|
||||
+ if (lnkbuf[0] == '/')
|
||||
+ dest = curr + 1;
|
||||
+ else if (dest > curr + 1)
|
||||
+ while ((--dest)[-1] != '/');
|
||||
+
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ if (dest > curr + 1 && dest[-1] == '/')
|
||||
+ --dest;
|
||||
+ *dest = '\0';
|
||||
+
|
||||
+ return curr;
|
||||
+}
|
||||
+
|
||||
/* libinit.c ends here */
|
||||
|
@ -1,3 +1,10 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 27 13:00:09 UTC 2011 - werner@novell.com
|
||||
|
||||
- Killproc: Sort mount info pointers in the reverse order of the
|
||||
directory depth to become the string compare of the readed link
|
||||
name of the exe link more safely.
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 21 19:26:44 CET 2011 - werner@suse.de
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user