fedora core 6 1.2949 + vserver 2.2.0
[linux-2.6.git] / scripts / mod / sumversion.c
index b41b718..8a28756 100644 (file)
@@ -1,43 +1,14 @@
 #include <netinet/in.h>
+#ifdef __sun__
+#include <inttypes.h>
+#else
 #include <stdint.h>
+#endif
 #include <ctype.h>
 #include <errno.h>
 #include <string.h>
 #include "modpost.h"
 
-/* Parse tag=value strings from .modinfo section */
-static char *next_string(char *string, unsigned long *secsize)
-{
-       /* Skip non-zero chars */
-       while (string[0]) {
-               string++;
-               if ((*secsize)-- <= 1)
-                       return NULL;
-       }
-
-       /* Skip any zero padding. */
-       while (!string[0]) {
-               string++;
-               if ((*secsize)-- <= 1)
-                       return NULL;
-       }
-       return string;
-}
-
-static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
-                        const char *tag)
-{
-       char *p;
-       unsigned int taglen = strlen(tag);
-       unsigned long size = modinfo_len;
-
-       for (p = modinfo; p; p = next_string(p, &size)) {
-               if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
-                       return p + taglen + 1;
-       }
-       return NULL;
-}
-
 /*
  * Stolen form Cryptographic API.
  *
@@ -345,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
 
        file = grab_file(cmd, &flen);
        if (!file) {
-               fprintf(stderr, "Warning: could not find %s for %s\n",
-                       cmd, objfile);
+               warn("could not find %s for %s\n", cmd, objfile);
                goto out;
        }
 
@@ -384,9 +354,8 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md)
                /* Check if this file is in same dir as objfile */
                if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
                        if (!parse_file(line, md)) {
-                               fprintf(stderr,
-                                       "Warning: could not open %s: %s\n",
-                                       line, strerror(errno));
+                               warn("could not open %s: %s\n",
+                                    line, strerror(errno));
                                goto out_file;
                        }
 
@@ -404,15 +373,19 @@ out:
        return ret;
 }
 
-static int get_version(const char *modname, char sum[])
+/* Calc and record src checksum. */
+void get_src_version(const char *modname, char sum[], unsigned sumlen)
 {
        void *file;
        unsigned long len;
-       int ret = 0;
        struct md4_ctx md;
        char *sources, *end, *fname;
        const char *basename;
-       char filelist[sizeof(".tmp_versions/%s.mod") + strlen(modname)];
+       char filelist[PATH_MAX + 1];
+       char *modverdir = getenv("MODVERDIR");
+
+       if (!modverdir)
+               modverdir = ".";
 
        /* Source files for module are in .tmp_versions/modname.mod,
           after the first line. */
@@ -420,45 +393,40 @@ static int get_version(const char *modname, char sum[])
                basename = strrchr(modname, '/') + 1;
        else
                basename = modname;
-       sprintf(filelist, ".tmp_versions/%s", basename);
-       /* Truncate .o, add .mod */
-       strcpy(filelist + strlen(filelist)-2, ".mod");
+       sprintf(filelist, "%s/%.*s.mod", modverdir,
+               (int) strlen(basename) - 2, basename);
 
        file = grab_file(filelist, &len);
        if (!file) {
-               fprintf(stderr, "Warning: could not find versions for %s\n",
-                       filelist);
-               return 0;
+               warn("could not find versions for %s\n", filelist);
+               return;
        }
 
        sources = strchr(file, '\n');
        if (!sources) {
-               fprintf(stderr, "Warning: malformed versions file for %s\n",
-                       modname);
+               warn("malformed versions file for %s\n", modname);
                goto release;
        }
 
        sources++;
        end = strchr(sources, '\n');
        if (!end) {
-               fprintf(stderr, "Warning: bad ending versions file for %s\n",
-                       modname);
+               warn("bad ending versions file for %s\n", modname);
                goto release;
        }
        *end = '\0';
 
        md4_init(&md);
-       for (fname = strtok(sources, " "); fname; fname = strtok(NULL, " ")) {
+       while ((fname = strsep(&sources, " ")) != NULL) {
+               if (!*fname)
+                       continue;
                if (!parse_source_files(fname, &md))
                        goto release;
        }
 
-       /* sum is of form \0<padding>. */
-       md4_final_ascii(&md, sum, 1 + strlen(sum+1));
-       ret = 1;
+       md4_final_ascii(&md, sum, sumlen);
 release:
        release_file(file, len);
-       return ret;
 }
 
 static void write_version(const char *filename, const char *sum,
@@ -468,19 +436,19 @@ static void write_version(const char *filename, const char *sum,
 
        fd = open(filename, O_RDWR);
        if (fd < 0) {
-               fprintf(stderr, "Warning: changing sum in %s failed: %s\n",
+               warn("changing sum in %s failed: %s\n",
                        filename, strerror(errno));
                return;
        }
 
        if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
-               fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n",
+               warn("changing sum in %s:%lu failed: %s\n",
                        filename, offset, strerror(errno));
                goto out;
        }
 
        if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
-               fprintf(stderr, "Warning: writing sum in %s failed: %s\n",
+               warn("writing sum in %s failed: %s\n",
                        filename, strerror(errno));
                goto out;
        }
@@ -488,12 +456,12 @@ out:
        close(fd);
 }
 
-void strip_rcs_crap(char *version)
+static int strip_rcs_crap(char *version)
 {
        unsigned int len, full_len;
 
        if (strncmp(version, "$Revision", strlen("$Revision")) != 0)
-               return;
+               return 0;
 
        /* Space for version string follows. */
        full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2;
@@ -514,31 +482,15 @@ void strip_rcs_crap(char *version)
                len++;
        memmove(version + len, version + strlen(version),
                full_len - strlen(version));
+       return 1;
 }
 
-/* If the modinfo contains a "version" value, then set this. */
-void maybe_frob_version(const char *modfilename,
-                       void *modinfo,
-                       unsigned long modinfo_len,
-                       unsigned long modinfo_offset)
+/* Clean up RCS-style version numbers. */
+void maybe_frob_rcs_version(const char *modfilename,
+                           char *version,
+                           void *modinfo,
+                           unsigned long version_offset)
 {
-       char *version, *csum;
-
-       version = get_modinfo(modinfo, modinfo_len, "version");
-       if (!version)
-               return;
-
-       /* RCS $Revision gets stripped out. */
-       strip_rcs_crap(version);
-
-       /* Check against double sumversion */
-       if (strchr(version, ' '))
-               return;
-
-       /* Version contains embedded NUL: second half has space for checksum */
-       csum = version + strlen(version);
-       *(csum++) = ' ';
-       if (get_version(modfilename, csum))
-               write_version(modfilename, version,
-                             modinfo_offset + (version - (char *)modinfo));
+       if (strip_rcs_crap(version))
+               write_version(modfilename, version, version_offset);
 }