diff --git a/Makefile b/Makefile index e69de29..c116f75 100644 --- a/Makefile +++ b/Makefile @@ -0,0 +1,14 @@ +all: slabpkg.pkg + +dist/slabpkg: slabpkg.c + $(CC) -o $@ $^ + +slabpkg.pkg: slabpkg.pkb dist/slabpkg + dist/slabpkg build slabpkg.pkb + +testroot/slabpkg: dist/slabpkg slabpkg.pkg testroot/README.md + dist/slabpkg --root ./testroot install slabpkg.pkg + +test: dist/slabpkg testroot/slabpkg + dist/slabpkg sum $^ + testroot/slabpkg sum $^ diff --git a/slabpkg.c b/slabpkg.c index 0265b80..3dd2351 100644 --- a/slabpkg.c +++ b/slabpkg.c @@ -6,6 +6,9 @@ #ifndef PKG_MKDIR_SIMPLE #define PKG_MKDIR_LINUX #endif +#ifndef PKG_CHMOD_SIMPLE +#define PKG_CHMOD_LINUX +#endif // For reliable integer sizing #include @@ -25,6 +28,15 @@ int mkdir(const char* dirname); #error Either (-D) PKG_MKDIR_LINUX or PKG_MKDIR_SIMPLE must be defined #endif #endif +// For chmod +#ifdef PKG_CHMOD_LINUX +#include +#else +#ifdef PKG_CHMOD_NONE +#else +#error Either (-D) PKG_CHMOD_LINUX or PKG_CHMOD_SIMPLE must be defined +#endif +#endif // The compressed buffer needs to be a bit over twice size the regular // buffer to account for worst case scenario. @@ -38,6 +50,7 @@ int mkdir(const char* dirname); #define PKG_JOBTYPE_COMPRESS 5 #define PKG_JOBTYPE_DECOMPRESS 6 +#define PKG_FLAGS_TYPEMASK 0xF00 #define PKG_FLAGS_DIRECTORY 0x100 #define PKG_FLAGS_EXECUTABLE 0x200 #define PKG_FLAGS_PROVIDES 0x300 @@ -110,7 +123,7 @@ char pkg_comprbuffer[PKG_COMPRBUFSIZE]; int pkg_mkdir(const char* path) { #ifdef PKG_MKDIR_LINUX - return mkdir(path, 0775); + return mkdir(path, 0755); // NOTE: Was previously using 0775, figured more secure by default is better? #endif #ifdef PKG_MKDIR_SIMPLE return mkdir(path); @@ -121,6 +134,23 @@ int pkg_remove(const char* path, int isdir) { return unlink(path); } +int pkg_chmod_default(const char* path) { +#ifdef PKG_CHMOD_LINUX + return chmod(path, 0644); +#else + return 0; +#endif +} + +int pkg_chmod_executable(const char* path) { +#ifdef PKG_CHMOD_LINUX + return chmod(path, 0755); +#else + fprintf(stderr, "NOTE: Ignoring executable bit for '%s'\n", path); + return 0; +#endif +} + int pkg_versionmeta_alldigits(pkg_versionmeta_t* m) { const char* s = m->value; while (*s) { @@ -516,6 +546,7 @@ int pkg_sum_init(pkg_sum_t* sum, char* filename, int dupfilename) { if (sum == NULL) { return -1; } + sum->flags = 0; sum->cmprsize = 0; sum->extrsize = 0; sum->checksum64 = 0x811C9DC5BADC0DE5ULL; @@ -846,10 +877,14 @@ int pkg_archive_extractcontents(pkg_archive_t* archive, FILE* input, const char* while (filehdr != NULL) { char* outputname = pkg_ezstrcat(installroot, filehdr->name); // Note, this assumes one or the other includes a path separator - if (filehdr->flags & PKG_FLAGS_DIRECTORY) { + int t = filehdr->flags & PKG_FLAGS_TYPEMASK; + + if (t == PKG_FLAGS_DIRECTORY) { fprintf(stderr, "Creating directory '%s'...\n", outputname); int mkdirresult = pkg_mkdir(outputname); fprintf(stderr, "mkdir of '%s' returned %d\n", outputname, mkdirresult); + } else if (t == PKG_FLAGS_PROVIDES || t == PKG_FLAGS_REQUIRES || t == PKG_FLAGS_SUGGESTS || t == PKG_FLAGS_CONFLICTS) { + fprintf(stderr, "Ignoring metadata line '%s'...\n", filehdr->name); } else { fprintf(stderr, "Creating file '%s'...\n", outputname); FILE* f = fopen(outputname, "w"); @@ -892,6 +927,12 @@ int pkg_archive_extractcontents(pkg_archive_t* archive, FILE* input, const char* fprintf(stderr, "VERIFICATION ERROR: File data checksums for '%s' don't match. Recorded checksum 0x%X, calculated checksum 0x%X!\n", filehdr->name, filehdr->checksum32, datasum.checksum32); return -1; } + + if (t == PKG_FLAGS_EXECUTABLE) { + pkg_chmod_executable(outputname); + } else { + pkg_chmod_default(outputname); + } } filehdr = filehdr->next; @@ -1054,7 +1095,7 @@ int pkg_job_build(pkg_job_t* job, char* name) { outname[strlen(outname)-1] = 'g'; // "*.pkb"-> "*.pkg" char* shortname = strndup(name + sepi, n - (sepi + 4)); // Trim directory path and filename extension - printf("TODO build '%s' source dirname '%s' dist dirname '%s' output name '%s' shortname '%s'...\n", name, srcd, distd, outname, shortname); + //printf("TODO build '%s' source dirname '%s' dist dirname '%s' output name '%s' shortname '%s'...\n", name, srcd, distd, outname, shortname); FILE* buildf = fopen(name, "rb"); @@ -1754,7 +1795,11 @@ int main(int argc, char** argv) { if (argi >= argc) { return usage(argc, argv, argi, "Expected a directory name following the --root option."); } - job.installroot = strdup(argv[argi]); + if (strlen(argv[argi]) == 0 || (argv[argi][strlen(argv[argi])-1] != '/' && argv[argi][strlen(argv[argi])-1] != '\\')) { + job.installroot = pkg_ezstrcat(argv[argi], "/"); + } else { + job.installroot = strdup(argv[argi]); + } argi++; } else if (!strcmp(argv[argi], "--dbroot")) { argi++; @@ -1840,4 +1885,4 @@ int main(int argc, char** argv) { } else { return usage(argc, argv, argi, "Unrecognised command"); } -} \ No newline at end of file +}