Initial revision
CVS patchset: 149 CVS date: 1996/01/06 18:54:50
This commit is contained in:
parent
02dfd12a92
commit
405a63ffff
|
@ -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;
|
||||
}
|
|
@ -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
|
Loading…
Reference in New Issue