Initial revision
authorewt <devnull@localhost>
Sat, 6 Jan 1996 18:54:50 +0000 (18:54 +0000)
committerewt <devnull@localhost>
Sat, 6 Jan 1996 18:54:50 +0000 (18:54 +0000)
CVS patchset: 149
CVS date: 1996/01/06 18:54:50

lib/oldheader.c [new file with mode: 0644]
lib/oldheader.h [new file with mode: 0644]

diff --git a/lib/oldheader.c b/lib/oldheader.c
new file mode 100644 (file)
index 0000000..9bcfd9e
--- /dev/null
@@ -0,0 +1,316 @@
+#include <endian.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netinet/in.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "misc.h"
+#include "oldheader.h"
+#include "rpmerr.h"
+#include "rpmlib.h"
+
+/* This *can't* read 1.0 headers -- it needs 1.1 (w/ group and icon fields)
+   or better. I'd be surprised if any 1.0 headers are left anywhere anyway.
+   Red Hat 2.0 shipped with 1.1 headers, but some old BETAs used 1.0. */
+
+struct literalHeader {
+    unsigned char m1, m2, m3, m4;
+    unsigned char major, minor;
+
+    unsigned short type, cpu;
+    char labelstr[66];
+    unsigned int specOffset;
+    unsigned int specLength;
+    unsigned int archiveOffset;
+    unsigned int size;
+    unsigned int os;
+    unsigned int groupLength;
+    unsigned int iconLength;
+} ;
+
+/* this leaves the file pointer pointing at the data section */
+
+char * oldhdrReadFromStream(int fd, struct oldrpmHeader * header) {
+    struct literalHeader lit;
+    char * chptr;
+    int bytesRead;
+    char ch;
+    unsigned int specOffset;
+    unsigned int archiveOffset;
+    unsigned int groupLength;
+
+    if (read(fd, &lit, sizeof(lit)) != sizeof(lit)) {
+       return strerror(errno);
+    }
+
+    bytesRead = sizeof(lit);
+
+    if (lit.m1 != 0xed || lit.m2 != 0xab || lit.m3 != 0xee ||
+       lit.m4 != 0xdb) {
+       return "bad magic for RPM package";
+    }
+
+    specOffset = htonl(lit.specOffset);
+    header->specLength = htonl(lit.specLength);
+    archiveOffset = htonl(lit.archiveOffset);
+    header->size = htonl(lit.size);
+    header->os = htonl(lit.os);
+    groupLength = htonl(lit.groupLength);
+    header->iconLength = htonl(lit.iconLength);
+
+    header->spec = malloc(header->specLength);
+    header->name = malloc(strlen(lit.labelstr) + 1);
+    if (!header->spec || !header->name) {
+       header->spec ? free(header->spec) : 0;
+       header->name ? free(header->name) : 0;
+       return "out of memory";
+    }
+
+    strcpy(header->name, lit.labelstr);
+    chptr = header->name + strlen(header->name);
+    while (*chptr != '-') chptr--;
+    *chptr = '\0';
+    header->release = chptr + 1;
+    while (*chptr != '-') chptr--;
+    *chptr = '\0';
+    header->version = chptr + 1;
+
+    if (groupLength) {
+        header->group = malloc(groupLength + 1);
+       if (!header->group) {
+           free(header->spec);
+           free(header->name);
+           return "out of memory";
+       }
+
+       if (read(fd, header->group, groupLength) != groupLength) {
+           oldhdrFree(header);
+           return strerror(errno);
+       }
+       header->group[groupLength] = '\0';
+       bytesRead += groupLength;
+    } else {
+       header->group = NULL;
+    }
+       
+    if (header->iconLength) {
+       header->icon = malloc(header->iconLength);
+       if (!header->icon) {
+           free(header->spec);
+           free(header->name);
+           free(header->icon);
+           return "out of memory";
+       }
+       if (read(fd, header->icon, header->iconLength) != header->iconLength) {
+           oldhdrFree(header);
+           return strerror(errno);
+       }
+       bytesRead += header->iconLength;
+    } else {
+       header->icon = NULL;
+    }
+
+    while (bytesRead < specOffset) {
+       if (read(fd, &ch, 1) != 1) {
+           oldhdrFree(header);
+           return strerror(errno);
+       }
+       bytesRead++;
+    }
+
+    if (read(fd, header->spec, header->specLength) != header->specLength) {
+       oldhdrFree(header);
+       return strerror(errno);
+    }
+    bytesRead += header->specLength;
+
+    while (bytesRead < archiveOffset) {
+       if (read(fd, &ch, 1) != 1) {
+           oldhdrFree(header);
+           return strerror(errno);
+       }
+       bytesRead++;
+    }
+
+    return NULL;
+}
+
+char * oldhdrReadFromFile(char * filename, struct oldrpmHeader * header) {
+    char * rc;
+    int fd;
+
+    fd = open(filename, O_RDONLY);
+    if (fd < 0) return strerror(errno);
+    
+    rc = oldhdrReadFromStream(fd, header);
+    close(fd);
+    
+    return rc;
+}
+
+void oldhdrFree(struct oldrpmHeader * header) {
+    free(header->name);
+    free(header->spec);
+    header->group ? free(header->icon) : 0;
+    header->group ? free(header->group) : 0;
+}
+
+void oldhdrSpecFree(struct oldrpmHeaderSpec * spec) {
+    free(spec->copyright);
+    free(spec->description);
+    free(spec->vendor);
+    free(spec->distribution);
+    free(spec->buildHost);
+
+    while (spec->fileCount) {
+       spec->fileCount--;
+       oldrpmfileFree(spec->files + spec->fileCount);
+    }
+
+    free(spec->files);
+}
+
+char * oldhdrParseSpec(struct oldrpmHeader * header, struct oldrpmHeaderSpec * spec) {
+    char ** lines;
+    char ** strptr;
+    char ** files = NULL;
+    int inFilelist = 0, i;
+
+    lines = splitString(header->spec, header->specLength, '\n');
+    if (!lines) {
+       return "out of memory";
+    }
+
+    /* these are optional */
+    spec->distribution = NULL;
+    spec->vendor = NULL;
+    spec->description = NULL;
+    spec->copyright = NULL;
+
+    spec->fileCount = 0;
+    for (strptr = lines; *strptr; strptr++) {
+       if (inFilelist) {
+           if (**strptr) 
+               spec->fileCount++;
+       } else {
+           if (!strncmp("Description: ", *strptr, 13))
+               spec->description = strdup((*strptr) + 13);
+           else if (!strncmp("Distribution: ", *strptr, 14))
+               spec->distribution = strdup((*strptr) + 14);
+           else if (!strncmp("Vendor: ", *strptr, 8))
+               spec->vendor = strdup((*strptr) + 8);
+           else if (!strncmp("BuildHost: ", *strptr, 11))
+               spec->buildHost = strdup((*strptr) + 11);
+           else if (!strncmp("BuildTime: ", *strptr, 11))
+               spec->buildTime = atoi((*strptr) + 11);
+           else if (!strncmp("Copyright: ", *strptr, 11))
+               spec->copyright = strdup((*strptr) + 11);
+           else if (!strncmp("%speci", *strptr, 6)) {
+               inFilelist = 1;
+               files = strptr + 1;
+           }
+       }
+    }
+
+    spec->files = malloc(sizeof(struct oldrpmFileInfo) * spec->fileCount);
+    if (!spec->files) {
+       freeSplitString(lines);
+       return "out of memory";
+    }
+
+    for (strptr = files, i = 0; *strptr; strptr++, i++) {
+       if (**strptr) 
+           oldrpmfileFromSpecLine(*strptr, spec->files + i);
+    }
+
+    freeSplitString(lines);
+
+    if (!spec->vendor) spec->vendor = strdup("");
+    if (!spec->description) spec->description = strdup("");
+    if (!spec->distribution) spec->distribution = strdup("");
+    if (!spec->copyright) spec->copyright = strdup("");
+
+    return NULL;
+}
+
+static void infoFromFields(char ** fields, struct oldrpmFileInfo * fi);
+
+void oldrpmfileFromInfoLine(char * path, char * state, char * str, 
+                       struct oldrpmFileInfo * fi) {
+    char ** fields;
+
+    fields = splitString(str, strlen(str), ' ');
+
+    fi->path = strdup(path);
+    if (!strcmp(state, "normal"))
+       fi->state = RPMFILE_STATE_NORMAL;
+    else if (!strcmp(state, "replaced"))
+       fi->state = RPMFILE_STATE_REPLACED;
+    else 
+       error(RPMERR_INTERNAL, "bad file state: ", state);
+
+    infoFromFields(fields, fi);
+
+    freeSplitString(fields);
+}
+
+void oldrpmfileFromSpecLine(char * str, struct oldrpmFileInfo * fi) {
+    char ** fields;
+
+    fields = splitString(str, strlen(str), ' ');
+
+    fi->path = strdup(fields[0]);
+    fi->state = RPMFILE_STATE_NORMAL;
+
+    infoFromFields(fields + 1, fi);
+
+    freeSplitString(fields);
+}
+
+void infoFromFields(char ** fields, struct oldrpmFileInfo * fi) {
+    fi->size = strtol(fields[0], NULL, 10);
+    fi->mtime = strtol(fields[1], NULL, 10);
+    strcpy(fi->md5, fields[2]);
+    fi->mode = strtol(fields[3], NULL, 8);
+    fi->uid = strtol(fields[4], NULL, 10);
+    fi->gid = strtol(fields[5], NULL, 10);
+    fi->isconf = fields[6][0] != '0';
+    fi->isdoc = fields[7][0] != '0';
+    fi->rdev = strtol(fields[8], NULL, 16);
+   
+    if (S_ISLNK(fi->mode)) {
+       fi->linkto = strdup(fields[9]);
+    } else {
+       fi->linkto = NULL;
+    }
+}
+
+void oldrpmfileFree(struct oldrpmFileInfo * fi) {
+    free(fi->path);
+    fi->linkto ? free(fi->linkto) : 0;
+}
+
+char * oldrpmfileToInfoStr(struct oldrpmFileInfo * fi) {
+    char * buf;
+
+    if (fi->linkto) 
+       buf = malloc(strlen(fi->linkto) + 100);
+    else
+       buf = malloc(100);
+
+    sprintf(buf, "%ld %ld %s %o %d %d %s %s %x ", fi->size, fi->mtime,
+               fi->md5, fi->mode, fi->uid, fi->gid,
+               fi->isconf ? "1" : "0", fi->isdoc ? "1" : "0",
+               fi->rdev);
+    
+    if (fi->linkto) 
+       strcat(buf, fi->linkto);
+    else
+       strcat(buf, "X");
+    return buf;
+}
diff --git a/lib/oldheader.h b/lib/oldheader.h
new file mode 100644 (file)
index 0000000..878984b
--- /dev/null
@@ -0,0 +1,59 @@
+#ifndef H_HEADER
+#define H_HEADER
+
+#include <stdio.h>
+
+struct oldrpmFileInfo {
+    char * path;
+    int state;
+    unsigned short mode;
+    unsigned short uid;
+    unsigned short gid;
+    unsigned short rdev;
+    unsigned long size;
+    unsigned long mtime;
+    char md5[32];
+    char * linkto;
+    int isconf;
+    int isdoc;
+} ;
+
+void oldrpmfileFromSpecLine(char * str, struct oldrpmFileInfo * fi);
+void oldrpmfileFromInfoLine(char * path, char * state, char * str, 
+                       struct oldrpmFileInfo * fi);
+void oldrpmfileFree(struct oldrpmFileInfo * fi);
+char * oldrpmfileToInfoStr(struct oldrpmFileInfo * fi);
+
+struct oldrpmHeader {
+    unsigned short type, cpu;
+    unsigned int size;
+    unsigned int os;
+    unsigned int iconLength;
+
+    char * name, * version, * release, * group;
+    char * icon;
+
+    unsigned int specLength;
+    char * spec;
+} ;
+
+struct oldrpmHeaderSpec {
+    char * description;
+    char * vendor;
+    char * distribution;
+    char * buildHost;
+    char * copyright;
+
+    int buildTime;
+
+    int fileCount;
+    struct oldrpmFileInfo * files;
+} ;
+
+char * oldhdrReadFromStream(int fd, struct oldrpmHeader * header);
+char * oldhdrReadFromFile(char * filename, struct oldrpmHeader * header);
+char * oldhdrParseSpec(struct oldrpmHeader * header, struct oldrpmHeaderSpec * spec);
+void   oldhdrFree(struct oldrpmHeader * header);
+void   oldhdrSpecFree(struct oldrpmHeaderSpec * spec);
+
+#endif