Get more help from gcc, add -Wformat -Werror=format-security -D_FORTIFY_SOURCE=2...
[sysvinit.git] / src / killall5.c
index 7d42eccbc379a00b9706218f993b5da6fbd8583d..187255598df3030a7fce410788d6aa6e30ecf5e4 100644 (file)
@@ -376,6 +376,20 @@ out:
        return 0;
 }
 
+/*
+ * Get the maximal number of symlinks to follow.  Use sysconf() on
+ * Hurd where the hardcoded value MAXSYMLINKS is not available.
+ */
+static int maxsymlinks(void)
+{
+       int v = sysconf(_SC_SYMLOOP_MAX);
+#ifdef MAXSYMLINKS
+       if (v == -1)
+               return MAXSYMLINKS;
+#endif
+       return v;
+}
+
 /*
  *     Check path is located on a network based partition.
  */
@@ -383,7 +397,7 @@ int check4nfs(const char * path, char * real)
 {
        char buf[PATH_MAX+1];
        const char *curr;
-       int deep = MAXSYMLINKS;
+       int deep = maxsymlinks();
 
        if (!nlist) return 0;
 
@@ -508,8 +522,10 @@ int readproc(int do_stat)
 
                /* Read SID & statname from it. */
                if ((fp = fopen(path, "r")) != NULL) {
-                       if (!fgets(buf, sizeof(buf), fp))
-                               buf[0] = '\0';
+                       size_t len;
+
+                       len = fread(buf, sizeof(char), sizeof(buf)-1, fp);
+                       buf[len] = '\0';
 
                        if (buf[0] == '\0') {
                                nsyslog(LOG_ERR,
@@ -638,8 +654,32 @@ int readproc(int do_stat)
                        if ((p->nfs = check4nfs(path, buf)))
                                goto link;
                case DO_STAT:
-                       if (stat(path, &st) != 0)
+                       if (stat(path, &st) != 0) {
+                               char * ptr;
+
+                               len = readlink(path, buf, PATH_MAX);
+                               if (len <= 0)
+                                       break;
+                               buf[len] = '\0';
+
+                               ptr = strstr(buf, " (deleted)");
+                               if (!ptr)
+                                       break;
+                               *ptr = '\0';
+                               len -= strlen(" (deleted)");
+
+                               if (stat(buf, &st) != 0)
+                                       break;
+                               p->dev = st.st_dev;
+                               p->ino = st.st_ino;
+                               p->pathname = (char *)xmalloc(len + 1);
+                               memcpy(p->pathname, buf, len);
+                               p->pathname[len] = '\0';
+
+                               /* All done */
                                break;
+                       }
+
                        p->dev = st.st_dev;
                        p->ino = st.st_ino;