Compare commits

..

No commits in common. "main" and "0.0.1" have entirely different histories.
main ... 0.0.1

7 changed files with 14 additions and 118 deletions

View File

@ -1,27 +0,0 @@
# Formats
The `slpkg` tool uses custom formats rather than zip/tar/gz and so on.
## Why New Formats?
The reasoning behind this is very simple: zip and tar are complex formats with different extensions & cross-platform concerns, whereas the package manager just needs to do the basic job of packaging & installing software files (NOT modifying archives one file at a time, NOT backwards compatibility with old archives etc.).
So it's much easier to implement formats for that purpose than using legacy zip or tar formats then having to add modern extensions as well as packaging metadata on top, but this also allows tight control over things like data integrity so hopefully the package manager also gives better feedback when things do break.
## .pkb files
These are human-edited text files listing package contents and other metadata needed to build a package file.
## .pkg files
These are binary files consisting of an archive header, a number of (file-like or metadata) entry headers, a string section and then a series of file contents.
Each part of a `.pkg` file is checksummed individually, allowing archivers years down the track to monitor any bitrot in old packages in a fine-grained way.
## .pkh files
These are the same format as their corresponding `.pkg` except only need to contain the headers & strings to index installed data.
## .cv1 files
These are compressed files in an early version compression format.

View File

@ -1,14 +0,0 @@
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 $^

View File

@ -1,22 +1,14 @@
# slabpkg # slpkg
SecureLang™ Application Binary Package Manager SecureLang™ Package Manager
## Features ## Features
* Builds/installs/removes software packages * build/install/remove software packages
* Keeps a simple database of installed packages/files * keeps a simple database of installed packages/files
* Compresses/decompresses individual files * compress/decompress individual files
* Uses custom formats (no zip/tar) * custom formats (no zip/tar)
* Built-in integrity checking * simple & portable codebase
* Very simple & portable codebase, plain C
## Limitations
* Doesn't handle advanced features or system integration yet, only "lowest common denominator" feature set
* No timestamps, minimal handling of permissions
* Not OS-aware, doesn't check system compatibility or have a way of organising packages for different targets yet
* Early version, so small changes to the format are to be expected
## TODO ## TODO

5
dist/README.md vendored
View File

@ -1,5 +0,0 @@
# The dist Directory
This directory is used within a project source directory to collect files for packaging with `slabpkg`. This generally means the compiled program files and any other installable program data are placed in a `dist` directory.
This file isn't packaged but exists in the source distribution for the purposes of documentation and so that the `dist` subdirectory isn't deleted when there are no built files.

View File

@ -1,2 +0,0 @@
provides slabpkg 0.0.2
executable /slabpkg

View File

@ -6,9 +6,6 @@
#ifndef PKG_MKDIR_SIMPLE #ifndef PKG_MKDIR_SIMPLE
#define PKG_MKDIR_LINUX #define PKG_MKDIR_LINUX
#endif #endif
#ifndef PKG_CHMOD_SIMPLE
#define PKG_CHMOD_LINUX
#endif
// For reliable integer sizing // For reliable integer sizing
#include <stdint.h> #include <stdint.h>
@ -28,15 +25,6 @@ int mkdir(const char* dirname);
#error Either (-D) PKG_MKDIR_LINUX or PKG_MKDIR_SIMPLE must be defined #error Either (-D) PKG_MKDIR_LINUX or PKG_MKDIR_SIMPLE must be defined
#endif #endif
#endif #endif
// For chmod
#ifdef PKG_CHMOD_LINUX
#include <sys/stat.h>
#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 // The compressed buffer needs to be a bit over twice size the regular
// buffer to account for worst case scenario. // buffer to account for worst case scenario.
@ -50,7 +38,6 @@ int mkdir(const char* dirname);
#define PKG_JOBTYPE_COMPRESS 5 #define PKG_JOBTYPE_COMPRESS 5
#define PKG_JOBTYPE_DECOMPRESS 6 #define PKG_JOBTYPE_DECOMPRESS 6
#define PKG_FLAGS_TYPEMASK 0xF00
#define PKG_FLAGS_DIRECTORY 0x100 #define PKG_FLAGS_DIRECTORY 0x100
#define PKG_FLAGS_EXECUTABLE 0x200 #define PKG_FLAGS_EXECUTABLE 0x200
#define PKG_FLAGS_PROVIDES 0x300 #define PKG_FLAGS_PROVIDES 0x300
@ -123,7 +110,7 @@ char pkg_comprbuffer[PKG_COMPRBUFSIZE];
int pkg_mkdir(const char* path) { int pkg_mkdir(const char* path) {
#ifdef PKG_MKDIR_LINUX #ifdef PKG_MKDIR_LINUX
return mkdir(path, 0755); // NOTE: Was previously using 0775, figured more secure by default is better? return mkdir(path, 0775);
#endif #endif
#ifdef PKG_MKDIR_SIMPLE #ifdef PKG_MKDIR_SIMPLE
return mkdir(path); return mkdir(path);
@ -134,23 +121,6 @@ int pkg_remove(const char* path, int isdir) {
return unlink(path); 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) { int pkg_versionmeta_alldigits(pkg_versionmeta_t* m) {
const char* s = m->value; const char* s = m->value;
while (*s) { while (*s) {
@ -546,7 +516,6 @@ int pkg_sum_init(pkg_sum_t* sum, char* filename, int dupfilename) {
if (sum == NULL) { if (sum == NULL) {
return -1; return -1;
} }
sum->flags = 0;
sum->cmprsize = 0; sum->cmprsize = 0;
sum->extrsize = 0; sum->extrsize = 0;
sum->checksum64 = 0x811C9DC5BADC0DE5ULL; sum->checksum64 = 0x811C9DC5BADC0DE5ULL;
@ -877,14 +846,10 @@ int pkg_archive_extractcontents(pkg_archive_t* archive, FILE* input, const char*
while (filehdr != NULL) { while (filehdr != NULL) {
char* outputname = pkg_ezstrcat(installroot, filehdr->name); // Note, this assumes one or the other includes a path separator char* outputname = pkg_ezstrcat(installroot, filehdr->name); // Note, this assumes one or the other includes a path separator
int t = filehdr->flags & PKG_FLAGS_TYPEMASK; if (filehdr->flags & PKG_FLAGS_DIRECTORY) {
if (t == PKG_FLAGS_DIRECTORY) {
fprintf(stderr, "Creating directory '%s'...\n", outputname); fprintf(stderr, "Creating directory '%s'...\n", outputname);
int mkdirresult = pkg_mkdir(outputname); int mkdirresult = pkg_mkdir(outputname);
fprintf(stderr, "mkdir of '%s' returned %d\n", outputname, mkdirresult); 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 { } else {
fprintf(stderr, "Creating file '%s'...\n", outputname); fprintf(stderr, "Creating file '%s'...\n", outputname);
FILE* f = fopen(outputname, "w"); FILE* f = fopen(outputname, "w");
@ -927,12 +892,6 @@ 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); 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; return -1;
} }
if (t == PKG_FLAGS_EXECUTABLE) {
pkg_chmod_executable(outputname);
} else {
pkg_chmod_default(outputname);
}
} }
filehdr = filehdr->next; filehdr = filehdr->next;
@ -1095,7 +1054,7 @@ int pkg_job_build(pkg_job_t* job, char* name) {
outname[strlen(outname)-1] = 'g'; // "*.pkb"-> "*.pkg" outname[strlen(outname)-1] = 'g'; // "*.pkb"-> "*.pkg"
char* shortname = strndup(name + sepi, n - (sepi + 4)); // Trim directory path and filename extension 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"); FILE* buildf = fopen(name, "rb");
@ -1761,7 +1720,7 @@ int usage(int argc, char** argv, int argi, char* error) {
formatinfo(out); formatinfo(out);
fprintf(out, "DEMO INSTRUCTIONS:\n\n"); fprintf(out, "DEMO INSTRUCTIONS:\n\n");
fprintf(out, " 1. compile slabpkg.c\n 2. place the executable in a subdirectory named `dist`\n 3. create a file `slabpkg.pkb` with a line `/slabpkg` (executable path within `dist`)\n 4. run `./dist/slabpkg build slabpkg.pkb`\n 5. work out how to install it (try --root ... install)\n\n"); fprintf(out, " 1. compile pkg.c\n 2. place the executable in a subdirectory named `dist`\n 3. create a file `pkg.pkb` with a line `/pkg` (executable path within `dist`)\n 4. run `./dist/pkg build pkg.pkb`\n 5. work out how to install it (try --root ... install)\n\n");
if (error) { if (error) {
fprintf(out, "ERROR:\n %s\n", error); fprintf(out, "ERROR:\n %s\n", error);
@ -1774,7 +1733,7 @@ int usage(int argc, char** argv, int argi, char* error) {
int main(int argc, char** argv) { int main(int argc, char** argv) {
pkg_job_t job; pkg_job_t job;
int argi = 1; int argi = 1;
printf("SecureLang Application Binary Package Manager 0.0.2\nThis currently doesn't include proper versioning or dependencies.\n"); printf("SecureLang Package Manager 0.0.1\nThis currently doesn't include proper versioning or dependencies.\n");
if (argc < 2) { if (argc < 2) {
return usage(argc, argv, argi, "Expected command (build, install, ...)"); return usage(argc, argv, argi, "Expected command (build, install, ...)");
@ -1795,11 +1754,7 @@ int main(int argc, char** argv) {
if (argi >= argc) { if (argi >= argc) {
return usage(argc, argv, argi, "Expected a directory name following the --root option."); return usage(argc, argv, argi, "Expected a directory name following the --root option.");
} }
if (strlen(argv[argi]) == 0 || (argv[argi][strlen(argv[argi])-1] != '/' && argv[argi][strlen(argv[argi])-1] != '\\')) { job.installroot = strdup(argv[argi]);
job.installroot = pkg_ezstrcat(argv[argi], "/");
} else {
job.installroot = strdup(argv[argi]);
}
argi++; argi++;
} else if (!strcmp(argv[argi], "--dbroot")) { } else if (!strcmp(argv[argi], "--dbroot")) {
argi++; argi++;
@ -1885,4 +1840,4 @@ int main(int argc, char** argv) {
} else { } else {
return usage(argc, argv, argi, "Unrecognised command"); return usage(argc, argv, argi, "Unrecognised command");
} }
} }

View File

@ -1,3 +0,0 @@
# The testroot Directory
This directory only exists for testing `slabpkg` installing itself, and this file only exists so that the directory isn't deleted from the source directory.