From dc25a788d874d9ee95738b9fa56d2a06f6a31141 Mon Sep 17 00:00:00 2001 From: Patrick McDermott Date: Sun, 30 Apr 2023 03:44:20 -0400 Subject: opk/write: Build mode (WIP) --- (limited to 'src/opk/write.c') diff --git a/src/opk/write.c b/src/opk/write.c new file mode 100644 index 0000000..12a36c6 --- /dev/null +++ b/src/opk/write.c @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2023 Patrick McDermott + * + * This file is part of opkg-opkg. + * + * opkg-opkg is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opkg-opkg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opkg-opkg. If not, see . + */ + +#include +#include +#include +#include +#include "../defs.h" +#include "../dirent.h" +#include "../gzip.h" +#include "../i18n.h" +#include "../opk.h" +#include "../ustar.h" +#include "opk.h" + +static int +_opkg_opk_opk_write_file(void *user_data, size_t size) +{ + struct opkg_opk_opk *opk = user_data; + + if (fwrite(opk->file_buffer, 1, sizeof(opk->file_buffer), opk->file) == + size) { + return OPKG_OPK_OK; + } else { + return OPKG_OPK_ERROR; + } +} + +int +opkg_opk_opk_write(struct opkg_opk_opk *opk, const char *file_name) +{ + int ret; + struct opkg_opk_dirent dirent; + char *buffer; + size_t size; + + ret = OPKG_OPK_OK; + + /* Open outer archive. */ + opk->file = fopen(file_name, "wb"); + if (opk->file == NULL) { + fprintf(stderr, _("Error: Failed to open file \"%s\"\n"), + file_name); + ret = OPKG_OPK_ERROR; + goto out0; + } + + /* Initialize outer gzip decompressor. */ + opk->outer_gzip = opkg_opk_gzip_init_write(&_opkg_opk_opk_write_file, + opk); + if (opk->outer_gzip == NULL) { + fputs(_("Error: Failed to initialize\n"), stderr); + ret = OPKG_OPK_ERROR; + goto out1; + } + opkg_opk_gzip_set_write_buffer(opk->outer_gzip, opk->file_buffer, + sizeof(opk->file_buffer)); + + /* Initialize outer ustar unarchiver. */ + opk->outer_ustar = opkg_opk_ustar_init(opk->outer_gzip); + if (opk->outer_ustar == NULL) { + fputs(_("Error: Failed to initialize\n"), stderr); + ret = OPKG_OPK_ERROR; + goto out2; + } + + /* Write version file. */ + dirent.name = "debian-binary"; + dirent.parent = NULL; + if (opkg_opk_ustar_write_header(opk->outer_ustar, &dirent, 0644, + 0, getpwuid(0)->pw_name, + 0, getgrgid(0)->gr_name, + 4, '-', NULL) != OPKG_OPK_OK) { + fputs(_("Error: Failed to write header\n"), stderr); + ret = OPKG_OPK_ERROR; + goto out3; + } + opkg_opk_ustar_get_buffer(opk->outer_ustar, &buffer, &size); + memcpy(buffer, "2.0\n", 4); + if (opkg_opk_ustar_write_data(opk->outer_ustar, 4) != OPKG_OPK_OK) { + fputs(_("Error: Failed to write data\n"), stderr); + ret = OPKG_OPK_ERROR; + goto out3; + } + + /* TODO: control.tar.gz and data.tar.gz */ + + /* Write trailer. */ + if (opkg_opk_ustar_write_trailer(opk->outer_ustar) != OPKG_OPK_OK) { + fputs(_("Error: Failed to write trailer\n"), stderr); + ret = OPKG_OPK_ERROR; + goto out3; + } + + out3: + opkg_opk_ustar_free(opk->outer_ustar); + out2: + opkg_opk_gzip_free(opk->outer_gzip); + out1: + fclose(opk->file); + out0: + return ret; +} -- cgit v0.9.1