├── tests ├── regress │ ├── cfg.py │ ├── Makefile │ ├── issue55.py │ ├── issue31.py │ ├── issue58.py │ ├── issue45.py │ ├── issue26.py │ ├── filehash.py │ ├── issue46.py │ ├── issue50.py │ ├── opkgcl.py │ ├── issue72.py │ ├── issue51.py │ └── opk.py ├── CMakeLists.txt ├── opkg_extract_test.c ├── opkg_hash_test.c ├── opkg_active_list_test.c └── libopkg_test.c ├── intercept ├── ldconfig ├── update-modules └── depmod ├── AUTHORS ├── libbb ├── CMakeLists.txt ├── xreadlink.c ├── wfopen.c ├── safe_strncpy.c ├── last_char_is.c ├── gzip.h ├── concat_path_file.c ├── time_string.c ├── copy_file_chunk.c ├── all_read.c ├── mode_string.c ├── xfuncs.c ├── make_directory.c ├── parse_mode.c ├── libbb.h ├── gz_open.c ├── gzip.c └── copy_file.c ├── src └── CMakeLists.txt ├── libopkg ├── CMakeLists.txt ├── pkg_alternatives.h ├── sprintf_alloc.h ├── opkg_configure.h ├── opkg_upgrade.h ├── opkg_utils.h ├── opkg_install.h ├── xregex.h ├── nv_pair.h ├── pkg_src.h ├── conffile.h ├── opkg_remove.h ├── pkg_src.c ├── nv_pair.c ├── conffile_list.c ├── xsystem.h ├── conffile_list.h ├── parse_util.h ├── pkg_dest.h ├── pkg_extract.h ├── opkg_cmd.h ├── opkg_download.h ├── opkg_defines.h ├── pkg_dest_list.h ├── xregex.c ├── sprintf_alloc.c ├── file_util.h ├── opkg_configure.c ├── pkg_src_list.h ├── str_list.h ├── active_list.h ├── opkg_message.h ├── nv_pair_list.h ├── pkg_src_list.c ├── hash_table.h ├── conffile.c ├── opkg_utils.c ├── xsystem.c ├── pkg_dest_list.c ├── pkg_parse.h ├── pkg_vec.h ├── void_list.h ├── opkg.h ├── pkg_dest.c ├── pkg_hash.h ├── nv_pair_list.c ├── str_list.c ├── pkg_extract.c ├── opkg_message.c ├── pkg_depends.h ├── opkg_conf.h ├── sha256.h ├── active_list.c ├── opkg_upgrade.c ├── parse_util.c ├── void_list.c ├── pkg_alternatives.c ├── hash_table.c ├── pkg_vec.c └── pkg.h ├── CONTRIBUTORS ├── .gitignore ├── CMakeLists.txt └── utils ├── opkg-key └── update-alternatives.in /tests/regress/cfg.py: -------------------------------------------------------------------------------- 1 | opkdir = "/tmp/opk" 2 | offline_root = "/tmp/opkg" 3 | opkgcl = "/home/grg/opkg/code/svn/src/opkg-cl" 4 | -------------------------------------------------------------------------------- /intercept/ldconfig: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -f $OPKG_INTERCEPT_DIR/ldconfig ]; then 4 | echo "ldconfig" > $OPKG_INTERCEPT_DIR/ldconfig 5 | chmod +x $OPKG_INTERCEPT_DIR/ldconfig 6 | fi 7 | 8 | -------------------------------------------------------------------------------- /intercept/update-modules: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ ! -f $OPKG_INTERCEPT_DIR/update-modules ]; then 4 | echo "update-modules" > $OPKG_INTERCEPT_DIR/update-modules 5 | chmod +x $OPKG_INTERCEPT_DIR/update-modules 6 | fi 7 | 8 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Opkg: 2 | * Thomas Wood 3 | * Tick Chen 4 | * Graham Gower 5 | Ipkg: 6 | * Pierluigi Frullani 7 | * Carl Worth 8 | * Steve Ayer 9 | -------------------------------------------------------------------------------- /libbb/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | PROJECT(libbb C) 4 | 5 | ADD_LIBRARY(bb STATIC 6 | all_read.c concat_path_file.c copy_file.c copy_file_chunk.c gzip.c 7 | gz_open.c last_char_is.c make_directory.c mode_string.c parse_mode.c 8 | safe_strncpy.c time_string.c unarchive.c unzip.c wfopen.c xfuncs.c 9 | xreadlink.c 10 | ) 11 | -------------------------------------------------------------------------------- /tests/regress/Makefile: -------------------------------------------------------------------------------- 1 | PYTHON=/usr/bin/python3 2 | REGRESSION_TESTS=issue26.py issue31.py issue45.py issue46.py \ 3 | issue50.py issue51.py issue55.py issue58.py \ 4 | issue72.py \ 5 | filehash.py 6 | 7 | regress: 8 | @for test in $(REGRESSION_TESTS); do \ 9 | echo $$test; \ 10 | $(PYTHON) $$test; \ 11 | done 12 | 13 | clean: 14 | rm -f *.pyc 15 | -------------------------------------------------------------------------------- /intercept/depmod: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | if [ "x$1" = "x-a" ] || [ "x$1" = "x-A" ]; then 4 | echo "depmod $@" >> $OPKG_INTERCEPT_DIR/depmod 5 | sort -u $OPKG_INTERCEPT_DIR/depmod > $OPKG_INTERCEPT_DIR/depmod.tmp 6 | mv $OPKG_INTERCEPT_DIR/depmod.tmp $OPKG_INTERCEPT_DIR/depmod 7 | chmod +x $OPKG_INTERCEPT_DIR/depmod 8 | exit 0 9 | fi 10 | 11 | /sbin/depmod $* 12 | 13 | -------------------------------------------------------------------------------- /tests/regress/issue55.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | long_filename = 110*"a" 9 | 10 | os.symlink(long_filename, "linky") 11 | a = opk.Opk(Package="a", Version="1.0", Architecture="all") 12 | a.write(data_files=["linky"]) 13 | os.unlink("linky") 14 | opkgcl.install("a_1.0_all.opk") 15 | 16 | if not opkgcl.is_installed("a"): 17 | print(__file__, ": Package 'a' not installed.") 18 | exit(False) 19 | 20 | if not os.path.lexists("{}/linky".format(cfg.offline_root)): 21 | print(__file__, ": symlink to file with a name longer than 100 " 22 | "characters not created.") 23 | exit(False) 24 | 25 | opkgcl.remove("a") 26 | -------------------------------------------------------------------------------- /tests/regress/issue31.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | o = opk.OpkGroup() 9 | o.add(Package="a", Version="1.0", Architecture="all", Depends="b") 10 | o.add(Package="b", Version="1.0", Architecture="all", Depends="c") 11 | o.write_opk() 12 | o.write_list() 13 | 14 | opkgcl.update() 15 | 16 | opkgcl.install("a") 17 | if opkgcl.is_installed("a"): 18 | print(__file__, ": Package 'a' installed, despite dependency " 19 | "upon a package with an unresolved dependency.") 20 | exit(False) 21 | 22 | if opkgcl.is_installed("b"): 23 | print(__file__, ": Package 'b' installed, " 24 | "despite unresolved dependency.") 25 | exit(False) 26 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | PROJECT(opkg-cl C) 4 | 5 | INCLUDE(CheckLibraryExists) 6 | 7 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libopkg) 8 | LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libopkg ${CMAKE_CURRENT_SOURCE_DIR}/../libbb) 9 | 10 | IF(STATIC_UBOX) 11 | FIND_LIBRARY(ubox NAMES libubox.a) 12 | ELSE() 13 | FIND_LIBRARY(ubox NAMES ubox) 14 | ENDIF() 15 | 16 | ADD_EXECUTABLE(opkg-cl opkg-cl.c) 17 | TARGET_LINK_LIBRARIES(opkg-cl opkg bb ${ubox}) 18 | 19 | CHECK_LIBRARY_EXISTS(pthread pthread_create "" NEED_PTHREAD) 20 | IF(NEED_PTHREAD) 21 | TARGET_LINK_LIBRARIES(opkg-cl pthread) 22 | ENDIF() 23 | 24 | INSTALL(TARGETS opkg-cl RUNTIME DESTINATION bin) 25 | -------------------------------------------------------------------------------- /libopkg/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | PROJECT(libopkg C) 4 | 5 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR};${CMAKE_CURRENT_SOURCE_DIR}/..) 6 | LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libbb) 7 | 8 | ADD_LIBRARY(opkg STATIC 9 | active_list.c conffile.c conffile_list.c file_util.c hash_table.c 10 | nv_pair.c nv_pair_list.c opkg.c opkg_cmd.c opkg_conf.c opkg_configure.c 11 | opkg_download.c opkg_install.c opkg_message.c opkg_remove.c 12 | opkg_upgrade.c opkg_utils.c parse_util.c pkg.c pkg_alternatives.c pkg_depends.c pkg_dest.c 13 | pkg_dest_list.c pkg_extract.c pkg_hash.c pkg_parse.c pkg_src.c 14 | pkg_src_list.c pkg_vec.c sha256.c sprintf_alloc.c str_list.c 15 | void_list.c xregex.c xsystem.c 16 | ) 17 | -------------------------------------------------------------------------------- /libopkg/pkg_alternatives.h: -------------------------------------------------------------------------------- 1 | /* pkg_alternatives.c - the opkg package management system 2 | 3 | Copyright (C) 2017 Yousong Zhou 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License as 7 | published by the Free Software Foundation; either version 2, or (at 8 | your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, but 11 | WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | General Public License for more details. 14 | */ 15 | 16 | #ifndef OPKG_ALTERNATIVES_H 17 | #define OPKG_ALTERNATIVES_H 18 | 19 | #include "pkg.h" 20 | 21 | int pkg_alternatives_update(pkg_t * pkg); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /libopkg/sprintf_alloc.h: -------------------------------------------------------------------------------- 1 | /* sprintf_alloca.c -- like sprintf with memory allocation 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2, or (at your option) 10 | any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | */ 17 | 18 | #ifndef SPRINTF_ALLOC_H 19 | #define SPRINTF_ALLOC_H 20 | 21 | void sprintf_alloc(char **str, const char *fmt, ...); 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /tests/regress/issue58.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | o = opk.OpkGroup() 9 | o.add(Package="a", Version="1.0", Architecture="all", Recommends="b") 10 | o.add(Package="b", Version="1.0", Architecture="all") 11 | o.add(Package="c", Version="1.0", Architecture="all", Recommends="b") 12 | o.write_opk() 13 | o.write_list() 14 | 15 | opkgcl.update() 16 | 17 | opkgcl.install("a") 18 | opkgcl.install("c") 19 | 20 | opkgcl.remove("a", "--autoremove") 21 | if not opkgcl.is_installed("b"): 22 | print(__file__, ": Pacakge 'b' orphaned despite remaining " 23 | "recommending package 'c'.") 24 | exit(False) 25 | 26 | opkgcl.remove("c", "--autoremove") 27 | if opkgcl.is_installed("b"): 28 | print(__file__, ": Recommended package 'b' not autoremoved.") 29 | exit(False) 30 | 31 | 32 | -------------------------------------------------------------------------------- /libopkg/opkg_configure.h: -------------------------------------------------------------------------------- 1 | /* opkg_configure.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_CONFIGURE_H 19 | #define OPKG_CONFIGURE_H 20 | 21 | #include "pkg.h" 22 | 23 | int opkg_configure(pkg_t * pkg); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /tests/regress/issue45.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | o = opk.OpkGroup() 9 | o.add(Package="a", Version="1.0", Architecture="all", Depends="b") 10 | o.add(Package="b", Version="1.0", Architecture="all") 11 | o.write_opk() 12 | o.write_list() 13 | 14 | opkgcl.update() 15 | 16 | (status, output) = opkgcl.opkgcl("install a") 17 | ln_a = output.find("Configuring a") 18 | ln_b = output.find("Configuring b") 19 | 20 | if ln_a == -1: 21 | print(__file__, ": Didn't see package 'a' get configured.") 22 | exit(False) 23 | 24 | if ln_b == -1: 25 | print(__file__, ": Didn't see package 'b' get configured.") 26 | exit(False) 27 | 28 | if ln_a < ln_b: 29 | print(__file__, ": Packages 'a' and 'b' configured in wrong order.") 30 | exit(False) 31 | 32 | opkgcl.remove("a") 33 | opkgcl.remove("b") 34 | -------------------------------------------------------------------------------- /libopkg/opkg_upgrade.h: -------------------------------------------------------------------------------- 1 | /* opkg_upgrade.c - the opkg package management system 2 | 3 | Copyright (C) 2003 Daniele Nicolodi 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License as 7 | published by the Free Software Foundation; either version 2, or (at 8 | your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, but 11 | WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | General Public License for more details. 14 | */ 15 | #ifndef OPKG_UPGRADE_H 16 | #define OPKG_UPGRADE_H 17 | 18 | #include "active_list.h" 19 | int opkg_upgrade_pkg(pkg_t * old); 20 | struct active_list *prepare_upgrade_list(void); 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /libbb/xreadlink.c: -------------------------------------------------------------------------------- 1 | /* 2 | * xreadlink.c - safe implementation of readlink. 3 | * Returns a NULL on failure... 4 | */ 5 | 6 | #include 7 | 8 | /* 9 | * NOTE: This function returns a malloced char* that you will have to free 10 | * yourself. You have been warned. 11 | */ 12 | 13 | #include 14 | #include "libbb.h" 15 | 16 | extern char *xreadlink(const char *path) 17 | { 18 | static const int GROWBY = 80; /* how large we will grow strings by */ 19 | 20 | char *buf = NULL; 21 | int bufsize = 0, readsize = 0; 22 | 23 | do { 24 | buf = xrealloc(buf, bufsize += GROWBY); 25 | readsize = readlink(path, buf, bufsize); /* 1st try */ 26 | if (readsize == -1) { 27 | perror_msg("%s", path); 28 | free(buf); 29 | return NULL; 30 | } 31 | } 32 | while (bufsize < readsize + 1); 33 | 34 | buf[readsize] = '\0'; 35 | 36 | return buf; 37 | } 38 | -------------------------------------------------------------------------------- /libopkg/opkg_utils.h: -------------------------------------------------------------------------------- 1 | /* opkg_utils.h - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_UTILS_H 19 | #define OPKG_UTILS_H 20 | 21 | unsigned long get_available_kbytes(char *filesystem); 22 | char *trim_xstrdup(const char *line); 23 | int line_is_blank(const char *line); 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /libopkg/opkg_install.h: -------------------------------------------------------------------------------- 1 | /* opkg_install.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_INSTALL_H 19 | #define OPKG_INSTALL_H 20 | 21 | #include "pkg.h" 22 | #include "opkg_conf.h" 23 | 24 | int opkg_install_by_name(const char *pkg_name); 25 | int opkg_install_pkg(pkg_t * pkg, int from_upgrading); 26 | 27 | #endif 28 | -------------------------------------------------------------------------------- /libopkg/xregex.h: -------------------------------------------------------------------------------- 1 | /* xregex.h - regex functions with error messages 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2, or (at your option) 10 | any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | */ 17 | 18 | #ifndef XREGEX_H 19 | #define XREGEX_H 20 | 21 | #include 22 | #include 23 | 24 | int xregcomp(regex_t * preg, const char *regex, int cflags); 25 | static inline void xregfree(regex_t * preg) 26 | { 27 | regfree(preg); 28 | } 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /tests/regress/issue26.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | o = opk.OpkGroup() 9 | o.add(Package="a", Version="2.0", Architecture="all") 10 | o.write_opk() 11 | o.write_list() 12 | 13 | # older version, not in Packages list 14 | a1 = opk.Opk(Package="a", Version="1.0", Architecture="all") 15 | a1.write() 16 | 17 | opkgcl.update() 18 | 19 | # install v2 from repository 20 | opkgcl.install("a") 21 | if not opkgcl.is_installed("a", "2.0"): 22 | print(__file__, ": Package 'a_2.0' not installed.") 23 | exit(False) 24 | 25 | opkgcl.install("a_1.0_all.opk", "--force-downgrade") 26 | if not opkgcl.is_installed("a", "1.0"): 27 | print(__file__, ": Package 'a_1.0' not installed (1).") 28 | exit(False) 29 | 30 | opkgcl.install("a_1.0_all.opk", "--force-downgrade") 31 | if not opkgcl.is_installed("a", "1.0"): 32 | print(__file__, ": Package 'a_1.0' not installed (2).") 33 | exit(False) 34 | 35 | opkgcl.remove("a") 36 | -------------------------------------------------------------------------------- /libopkg/nv_pair.h: -------------------------------------------------------------------------------- 1 | /* nv_pair.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef NV_PAIR_H 19 | #define NV_PAIR_H 20 | 21 | typedef struct nv_pair nv_pair_t; 22 | struct nv_pair { 23 | char *name; 24 | char *value; 25 | }; 26 | 27 | int nv_pair_init(nv_pair_t * nv_pair, const char *name, const char *value); 28 | void nv_pair_deinit(nv_pair_t * nv_pair); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.6) 2 | 3 | PROJECT(opkg-tests C) 4 | 5 | INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libopkg ${CMAKE_CURRENT_SOURCE_DIR}/..) 6 | LINK_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR}/../libopkg ${CMAKE_CURRENT_SOURCE_DIR}/../libbb) 7 | 8 | IF(STATIC_UBOX) 9 | FIND_LIBRARY(ubox NAMES libubox.a) 10 | ELSE() 11 | FIND_LIBRARY(ubox NAMES ubox) 12 | ENDIF() 13 | 14 | FIND_LIBRARY(pthread NAMES pthread) 15 | 16 | ADD_EXECUTABLE(libopkg_test libopkg_test.c) 17 | TARGET_LINK_LIBRARIES(libopkg_test bb opkg bb ${ubox} ${pthread}) 18 | 19 | ADD_EXECUTABLE(opkg_active_list_test opkg_active_list_test.c) 20 | TARGET_LINK_LIBRARIES(opkg_active_list_test bb opkg bb ${ubox} ${pthread}) 21 | 22 | ADD_EXECUTABLE(opkg_extract_test opkg_extract_test.c) 23 | TARGET_LINK_LIBRARIES(opkg_extract_test bb opkg bb ${ubox} ${pthread}) 24 | 25 | #ADD_EXECUTABLE(opkg_hash_test opkg_hash_test.c) 26 | #TARGET_LINK_LIBRARIES(opkg_hash_test bb opkg bb ${ubox} ${pthread}) 27 | -------------------------------------------------------------------------------- /libopkg/pkg_src.h: -------------------------------------------------------------------------------- 1 | /* pkg_src.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_SRC_H 19 | #define PKG_SRC_H 20 | 21 | #include "nv_pair.h" 22 | 23 | typedef struct { 24 | char *name; 25 | char *value; 26 | int gzip; 27 | } pkg_src_t; 28 | 29 | int pkg_src_init(pkg_src_t * src, const char *name, const char *base_url, 30 | int gzip); 31 | void pkg_src_deinit(pkg_src_t * src); 32 | 33 | #endif 34 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | === Contributors === 2 | 3 | The following people have submitted changes which have been applied to the 4 | core: 5 | 6 | Christopher Hall 7 | EdorFaus 8 | Graham Gower 9 | Krzysztof Kotlenga : 10 | Per Hansen 11 | Mike Westerhof 12 | Antonio Ospite 13 | Koen Kooi 14 | Claudio Mignanti 15 | Florian Boor 16 | Camille Moncelier 17 | Jim Huang 18 | John L. Chmielewski 19 | 20 | 21 | == We don't have your name / email == 22 | Gilles Doffe 23 | cconroy 24 | chgros 25 | Kosmaty 26 | manitu 27 | pblack88@gmail.com 28 | 29 | and anyone else who has sent patches or bug reports. If your name isn't on this 30 | list, please forgive us and send an email to a maintainer 31 | The project owners/committers is here: http://code.google.com/p/opkg/ 32 | -------------------------------------------------------------------------------- /libopkg/conffile.h: -------------------------------------------------------------------------------- 1 | /* conffile.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef CONFFILE_H 19 | #define CONFFILE_H 20 | 21 | #include "nv_pair.h" 22 | typedef struct nv_pair conffile_t; 23 | 24 | int conffile_init(conffile_t * conffile, const char *file_name, 25 | const char *md5sum); 26 | void conffile_deinit(conffile_t * conffile); 27 | int conffile_has_been_modified(conffile_t * conffile); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /tests/regress/filehash.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | open("asdf", "w").close() 9 | a = opk.Opk(Package="a", Version="1.0", Architecture="all") 10 | a.write(data_files=["asdf"]) 11 | b = opk.Opk(Package="b", Version="1.0", Architecture="all") 12 | b.write(data_files=["asdf"]) 13 | os.unlink("asdf") 14 | opkgcl.install("a_1.0_all.opk") 15 | 16 | if not opkgcl.is_installed("a"): 17 | print(__file__, ": Package 'a' not installed.") 18 | exit(False) 19 | 20 | if not os.path.exists("{}/asdf".format(cfg.offline_root)): 21 | print(__file__, ": asdf not created.") 22 | exit(False) 23 | 24 | opkgcl.install("b_1.0_all.opk", "--force-overwrite") 25 | 26 | if "{}/asdf".format(cfg.offline_root) not in opkgcl.files("b"): 27 | print(__file__, ": asdf not claimed by ``b''.") 28 | exit(False) 29 | 30 | if "{}/asdf".format(cfg.offline_root) in opkgcl.files("a"): 31 | print(__file__, ": asdf is still claimed by ``a''.") 32 | exit(False) 33 | 34 | opkgcl.remove("b") 35 | opkgcl.remove("a") 36 | -------------------------------------------------------------------------------- /libopkg/opkg_remove.h: -------------------------------------------------------------------------------- 1 | /* opkg_remove.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_REMOVE_H 19 | #define OPKG_REMOVE_H 20 | 21 | #include "pkg.h" 22 | #include "opkg_conf.h" 23 | 24 | int opkg_remove_pkg(pkg_t * pkg, int message); 25 | int pkg_has_installed_dependents(pkg_t * pkg, abstract_pkg_t *** pdependents); 26 | void remove_data_files_and_list(pkg_t * pkg); 27 | void remove_maintainer_scripts(pkg_t * pkg); 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /libopkg/pkg_src.c: -------------------------------------------------------------------------------- 1 | /* pkg_src.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "pkg_src.h" 19 | #include "libbb/libbb.h" 20 | 21 | int pkg_src_init(pkg_src_t * src, const char *name, const char *base_url, 22 | int gzip) 23 | { 24 | src->gzip = gzip; 25 | src->name = xstrdup(name); 26 | src->value = xstrdup(base_url); 27 | return 0; 28 | } 29 | 30 | void pkg_src_deinit(pkg_src_t * src) 31 | { 32 | free(src->name); 33 | free(src->value); 34 | } 35 | -------------------------------------------------------------------------------- /libopkg/nv_pair.c: -------------------------------------------------------------------------------- 1 | /* nv_pair.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "nv_pair.h" 19 | #include "libbb/libbb.h" 20 | 21 | int nv_pair_init(nv_pair_t * nv_pair, const char *name, const char *value) 22 | { 23 | 24 | nv_pair->name = xstrdup(name); 25 | nv_pair->value = xstrdup(value); 26 | 27 | return 0; 28 | } 29 | 30 | void nv_pair_deinit(nv_pair_t * nv_pair) 31 | { 32 | free(nv_pair->name); 33 | nv_pair->name = NULL; 34 | 35 | free(nv_pair->value); 36 | nv_pair->value = NULL; 37 | } 38 | -------------------------------------------------------------------------------- /libopkg/conffile_list.c: -------------------------------------------------------------------------------- 1 | /* conffile_list.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "conffile_list.h" 19 | 20 | void conffile_list_init(conffile_list_t * list) 21 | { 22 | nv_pair_list_init(list); 23 | } 24 | 25 | void conffile_list_deinit(conffile_list_t * list) 26 | { 27 | nv_pair_list_deinit(list); 28 | } 29 | 30 | conffile_t *conffile_list_append(conffile_list_t * list, const char *file_name, 31 | const char *md5sum) 32 | { 33 | return nv_pair_list_append(list, file_name, md5sum); 34 | } 35 | -------------------------------------------------------------------------------- /libopkg/xsystem.h: -------------------------------------------------------------------------------- 1 | /* xsystem.h - system(3) with error messages 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef XSYSTEM_H 19 | #define XSYSTEM_H 20 | 21 | /* Like system(3), but with error messages printed if the fork fails 22 | or if the child process dies due to an uncaught signal. Also, the 23 | return value is a bit simpler: 24 | 25 | -1 if there was any problem 26 | Otherwise, the 8-bit return value of the program ala WEXITSTATUS 27 | as defined in . 28 | */ 29 | int xsystem(const char *argv[]); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tests/regress/issue46.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | o = opk.OpkGroup() 9 | o.add(Package="a", Version="1.0", Architecture="all", Recommends="b") 10 | o.add(Package="b", Version="2.0", Architecture="all") 11 | o.write_opk() 12 | o.write_list() 13 | 14 | # prime the status file so 'b' is not installed as a recommendation 15 | status_filename = "{}/usr/lib/opkg/status".format(cfg.offline_root) 16 | f = open(status_filename, "w") 17 | f.write("Package: b\n") 18 | f.write("Version: 1.0\n") 19 | f.write("Architecture: all\n") 20 | f.write("Status: deinstall hold not-installed\n") 21 | f.close() 22 | 23 | opkgcl.update() 24 | 25 | opkgcl.install("a") 26 | if opkgcl.is_installed("b"): 27 | print(__file__, ": Package 'b' installed despite " 28 | "deinstall/hold status.") 29 | exit(False) 30 | 31 | opkgcl.remove("a") 32 | opkgcl.install("a") 33 | if opkgcl.is_installed("b"): 34 | print(__file__, ": Package 'b' installed - deinstall/hold status " 35 | "not retained.") 36 | exit(False) 37 | 38 | opkgcl.remove("a") 39 | open(status_filename, "w").close() 40 | -------------------------------------------------------------------------------- /tests/regress/issue50.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | open("foo", "w").close() 9 | a1 = opk.Opk(Package="a", Version="1.0", Architecture="all") 10 | a1.write(data_files=["foo"]) 11 | 12 | opkgcl.install("a_1.0_all.opk") 13 | 14 | o = opk.OpkGroup() 15 | a2 = opk.Opk(Package="a", Version="2.0", Architecture="all", Depends="b") 16 | a2.write() 17 | b1 = opk.Opk(Package="b", Version="1.0", Architecture="all") 18 | b1.write(data_files=["foo"]) 19 | o.opk_list.append(a2) 20 | o.opk_list.append(b1) 21 | o.write_list() 22 | 23 | os.unlink("foo") 24 | 25 | opkgcl.update() 26 | opkgcl.upgrade() 27 | 28 | if not opkgcl.is_installed("a", "2.0"): 29 | print(__file__, ": Package 'a_2.0' not installed.") 30 | exit(False) 31 | 32 | foo_fullpath = "{}/foo".format(cfg.offline_root) 33 | 34 | if not os.path.exists(foo_fullpath): 35 | print(__file__, ": File 'foo' incorrectly orphaned.") 36 | exit(False) 37 | 38 | if not foo_fullpath in opkgcl.files("b"): 39 | print(__file__, ": Package 'b' does not own file 'foo'.") 40 | exit(False) 41 | 42 | opkgcl.remove("a") 43 | opkgcl.remove("b") 44 | -------------------------------------------------------------------------------- /libopkg/conffile_list.h: -------------------------------------------------------------------------------- 1 | /* conffile_list.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef CONFFILE_LIST_H 19 | #define CONFFILE_LIST_H 20 | 21 | #include "nv_pair_list.h" 22 | 23 | typedef nv_pair_list_elt_t conffile_list_elt_t; 24 | typedef nv_pair_list_t conffile_list_t; 25 | 26 | #include "conffile.h" 27 | 28 | void conffile_list_init(conffile_list_t * list); 29 | void conffile_list_deinit(conffile_list_t * list); 30 | 31 | conffile_t *conffile_list_append(conffile_list_t * list, const char *name, 32 | const char *root_dir); 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /libopkg/parse_util.h: -------------------------------------------------------------------------------- 1 | /* parse_util.h - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PARSE_UTIL_H 19 | #define PARSE_UTIL_H 20 | 21 | int is_field(const char *type, const char *line); 22 | char *parse_simple(const char *type, const char *line); 23 | char **parse_list(const char *raw, unsigned int *count, const char sep, 24 | int skip_field); 25 | 26 | typedef int (*parse_line_t) (void *, char *, uint); 27 | int parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE * fp, 28 | uint mask, char **buf0, size_t buf0len); 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /libopkg/pkg_dest.h: -------------------------------------------------------------------------------- 1 | /* pkg_dest.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_DEST_H 19 | #define PKG_DEST_H 20 | 21 | #include 22 | 23 | typedef struct pkg_dest pkg_dest_t; 24 | struct pkg_dest { 25 | char *name; 26 | char *root_dir; 27 | char *opkg_dir; 28 | char *lists_dir; 29 | char *info_dir; 30 | char *status_file_name; 31 | FILE *status_fp; 32 | }; 33 | 34 | int pkg_dest_init(pkg_dest_t * dest, const char *name, const char *root_dir, 35 | const char *lists_dir); 36 | void pkg_dest_deinit(pkg_dest_t * dest); 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /libopkg/pkg_extract.h: -------------------------------------------------------------------------------- 1 | /* pkg_extract.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_EXTRACT_H 19 | #define PKG_EXTRACT_H 20 | 21 | #include "pkg.h" 22 | 23 | int pkg_extract_control_file_to_stream(pkg_t * pkg, FILE * stream); 24 | int pkg_extract_control_files_to_dir(pkg_t * pkg, const char *dir); 25 | int pkg_extract_control_files_to_dir_with_prefix(pkg_t * pkg, 26 | const char *dir, 27 | const char *prefix); 28 | int pkg_extract_data_files_to_dir(pkg_t * pkg, const char *dir); 29 | int pkg_extract_data_file_names_to_stream(pkg_t * pkg, FILE * file); 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /tests/regress/opkgcl.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os, subprocess 4 | import cfg 5 | 6 | def opkgcl(opkg_args): 7 | cmd = "{} -o {} {}".format(cfg.opkgcl, cfg.offline_root, opkg_args) 8 | #print(cmd) 9 | return subprocess.getstatusoutput(cmd) 10 | 11 | def install(pkg_name, flags=""): 12 | return opkgcl("{} install {}".format(flags, pkg_name))[0] 13 | 14 | def remove(pkg_name, flags=""): 15 | return opkgcl("{} remove {}".format(flags, pkg_name))[0] 16 | 17 | def update(): 18 | return opkgcl("update")[0] 19 | 20 | def upgrade(): 21 | return opkgcl("upgrade")[0] 22 | 23 | def files(pkg_name): 24 | output = opkgcl("files {}".format(pkg_name))[1] 25 | return output.split("\n")[1:] 26 | 27 | 28 | def is_installed(pkg_name, version=None): 29 | out = opkgcl("list_installed {}".format(pkg_name))[1] 30 | if len(out) == 0 or out.split()[0] != pkg_name: 31 | return False 32 | if version and out.split()[2] != version: 33 | return False 34 | if not os.path.exists("{}/usr/lib/opkg/info/{}.control"\ 35 | .format(cfg.offline_root, pkg_name)): 36 | return False 37 | return True 38 | 39 | 40 | if __name__ == '__main__': 41 | import sys 42 | (status, output) = opkgcl(" ".join(sys.argv[1:])) 43 | print(output) 44 | exit(status) 45 | -------------------------------------------------------------------------------- /libopkg/opkg_cmd.h: -------------------------------------------------------------------------------- 1 | /* opkg_cmd.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_CMD_H 19 | #define OPKG_CMD_H 20 | 21 | typedef int (*opkg_cmd_fun_t) (int argc, const char **argv); 22 | 23 | struct opkg_cmd { 24 | const char *name; 25 | int requires_args; 26 | opkg_cmd_fun_t fun; 27 | unsigned int pfm; /* package field mask */ 28 | }; 29 | typedef struct opkg_cmd opkg_cmd_t; 30 | 31 | opkg_cmd_t *opkg_cmd_find(const char *name); 32 | int opkg_cmd_exec(opkg_cmd_t * cmd, int argc, const char **argv); 33 | 34 | extern int opkg_state_changed; 35 | extern int opkg_cli_argc; 36 | extern const char **opkg_cli_argv; 37 | #endif 38 | -------------------------------------------------------------------------------- /libopkg/opkg_download.h: -------------------------------------------------------------------------------- 1 | /* opkg_download.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_DOWNLOAD_H 19 | #define OPKG_DOWNLOAD_H 20 | 21 | #include "pkg.h" 22 | 23 | int opkg_verify_integrity(pkg_t *pkg, const char *filename); 24 | int opkg_download(const char *src, const char *dest_file_name, 25 | const short hide_error); 26 | int opkg_download_pkg(pkg_t * pkg, const char *dir); 27 | /* 28 | * Downloads file from url, installs in package database, return package name. 29 | */ 30 | int opkg_prepare_url_for_install(const char *url, char **namep); 31 | 32 | int opkg_verify_file(char *text_file, char *sig_file); 33 | #endif 34 | -------------------------------------------------------------------------------- /libopkg/opkg_defines.h: -------------------------------------------------------------------------------- 1 | /* opkg_defines.h - the opkg package management system 2 | 3 | Copyright (C) 2008 OpenMoko Inc 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License as 7 | published by the Free Software Foundation; either version 2, or (at 8 | your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, but 11 | WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | General Public License for more details. 14 | */ 15 | 16 | #ifndef OPKG_DEFINES_H 17 | #define OPKG_DEFINES_H 18 | 19 | #define OPKG_PKG_EXTENSION ".opk" 20 | #define IPKG_PKG_EXTENSION ".ipk" 21 | #define DPKG_PKG_EXTENSION ".deb" 22 | 23 | #define OPKG_LEGAL_PKG_NAME_CHARS "abcdefghijklmnopqrstuvwxyz0123456789.+-" 24 | #define OPKG_PKG_VERSION_SEP_CHAR '_' 25 | 26 | #define OPKG_STATE_DIR_PREFIX OPKGLIBDIR"/opkg" 27 | #define OPKG_LISTS_DIR_SUFFIX "lists" 28 | #define OPKG_INFO_DIR_SUFFIX "info" 29 | #define OPKG_STATUS_FILE_SUFFIX "status" 30 | 31 | #define OPKG_BACKUP_SUFFIX "-opkg.backup" 32 | 33 | #define OPKG_LIST_DESCRIPTION_LENGTH 128 34 | 35 | #endif /* OPKG_DEFINES_H */ 36 | -------------------------------------------------------------------------------- /libopkg/pkg_dest_list.h: -------------------------------------------------------------------------------- 1 | /* pkg_dest_list.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_DEST_LIST_H 19 | #define PKG_DEST_LIST_H 20 | 21 | #include "pkg_dest.h" 22 | 23 | typedef struct void_list_elt pkg_dest_list_elt_t; 24 | 25 | typedef struct void_list pkg_dest_list_t; 26 | 27 | void pkg_dest_list_elt_init(pkg_dest_list_elt_t * elt, pkg_dest_t * data); 28 | void pkg_dest_list_elt_deinit(pkg_dest_list_elt_t * elt); 29 | 30 | void pkg_dest_list_init(pkg_dest_list_t * list); 31 | void pkg_dest_list_deinit(pkg_dest_list_t * list); 32 | 33 | pkg_dest_t *pkg_dest_list_append(pkg_dest_list_t * list, const char *name, 34 | const char *root_dir, const char *lists_dir); 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /libbb/wfopen.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999,2000,2001 by Erik Andersen 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include "libbb.h" 25 | 26 | FILE *wfopen(const char *path, const char *mode) 27 | { 28 | FILE *fp; 29 | if ((fp = fopen(path, mode)) == NULL) { 30 | perror_msg("%s", path); 31 | errno = 0; 32 | } 33 | return fp; 34 | } 35 | 36 | /* END CODE */ 37 | /* 38 | Local Variables: 39 | c-file-style: "linux" 40 | c-basic-offset: 4 41 | tab-width: 4 42 | End: 43 | */ 44 | -------------------------------------------------------------------------------- /libbb/safe_strncpy.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999,2000,2001 by Erik Andersen 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include 23 | #include "libbb.h" 24 | 25 | /* Like strncpy but make sure the resulting string is always 0 terminated. */ 26 | extern char *safe_strncpy(char *dst, const char *src, size_t size) 27 | { 28 | dst[size - 1] = '\0'; 29 | return strncpy(dst, src, size - 1); 30 | } 31 | 32 | /* END CODE */ 33 | /* 34 | Local Variables: 35 | c-file-style: "linux" 36 | c-basic-offset: 4 37 | tab-width: 4 38 | End: 39 | */ 40 | -------------------------------------------------------------------------------- /tests/opkg_extract_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | * build thus: 7 | 8 | * gcc -o opkg_extract_test opkg_extract_test.c -I./busybox-0.60.2/libbb -L./busybox-0.60.2 -lbb 9 | * 10 | */ 11 | const char *applet_name; 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | /* 16 | * see libbb.h and let your imagination run wild 17 | * or, set the last item below to extract_one_to_buffer, and you get the control file in 18 | * "returned" 19 | * or, set the last one to extract_all_to_fs, and, well, guess what happens 20 | */ 21 | 22 | /* enum extract_functions_e dowhat = extract_control_tar_gz | extract_unconditional | extract_one_to_buffer; */ 23 | enum extract_functions_e dowhat = 24 | extract_control_tar_gz | extract_all_to_fs | extract_preserve_date; 25 | char *returned; 26 | char *filename; 27 | int err; 28 | 29 | if (argc < 2) { 30 | fprintf(stderr, "syntax: %s []\n", 31 | argv[0]); 32 | exit(0); 33 | } 34 | 35 | if (argc < 3) { 36 | filename = NULL; 37 | } else { 38 | filename = argv[2]; 39 | } 40 | 41 | returned = deb_extract(argv[1], stdout, dowhat, NULL, filename, &err); 42 | 43 | if (returned) 44 | fprintf(stderr, "returned %s\n", returned); 45 | else 46 | fprintf(stderr, "extract returned nuthin'\n"); 47 | 48 | return 0; 49 | } 50 | -------------------------------------------------------------------------------- /libopkg/xregex.c: -------------------------------------------------------------------------------- 1 | /* xregex.c - regex functions with error messages 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation; either version 2, or (at your option) 10 | any later version. 11 | 12 | This program is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | */ 17 | 18 | #include "xregex.h" 19 | #include "libbb/libbb.h" 20 | 21 | static void print_regcomp_err(const regex_t * preg, int err); 22 | 23 | int xregcomp(regex_t * preg, const char *regex, int cflags) 24 | { 25 | int err; 26 | err = regcomp(preg, regex, cflags); 27 | if (err) { 28 | print_regcomp_err(preg, err); 29 | } 30 | 31 | return err; 32 | } 33 | 34 | static void print_regcomp_err(const regex_t * preg, int err) 35 | { 36 | unsigned int size; 37 | char *error; 38 | 39 | size = regerror(err, preg, 0, 0); 40 | error = xcalloc(1, size); 41 | regerror(err, preg, error, size); 42 | 43 | opkg_msg(ERROR, "Internal error compiling regex: %s.", error); 44 | 45 | free(error); 46 | } 47 | -------------------------------------------------------------------------------- /libopkg/sprintf_alloc.c: -------------------------------------------------------------------------------- 1 | /* sprintf_alloc.c -- like sprintf with memory allocation 2 | 3 | Copyright (C) 2010 Ubiq Technologies 4 | 5 | This program is free software; you can redistribute it and/or modify 6 | it under the terms of the GNU General Public License as published by 7 | the Free Software Foundation; either version 2, or (at your option) 8 | any later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | */ 15 | 16 | #include 17 | 18 | #include "sprintf_alloc.h" 19 | #include "libbb/libbb.h" 20 | 21 | void sprintf_alloc(char **str, const char *fmt, ...) 22 | { 23 | va_list ap; 24 | int n; 25 | unsigned int size = 0; 26 | 27 | *str = NULL; 28 | 29 | for (;;) { 30 | va_start(ap, fmt); 31 | n = vsnprintf(*str, size, fmt, ap); 32 | va_end(ap); 33 | 34 | if (n < 0) { 35 | fprintf(stderr, "%s: encountered an output or encoding" 36 | " error during vsnprintf.\n", __FUNCTION__); 37 | exit(EXIT_FAILURE); 38 | } 39 | 40 | if (n < size) 41 | break; 42 | 43 | /* Truncated, try again with more space. */ 44 | size = n + 1; 45 | *str = xrealloc(*str, size); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /libopkg/file_util.h: -------------------------------------------------------------------------------- 1 | /* file_util.h - convenience routines for common file operations 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef FILE_UTIL_H 19 | #define FILE_UTIL_H 20 | 21 | int file_exists(const char *file_name); 22 | int file_is_dir(const char *file_name); 23 | char *file_read_line_alloc(FILE * file); 24 | int file_move(const char *src, const char *dest); 25 | int file_copy(const char *src, const char *dest); 26 | int file_mkdir_hier(const char *path, long mode); 27 | char *file_md5sum_alloc(const char *file_name); 28 | char *file_sha256sum_alloc(const char *file_name); 29 | int rm_r(const char *path); 30 | 31 | char *checksum_bin2hex(const char *src, size_t len); 32 | char *checksum_hex2bin(const char *src, size_t *len); 33 | 34 | char *urlencode_path(const char *filename); 35 | char *urldecode_path(const char *filename); 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /libbb/last_char_is.c: -------------------------------------------------------------------------------- 1 | /* 2 | * busybox library eXtended function 3 | * 4 | * Copyright (C) 2001 Larry Doolittle, 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 19 | * 20 | */ 21 | 22 | #include 23 | #include "libbb.h" 24 | 25 | /* Find out if the last character of a string matches the one given Don't 26 | * underrun the buffer if the string length is 0. Also avoids a possible 27 | * space-hogging inline of strlen() per usage. 28 | */ 29 | char *last_char_is(const char *s, int c) 30 | { 31 | char *sret; 32 | if (!s) 33 | return NULL; 34 | sret = (char *)s + strlen(s) - 1; 35 | if (sret >= s && *sret == c) { 36 | return sret; 37 | } else { 38 | return NULL; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /libopkg/opkg_configure.c: -------------------------------------------------------------------------------- 1 | /* opkg_configure.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | 20 | #include "sprintf_alloc.h" 21 | #include "opkg_configure.h" 22 | #include "opkg_message.h" 23 | #include "opkg_cmd.h" 24 | #include "pkg_alternatives.h" 25 | 26 | int opkg_configure(pkg_t * pkg) 27 | { 28 | int err; 29 | 30 | /* DPKG_INCOMPATIBILITY: 31 | dpkg actually does some conffile handling here, rather than at the 32 | end of opkg_install(). Do we care? */ 33 | /* DPKG_INCOMPATIBILITY: 34 | dpkg actually includes a version number to this script call */ 35 | 36 | err = pkg_run_script(pkg, "postinst", "configure"); 37 | if (err) { 38 | opkg_msg(ERROR, "%s.postinst returned %d.\n", pkg->name, err); 39 | return err; 40 | } 41 | 42 | pkg_alternatives_update(pkg); 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /libopkg/pkg_src_list.h: -------------------------------------------------------------------------------- 1 | /* pkg_src_list.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_SRC_LIST_H 19 | #define PKG_SRC_LIST_H 20 | 21 | #include "pkg_src.h" 22 | #include "void_list.h" 23 | 24 | typedef struct void_list_elt pkg_src_list_elt_t; 25 | 26 | typedef struct void_list pkg_src_list_t; 27 | 28 | static inline int pkg_src_list_empty(pkg_src_list_t * list) 29 | { 30 | return void_list_empty((void_list_t *) list); 31 | } 32 | 33 | void pkg_src_list_elt_init(pkg_src_list_elt_t * elt, nv_pair_t * data); 34 | void pkg_src_list_elt_deinit(pkg_src_list_elt_t * elt); 35 | 36 | void pkg_src_list_init(pkg_src_list_t * list); 37 | void pkg_src_list_deinit(pkg_src_list_t * list); 38 | 39 | pkg_src_t *pkg_src_list_append(pkg_src_list_t * list, const char *name, 40 | const char *root_dir, int gzip); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /libbb/gzip.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Jo-Philipp Wich 3 | * 4 | * Zlib decrompression utility routines. 5 | * 6 | * This program is free software; you can redistribute it and/or modify 7 | * it under the terms of the GNU General Public License as published by 8 | * the Free Software Foundation; either version 2 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Library General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU General Public License 17 | * along with this program; if not, write to the Free Software 18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 | */ 20 | 21 | #include 22 | #include 23 | #include 24 | 25 | struct gzip_handle { 26 | FILE *file; 27 | struct gzip_handle *gzip; 28 | 29 | pid_t pid; 30 | int rfd, wfd; 31 | struct sigaction pipe_sa; 32 | pthread_t thread; 33 | }; 34 | 35 | int gzip_exec(struct gzip_handle *zh, const char *filename); 36 | ssize_t gzip_read(struct gzip_handle *zh, void *buf, ssize_t len); 37 | ssize_t gzip_copy(struct gzip_handle *zh, FILE * out, ssize_t len); 38 | int gzip_close(struct gzip_handle *zh); 39 | FILE *gzip_fdopen(struct gzip_handle *zh, const char *filename); 40 | 41 | #define gzip_seek(zh, len) gzip_copy(zh, NULL, len) 42 | -------------------------------------------------------------------------------- /libbb/concat_path_file.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) many different people. If you wrote this, please 6 | * acknowledge your work. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 | * USA 22 | */ 23 | 24 | /* concatenate path and file name to new allocation buffer, 25 | * not addition '/' if path name already have '/' 26 | */ 27 | 28 | #include 29 | #include "libbb.h" 30 | 31 | extern char *concat_path_file(const char *path, const char *filename) 32 | { 33 | char *outbuf; 34 | char *lc; 35 | 36 | if (!path) 37 | path = ""; 38 | lc = last_char_is(path, '/'); 39 | while (*filename == '/') 40 | filename++; 41 | outbuf = xmalloc(strlen(path) + strlen(filename) + 1 + (lc == NULL)); 42 | sprintf(outbuf, "%s%s%s", path, (lc == NULL) ? "/" : "", filename); 43 | 44 | return outbuf; 45 | } 46 | -------------------------------------------------------------------------------- /libopkg/str_list.h: -------------------------------------------------------------------------------- 1 | /* str_list.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef STR_LIST_H 19 | #define STR_LIST_H 20 | 21 | #include "void_list.h" 22 | 23 | typedef struct void_list_elt str_list_elt_t; 24 | 25 | typedef struct void_list str_list_t; 26 | 27 | void str_list_elt_init(str_list_elt_t * elt, char *data); 28 | void str_list_elt_deinit(str_list_elt_t * elt); 29 | 30 | str_list_t *str_list_alloc(void); 31 | void str_list_init(str_list_t * list); 32 | void str_list_deinit(str_list_t * list); 33 | 34 | void str_list_append(str_list_t * list, char *data); 35 | str_list_elt_t *str_list_pop(str_list_t * list); 36 | void str_list_remove(str_list_t * list, str_list_elt_t ** iter); 37 | void str_list_remove_elt(str_list_t * list, const char *target_str); 38 | 39 | str_list_elt_t *str_list_first(str_list_t * list); 40 | str_list_elt_t *str_list_next(str_list_t * list, str_list_elt_t * node); 41 | 42 | void str_list_purge(str_list_t * list); 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # git-ls-files --others --exclude-from=.git/info/exclude 2 | # Lines that start with '#' are comments. 3 | # For a project mostly in C, the following would be a good set of 4 | # exclude patterns (uncomment them if you want to use them): 5 | 6 | *.orig 7 | *.rej 8 | *.mergebackup 9 | *.[oa] 10 | *~ 11 | *.*.swp 12 | 13 | Makefile 14 | Makefile.in 15 | # o_0 16 | Makefile.in.in 17 | !tests/regress/Makefile 18 | 19 | # The local aclocal.m4 file 20 | aclocal.m4 21 | m4/ 22 | shave/lt* 23 | shave/libtool.m4 24 | shave/shave 25 | shave/shave-libtool 26 | 27 | # The output of the configure script 28 | conf/ 29 | config.guess 30 | config.log 31 | config.status 32 | config.sub 33 | 34 | # The configure script itself 35 | configure 36 | 37 | # The libopkg directory artifacts 38 | libopkg/config.h 39 | libopkg/config.h.in 40 | libopkg/stamp-h1 41 | 42 | # Various scripts used for libtool and the like 43 | install-sh 44 | libtool 45 | ltmain.sh 46 | missing 47 | depcomp 48 | 49 | # opkg stuff 50 | libopkg.pc 51 | utils/update-alternatives 52 | 53 | autom4te.cache/ 54 | 55 | # Binaries 56 | *.la 57 | *.lo 58 | *.o 59 | *.so 60 | .libs/ 61 | .deps/ 62 | src/opkg-cl 63 | tests/libopkg_test 64 | tests/opkg_active_list_test 65 | tests/opkg_extract_test 66 | tests/opkg_hash_test 67 | 68 | # Man pages 69 | man/*.1 70 | 71 | # CMake artifacts 72 | CMakeCache.txt 73 | CMakeFiles/ 74 | cmake_install.cmake 75 | libbb/CMakeFiles/ 76 | libbb/cmake_install.cmake 77 | libopkg/CMakeFiles/ 78 | libopkg/cmake_install.cmake 79 | src/CMakeFiles/ 80 | src/cmake_install.cmake 81 | tests/CMakeFiles/ 82 | tests/cmake_install.cmake 83 | -------------------------------------------------------------------------------- /libopkg/active_list.h: -------------------------------------------------------------------------------- 1 | /* active_list.h - the opkg package management system 2 | 3 | Tick Chen 4 | 5 | Copyright (C) 2008 Openmoko Inc. 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef ACTIVE_LIST_H 19 | #define ACTIVE_LIST_H 20 | 21 | #include "list.h" 22 | #include "pkg.h" 23 | 24 | struct active_list { 25 | struct list_head node; 26 | struct list_head depend; 27 | struct active_list *depended; 28 | pkg_t *pkg; 29 | }; 30 | 31 | struct active_list *active_list_head_new(void); 32 | void active_list_head_delete(struct active_list *); 33 | void active_list_init(struct active_list *ptr); 34 | void active_list_clear(struct active_list *head); 35 | void active_list_add(struct active_list *head, struct active_list *node); 36 | struct active_list *active_list_move_node(struct active_list *old_head, 37 | struct active_list *new_head, 38 | struct active_list *node); 39 | 40 | struct active_list *active_list_next(struct active_list *head, 41 | struct active_list *ptr); 42 | 43 | struct active_list *active_list_prev(struct active_list *head, 44 | struct active_list *ptr); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /libopkg/opkg_message.h: -------------------------------------------------------------------------------- 1 | /* opkg_message.h - the opkg package management system 2 | 3 | Copyright (C) 2009 Ubiq Technologies 4 | Copyright (C) 2003 Daniele Nicolodi 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2, or (at 9 | your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | */ 16 | 17 | #ifndef _OPKG_MESSAGE_H_ 18 | #define _OPKG_MESSAGE_H_ 19 | 20 | #include 21 | #include 22 | 23 | typedef enum { 24 | ERROR, /* error conditions */ 25 | NOTICE, /* normal but significant condition */ 26 | INFO, /* informational message */ 27 | DEBUG, /* debug level message */ 28 | DEBUG2, /* more debug level message */ 29 | } message_level_t; 30 | 31 | void free_error_list(void); 32 | void print_error_list(void); 33 | void opkg_message(message_level_t level, const char *fmt, ...) 34 | __attribute__ ((format(printf, 2, 3))); 35 | 36 | #define opkg_msg(l, fmt, args...) \ 37 | do { \ 38 | if (l == NOTICE) \ 39 | opkg_message(l, fmt, ##args); \ 40 | else \ 41 | opkg_message(l, "%s: "fmt, __FUNCTION__, ##args); \ 42 | } while (0) 43 | 44 | #define opkg_perror(l, fmt, args...) \ 45 | opkg_msg(l, fmt": %s.\n", ##args, strerror(errno)) 46 | 47 | #endif /* _OPKG_MESSAGE_H_ */ 48 | -------------------------------------------------------------------------------- /libopkg/nv_pair_list.h: -------------------------------------------------------------------------------- 1 | /* nv_pair_list.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef NV_PAIR_LIST_H 19 | #define NV_PAIR_LIST_H 20 | 21 | #include "nv_pair.h" 22 | #include "void_list.h" 23 | 24 | typedef struct void_list_elt nv_pair_list_elt_t; 25 | 26 | typedef struct void_list nv_pair_list_t; 27 | 28 | static inline int nv_pair_list_empty(nv_pair_list_t * list) 29 | { 30 | return void_list_empty((void_list_t *) list); 31 | } 32 | 33 | void nv_pair_list_init(nv_pair_list_t * list); 34 | void nv_pair_list_deinit(nv_pair_list_t * list); 35 | 36 | nv_pair_t *nv_pair_list_append(nv_pair_list_t * list, 37 | const char *name, const char *value); 38 | void nv_pair_list_push(nv_pair_list_t * list, nv_pair_t * data); 39 | nv_pair_list_elt_t *nv_pair_list_pop(nv_pair_list_t * list); 40 | char *nv_pair_list_find(nv_pair_list_t * list, char *name); 41 | 42 | nv_pair_list_elt_t *nv_pair_list_first(nv_pair_list_t * list); 43 | nv_pair_list_elt_t *nv_pair_list_next(nv_pair_list_t * list, 44 | nv_pair_list_elt_t * node); 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | PROJECT(opkg C) 4 | 5 | INCLUDE(TestBigEndian) 6 | 7 | SET(HOST_CPU "" CACHE STRING "Override Host CPU") 8 | SET(BUILD_CPU "" CACHE STRING "Override Host CPU") 9 | SET(LOCK_FILE "/var/lock/opkg.lock" CACHE STRING "Override lock file path") 10 | SET(PATH_SPEC "/usr/sbin:/usr/bin:/sbin:/bin" CACHE STRING "Override default PATH value") 11 | SET(VERSION "" CACHE STRING "Override version") 12 | 13 | OPTION(STATIC_UBOX "Statically link libubox" OFF) 14 | OPTION(BUILD_TESTS "Build test programs" ON) 15 | OPTION(ENABLE_USIGN "Enable usign support" ON) 16 | 17 | IF(NOT HOST_CPU) 18 | SET(HOST_CPU "${CMAKE_HOST_SYSTEM_PROCESSOR}") 19 | ENDIF() 20 | 21 | IF(NOT BUILD_CPU) 22 | SET(BUILD_CPU "${CMAKE_SYSTEM_PROCESSOR}") 23 | ENDIF() 24 | 25 | IF(NOT VERSION) 26 | EXECUTE_PROCESS(COMMAND git log -1 "--format=%h (%ci)" 27 | OUTPUT_VARIABLE VERSION 28 | OUTPUT_STRIP_TRAILING_WHITESPACE 29 | ) 30 | ENDIF() 31 | 32 | IF(NOT VERSION) 33 | SET(VERSION "unknown") 34 | ENDIF() 35 | 36 | TEST_BIG_ENDIAN(WORDS_BIGENDIAN) 37 | 38 | ADD_DEFINITIONS(-Os -Wall --std=gnu99 -g3 -Wmissing-declarations 39 | -DDATADIR="/usr/share" 40 | -DOPKGETCDIR="/etc" 41 | -DOPKGLOCKFILE="${LOCK_FILE}" 42 | -DOPKGLIBDIR="/usr/lib" 43 | -DHOST_CPU_STR="${HOST_CPU}" 44 | -DBUILD_CPU=${BUILD_CPU} 45 | -DPATH_SPEC="${PATH_SPEC}" 46 | -DVERSION="${VERSION}" 47 | ) 48 | 49 | IF(ENABLE_USIGN) 50 | ADD_DEFINITIONS(-DHAVE_USIGN) 51 | ENDIF() 52 | 53 | IF(WORDS_BIGENDIAN) 54 | ADD_DEFINITIONS(-DWORDS_BIGENDIAN) 55 | ENDIF() 56 | 57 | ADD_SUBDIRECTORY(libbb) 58 | ADD_SUBDIRECTORY(libopkg) 59 | ADD_SUBDIRECTORY(src) 60 | 61 | IF(BUILD_TESTS) 62 | ADD_SUBDIRECTORY(tests) 63 | ENDIF() 64 | -------------------------------------------------------------------------------- /libopkg/pkg_src_list.c: -------------------------------------------------------------------------------- 1 | /* pkg_src_list.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "pkg_src_list.h" 19 | #include "void_list.h" 20 | #include "libbb/libbb.h" 21 | 22 | void pkg_src_list_init(pkg_src_list_t * list) 23 | { 24 | void_list_init((void_list_t *) list); 25 | } 26 | 27 | void pkg_src_list_deinit(pkg_src_list_t * list) 28 | { 29 | pkg_src_list_elt_t *iter, *n; 30 | pkg_src_t *pkg_src; 31 | 32 | list_for_each_entry_safe(iter, n, &list->head, node) { 33 | pkg_src = (pkg_src_t *) iter->data; 34 | pkg_src_deinit(pkg_src); 35 | 36 | /* malloced in pkg_src_list_append */ 37 | free(pkg_src); 38 | iter->data = NULL; 39 | } 40 | void_list_deinit((void_list_t *) list); 41 | } 42 | 43 | pkg_src_t *pkg_src_list_append(pkg_src_list_t * list, 44 | const char *name, const char *base_url, 45 | int gzip) 46 | { 47 | /* freed in pkg_src_list_deinit */ 48 | pkg_src_t *pkg_src = xcalloc(1, sizeof(pkg_src_t)); 49 | pkg_src_init(pkg_src, name, base_url, gzip); 50 | 51 | void_list_append((void_list_t *) list, pkg_src); 52 | 53 | return pkg_src; 54 | } 55 | -------------------------------------------------------------------------------- /libbb/time_string.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999,2000,2001 by Erik Andersen 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "libbb.h" 27 | 28 | /* 29 | * Return the standard ls-like time string from a time_t 30 | * This is static and so is overwritten on each call. 31 | */ 32 | const char *time_string(time_t timeVal) 33 | { 34 | time_t now; 35 | char *str; 36 | static char buf[26]; 37 | 38 | time(&now); 39 | 40 | str = ctime(&timeVal); 41 | 42 | strcpy(buf, &str[4]); 43 | buf[12] = '\0'; 44 | 45 | if ((timeVal > now) || (timeVal < now - 365 * 24 * 60 * 60L)) { 46 | strcpy(&buf[7], &str[20]); 47 | buf[11] = '\0'; 48 | } 49 | 50 | return buf; 51 | } 52 | 53 | /* END CODE */ 54 | /* 55 | Local Variables: 56 | c-file-style: "linux" 57 | c-basic-offset: 4 58 | tab-width: 4 59 | End: 60 | */ 61 | -------------------------------------------------------------------------------- /tests/regress/issue72.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | long_dir = 110*"a" 9 | long_b = 110*"b" 10 | long_filename = long_dir + "/"+ long_b 11 | long_filename2 = long_dir + "/" + 110*"c" 12 | 13 | os.mkdir(long_dir) 14 | open(long_filename, "w").close() 15 | os.symlink(long_b, long_filename2) 16 | a = opk.Opk(Package="a", Version="1.0", Architecture="all") 17 | a.write(data_files=[long_dir, long_filename, long_filename2]) 18 | os.unlink(long_filename) 19 | os.unlink(long_filename2) 20 | os.rmdir(long_dir) 21 | opkgcl.install("a_1.0_all.opk") 22 | 23 | if not opkgcl.is_installed("a"): 24 | print(__file__, ": Package 'a' not installed.") 25 | exit(False) 26 | 27 | if not os.path.exists("{}/{}".format(cfg.offline_root, long_dir)): 28 | print(__file__, ": dir with name longer than 100 " 29 | "characters not created.") 30 | exit(False) 31 | 32 | if not os.path.exists("{}/{}".format(cfg.offline_root, long_filename)): 33 | print(__file__, ": file with a name longer than 100 characters, " 34 | "in dir with name longer than 100 characters, " 35 | "not created.") 36 | exit(False) 37 | 38 | if not os.path.lexists("{}/{}".format(cfg.offline_root, long_filename2)): 39 | print(__file__, ": symlink with a name longer than 100 characters, " 40 | "pointing at a file with a name longer than " 41 | "100 characters," 42 | "in dir with name longer than 100 characters, " 43 | "not created.") 44 | exit(False) 45 | 46 | linky = os.path.realpath("{}/{}".format(cfg.offline_root, long_filename2)) 47 | linky_dst = "{}/{}".format(cfg.offline_root, long_filename) 48 | if linky != linky_dst: 49 | print(__file__, ": symlink path truncated.") 50 | exit(False) 51 | 52 | opkgcl.remove("a") 53 | -------------------------------------------------------------------------------- /libopkg/hash_table.h: -------------------------------------------------------------------------------- 1 | /* hash.h - hash tables for opkg 2 | 3 | Steven M. Ayer, Jamey Hicks 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef _HASH_TABLE_H_ 19 | #define _HASH_TABLE_H_ 20 | 21 | typedef struct hash_entry hash_entry_t; 22 | typedef struct hash_table hash_table_t; 23 | 24 | struct hash_entry { 25 | char *key; 26 | void *data; 27 | struct hash_entry *next; 28 | }; 29 | 30 | struct hash_table { 31 | const char *name; 32 | hash_entry_t *entries; 33 | unsigned int n_buckets; 34 | unsigned int n_elements; 35 | 36 | /* useful stats */ 37 | unsigned int n_used_buckets; 38 | unsigned int n_collisions; 39 | unsigned int max_bucket_len; 40 | unsigned int n_hits, n_misses; 41 | }; 42 | 43 | void hash_table_init(const char *name, hash_table_t * hash, int len); 44 | void hash_table_deinit(hash_table_t * hash); 45 | void hash_print_stats(hash_table_t * hash); 46 | void *hash_table_get(hash_table_t * hash, const char *key); 47 | int hash_table_insert(hash_table_t * hash, const char *key, void *value); 48 | int hash_table_remove(hash_table_t * has, const char *key); 49 | void hash_table_foreach(hash_table_t * hash, 50 | void (*f) (const char *key, void *entry, void *data), 51 | void *data); 52 | 53 | #endif /* _HASH_TABLE_H_ */ 54 | -------------------------------------------------------------------------------- /tests/regress/issue51.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import opk, cfg, opkgcl 5 | 6 | opk.regress_init() 7 | 8 | open("foo", "w").close() 9 | a1 = opk.Opk(Package="a", Version="1.0", Architecture="all") 10 | a1.write(data_files=["foo"]) 11 | os.rename("a_1.0_all.opk", "a_with_foo.opk") 12 | 13 | opkgcl.install("a_with_foo.opk") 14 | 15 | # ---- 16 | opkgcl.install("a_with_foo.opk") 17 | 18 | open("bar", "w").close() 19 | o = opk.OpkGroup() 20 | a2 = opk.Opk(Package="a", Version="1.0", Architecture="all") 21 | a2.write(data_files=["foo", "bar"]) 22 | o.opk_list.append(a2) 23 | o.write_list() 24 | 25 | os.unlink("foo") 26 | os.unlink("bar") 27 | 28 | opkgcl.update() 29 | opkgcl.install("a", "--force-reinstall") 30 | 31 | foo_fullpath = "{}/foo".format(cfg.offline_root) 32 | bar_fullpath = "{}/bar".format(cfg.offline_root) 33 | 34 | if not os.path.exists(foo_fullpath) or not os.path.exists(bar_fullpath): 35 | print(__file__, ": Files foo and/or bar are missing.") 36 | exit(False) 37 | 38 | a_files = opkgcl.files("a") 39 | if not foo_fullpath in a_files or not bar_fullpath in a_files: 40 | print(__file__, ": Package 'a' does not own foo and/or bar.") 41 | exit(False) 42 | 43 | opkgcl.remove("a") 44 | 45 | if os.path.exists(foo_fullpath) or os.path.exists(bar_fullpath): 46 | print(__file__, ": Files foo and/or bar still exist " 47 | "after removal of package 'a'.") 48 | exit(False) 49 | 50 | # ---- 51 | o = opk.OpkGroup() 52 | a2 = opk.Opk(Package="a", Version="1.0", Architecture="all") 53 | a2.write() 54 | o.opk_list.append(a2) 55 | o.write_list() 56 | 57 | 58 | opkgcl.update() 59 | 60 | opkgcl.install("a", "--force-reinstall") 61 | 62 | if os.path.exists(foo_fullpath): 63 | print(__file__, ": File 'foo' not orphaned as it should be.") 64 | exit(False) 65 | 66 | if foo_fullpath in opkgcl.files("a"): 67 | print(__file__, ": Package 'a' incorrectly owns file 'foo'.") 68 | exit(False) 69 | 70 | opkgcl.remove("a") 71 | -------------------------------------------------------------------------------- /utils/opkg-key: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # Based on apt-key from apt-0.6.25 4 | # Licensed under GPL Version 2 5 | 6 | set -e 7 | 8 | usage() { 9 | echo "Usage: opkg-key [options] command [arguments]" 10 | echo 11 | echo "Manage opkg's list of trusted keys" 12 | echo 13 | echo " opkg-key add - add the key contained in ('-' for stdin)" 14 | echo " opkg-key del - remove the key " 15 | echo " opkg-key list - list keys" 16 | echo 17 | echo "Options:" 18 | echo " -o Use as the offline root directory" 19 | echo 20 | } 21 | 22 | if [ "$1" = "-o" ]; then 23 | ROOT=$2 24 | shift 2 25 | echo "Note: using \"$ROOT\" as root path" 26 | else 27 | ROOT="" 28 | fi 29 | 30 | command="$1" 31 | if [ -z "$command" ]; then 32 | usage 33 | exit 1 34 | fi 35 | shift 36 | 37 | if [ "$command" != "help" ] && ! which gpg >/dev/null 2>&1; then 38 | echo >&2 "Warning: gnupg does not seem to be installed." 39 | echo >&2 "Warning: opkg-key requires gnupg for most operations." 40 | echo >&2 41 | fi 42 | 43 | # We don't use a secret keyring, of course, but gpg panics and 44 | # implodes if there isn't one available 45 | 46 | GPG="gpg --no-options --no-default-keyring --keyring $ROOT/etc/opkg/trusted.gpg --secret-keyring $ROOT/etc/opkg/secring.gpg --trustdb-name $ROOT/etc/opkg/trustdb.gpg" 47 | 48 | case "$command" in 49 | add) 50 | $GPG --quiet --batch --import "$1" 51 | echo "OK" 52 | ;; 53 | del|rm|remove) 54 | $GPG --quiet --batch --delete-key --yes "$1" 55 | echo "OK" 56 | ;; 57 | list) 58 | $GPG --batch --list-keys 59 | ;; 60 | finger*) 61 | $GPG --batch --fingerprint 62 | ;; 63 | adv*) 64 | echo "Executing: $GPG $*" 65 | $GPG $* 66 | ;; 67 | help) 68 | usage 69 | ;; 70 | *) 71 | usage 72 | exit 1 73 | ;; 74 | esac 75 | -------------------------------------------------------------------------------- /libopkg/conffile.c: -------------------------------------------------------------------------------- 1 | /* conffile.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "opkg_message.h" 22 | #include "conffile.h" 23 | #include "file_util.h" 24 | #include "sprintf_alloc.h" 25 | #include "opkg_conf.h" 26 | 27 | int conffile_init(conffile_t * conffile, const char *file_name, 28 | const char *md5sum) 29 | { 30 | return nv_pair_init(conffile, file_name, md5sum); 31 | } 32 | 33 | void conffile_deinit(conffile_t * conffile) 34 | { 35 | nv_pair_deinit(conffile); 36 | } 37 | 38 | int conffile_has_been_modified(conffile_t * conffile) 39 | { 40 | char *chksum; 41 | char *filename = conffile->name; 42 | char *root_filename; 43 | int ret = 1; 44 | 45 | if (conffile->value == NULL) { 46 | opkg_msg(NOTICE, "Conffile %s has no md5sum.\n", 47 | conffile->name); 48 | return 1; 49 | } 50 | 51 | root_filename = root_filename_alloc(filename); 52 | 53 | if (conffile->value && strlen(conffile->value) > 33) { 54 | chksum = file_sha256sum_alloc(root_filename); 55 | } else { 56 | chksum = file_md5sum_alloc(root_filename); 57 | } 58 | 59 | if (chksum && (ret = strcmp(chksum, conffile->value))) { 60 | opkg_msg(INFO, "Conffile %s:\n\told chk=%s\n\tnew chk=%s\n", 61 | conffile->name, chksum, conffile->value); 62 | } 63 | 64 | free(root_filename); 65 | if (chksum) 66 | free(chksum); 67 | 68 | return ret; 69 | } 70 | -------------------------------------------------------------------------------- /libopkg/opkg_utils.c: -------------------------------------------------------------------------------- 1 | /* opkg_utils.c - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "libbb/libbb.h" 22 | #include "opkg_utils.h" 23 | 24 | unsigned long get_available_kbytes(char *filesystem) 25 | { 26 | struct statvfs f; 27 | 28 | if (statvfs(filesystem, &f) == -1) { 29 | opkg_perror(ERROR, "Failed to statvfs for %s", filesystem); 30 | return 0; 31 | } 32 | // Actually ((sfs.f_bavail * sfs.f_frsize) / 1024) 33 | // and here we try to avoid overflow. 34 | if (f.f_frsize >= 1024) 35 | return (f.f_bavail * (f.f_frsize / 1024)); 36 | else if (f.f_frsize > 0) 37 | return f.f_bavail / (1024 / f.f_frsize); 38 | 39 | opkg_msg(ERROR, "Unknown block size for target filesystem.\n"); 40 | 41 | return 0; 42 | } 43 | 44 | /* something to remove whitespace, a hash pooper */ 45 | char *trim_xstrdup(const char *src) 46 | { 47 | const char *end; 48 | 49 | /* remove it from the front */ 50 | while (src && isspace(*src) && *src) 51 | src++; 52 | 53 | end = src + (strlen(src) - 1); 54 | 55 | /* and now from the back */ 56 | while ((end > src) && isspace(*end)) 57 | end--; 58 | 59 | end++; 60 | 61 | /* xstrndup will NULL terminate for us */ 62 | return xstrndup(src, end - src); 63 | } 64 | 65 | int line_is_blank(const char *line) 66 | { 67 | const char *s; 68 | 69 | for (s = line; *s; s++) { 70 | if (!isspace(*s)) 71 | return 0; 72 | } 73 | return 1; 74 | } 75 | -------------------------------------------------------------------------------- /libopkg/xsystem.c: -------------------------------------------------------------------------------- 1 | /* xsystem.c - system(3) with error messages 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | 22 | #include "xsystem.h" 23 | #include "libbb/libbb.h" 24 | 25 | /* Like system(3), but with error messages printed if the fork fails 26 | or if the child process dies due to an uncaught signal. Also, the 27 | return value is a bit simpler: 28 | 29 | -1 if there was any problem 30 | Otherwise, the 8-bit return value of the program ala WEXITSTATUS 31 | as defined in . 32 | */ 33 | int xsystem(const char *argv[]) 34 | { 35 | int status; 36 | pid_t pid; 37 | 38 | pid = vfork(); 39 | 40 | switch (pid) { 41 | case -1: 42 | opkg_perror(ERROR, "%s: vfork", argv[0]); 43 | return -1; 44 | case 0: 45 | /* child */ 46 | execvp(argv[0], (char *const *)argv); 47 | _exit(-1); 48 | default: 49 | /* parent */ 50 | break; 51 | } 52 | 53 | if (waitpid(pid, &status, 0) == -1) { 54 | opkg_perror(ERROR, "%s: waitpid", argv[0]); 55 | return -1; 56 | } 57 | 58 | if (WIFSIGNALED(status)) { 59 | opkg_msg(ERROR, "%s: Child killed by signal %d.\n", 60 | argv[0], WTERMSIG(status)); 61 | return -1; 62 | } 63 | 64 | if (!WIFEXITED(status)) { 65 | /* shouldn't happen */ 66 | opkg_msg(ERROR, "%s: Your system is broken: got status %d " 67 | "from waitpid.\n", argv[0], status); 68 | return -1; 69 | } 70 | 71 | return WEXITSTATUS(status); 72 | } 73 | -------------------------------------------------------------------------------- /libopkg/pkg_dest_list.c: -------------------------------------------------------------------------------- 1 | /* pkg_dest_list.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | 20 | #include "pkg_dest.h" 21 | #include "void_list.h" 22 | #include "pkg_dest_list.h" 23 | #include "libbb/libbb.h" 24 | 25 | void pkg_dest_list_elt_init(pkg_dest_list_elt_t * elt, pkg_dest_t * data) 26 | { 27 | void_list_elt_init((void_list_elt_t *) elt, data); 28 | } 29 | 30 | void pkg_dest_list_elt_deinit(pkg_dest_list_elt_t * elt) 31 | { 32 | void_list_elt_deinit((void_list_elt_t *) elt); 33 | } 34 | 35 | void pkg_dest_list_init(pkg_dest_list_t * list) 36 | { 37 | void_list_init((void_list_t *) list); 38 | } 39 | 40 | void pkg_dest_list_deinit(pkg_dest_list_t * list) 41 | { 42 | pkg_dest_list_elt_t *iter, *n; 43 | pkg_dest_t *pkg_dest; 44 | 45 | list_for_each_entry_safe(iter, n, &list->head, node) { 46 | pkg_dest = (pkg_dest_t *) iter->data; 47 | pkg_dest_deinit(pkg_dest); 48 | 49 | /* malloced in pkg_dest_list_append */ 50 | free(pkg_dest); 51 | iter->data = NULL; 52 | } 53 | void_list_deinit((void_list_t *) list); 54 | } 55 | 56 | pkg_dest_t *pkg_dest_list_append(pkg_dest_list_t * list, const char *name, 57 | const char *root_dir, const char *lists_dir) 58 | { 59 | pkg_dest_t *pkg_dest; 60 | 61 | /* freed in pkg_dest_list_deinit */ 62 | pkg_dest = xcalloc(1, sizeof(pkg_dest_t)); 63 | pkg_dest_init(pkg_dest, name, root_dir, lists_dir); 64 | void_list_append((void_list_t *) list, pkg_dest); 65 | 66 | return pkg_dest; 67 | } 68 | -------------------------------------------------------------------------------- /libopkg/pkg_parse.h: -------------------------------------------------------------------------------- 1 | /* pkg_parse.h - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_PARSE_H 19 | #define PKG_PARSE_H 20 | 21 | #include "pkg.h" 22 | 23 | int parse_version(pkg_t * pkg, const char *raw); 24 | int pkg_parse_from_stream(pkg_t * pkg, FILE * fp, uint mask); 25 | int pkg_parse_line(void *ptr, char *line, uint mask); 26 | 27 | #define EXCESSIVE_LINE_LEN (4096 << 8) 28 | 29 | /* package field mask */ 30 | #define PFM_ALTERNATIVES (1 << 1) 31 | #define PFM_ARCHITECTURE (1 << 2) 32 | #define PFM_AUTO_INSTALLED (1 << 3) 33 | #define PFM_CONFFILES (1 << 4) 34 | #define PFM_CONFLICTS (1 << 5) 35 | #define PFM_DESCRIPTION (1 << 6) 36 | #define PFM_DEPENDS (1 << 7) 37 | #define PFM_ESSENTIAL (1 << 8) 38 | #define PFM_FILENAME (1 << 9) 39 | #define PFM_INSTALLED_SIZE (1 << 10) 40 | #define PFM_INSTALLED_TIME (1 << 11) 41 | #define PFM_MD5SUM (1 << 12) 42 | #define PFM_MAINTAINER (1 << 13) 43 | #define PFM_PACKAGE (1 << 14) 44 | #define PFM_PRIORITY (1 << 15) 45 | #define PFM_PROVIDES (1 << 16) 46 | #define PFM_PRE_DEPENDS (1 << 17) 47 | #define PFM_RECOMMENDS (1 << 18) 48 | #define PFM_REPLACES (1 << 19) 49 | #define PFM_SECTION (1 << 20) 50 | #define PFM_SHA256SUM (1 << 21) 51 | #define PFM_SIZE (1 << 22) 52 | #define PFM_SOURCE (1 << 23) 53 | #define PFM_STATUS (1 << 24) 54 | #define PFM_SUGGESTS (1 << 25) 55 | #define PFM_TAGS (1 << 26) 56 | #define PFM_VERSION (1 << 27) 57 | #define PFM_ABIVERSION (1 << 28) 58 | 59 | #define PFM_ALL (~(uint)0) 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /libbb/copy_file_chunk.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) many different people. If you wrote this, please 6 | * acknowledge your work. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 | * USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include "libbb.h" 27 | 28 | /* Copy CHUNKSIZE bytes (or until EOF if CHUNKSIZE equals -1) from SRC_FILE 29 | * to DST_FILE. */ 30 | extern int copy_file_chunk(FILE * src_file, FILE * dst_file, 31 | unsigned long long chunksize) 32 | { 33 | size_t nread, nwritten, size; 34 | char buffer[BUFSIZ]; 35 | 36 | while (chunksize != 0) { 37 | if (chunksize > BUFSIZ) 38 | size = BUFSIZ; 39 | else 40 | size = chunksize; 41 | 42 | nread = fread(buffer, 1, size, src_file); 43 | 44 | if (nread != size && ferror(src_file)) { 45 | perror_msg("read"); 46 | return -1; 47 | } else if (nread == 0) { 48 | if (chunksize != -1) { 49 | error_msg("Unable to read all data"); 50 | return -1; 51 | } 52 | 53 | return 0; 54 | } 55 | 56 | nwritten = fwrite(buffer, 1, nread, dst_file); 57 | 58 | if (nwritten != nread) { 59 | if (ferror(dst_file)) 60 | perror_msg("write"); 61 | else 62 | error_msg("Unable to write all data"); 63 | return -1; 64 | } 65 | 66 | if (chunksize != -1) 67 | chunksize -= nwritten; 68 | } 69 | 70 | return 0; 71 | } 72 | -------------------------------------------------------------------------------- /libbb/all_read.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999-2004 by Erik Andersen 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include "libbb.h" 26 | 27 | extern void archive_xread_all(int fd, char *buf, size_t count) 28 | { 29 | ssize_t size; 30 | 31 | size = full_read(fd, buf, count); 32 | if (size != count) { 33 | perror_msg_and_die("Short read"); 34 | } 35 | return; 36 | } 37 | 38 | /* 39 | * Read all of the supplied buffer from a file. 40 | * This does multiple reads as necessary. 41 | * Returns the amount read, or -1 on an error. 42 | * A short read is returned on an end of file. 43 | */ 44 | ssize_t full_read(int fd, char *buf, int len) 45 | { 46 | ssize_t cc; 47 | ssize_t total; 48 | 49 | total = 0; 50 | 51 | while (len > 0) { 52 | cc = safe_read(fd, buf, len); 53 | 54 | if (cc < 0) 55 | return cc; /* read() returns -1 on failure. */ 56 | 57 | if (cc == 0) 58 | break; 59 | 60 | buf = ((char *)buf) + cc; 61 | total += cc; 62 | len -= cc; 63 | } 64 | 65 | return total; 66 | } 67 | 68 | ssize_t safe_read(int fd, void *buf, size_t count) 69 | { 70 | ssize_t n; 71 | 72 | do { 73 | n = read(fd, buf, count); 74 | } while (n < 0 && errno == EINTR); 75 | 76 | return n; 77 | } 78 | 79 | /* END CODE */ 80 | -------------------------------------------------------------------------------- /libopkg/pkg_vec.h: -------------------------------------------------------------------------------- 1 | /* pkg_vec.h - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_VEC_H 19 | #define PKG_VEC_H 20 | 21 | typedef struct pkg pkg_t; 22 | typedef struct abstract_pkg abstract_pkg_t; 23 | typedef struct pkg_vec pkg_vec_t; 24 | typedef struct abstract_pkg_vec abstract_pkg_vec_t; 25 | 26 | #include "opkg_conf.h" 27 | 28 | struct pkg_vec { 29 | pkg_t **pkgs; 30 | unsigned int len; 31 | }; 32 | 33 | struct abstract_pkg_vec { 34 | abstract_pkg_t **pkgs; 35 | unsigned int len; 36 | }; 37 | 38 | pkg_vec_t *pkg_vec_alloc(void); 39 | void pkg_vec_free(pkg_vec_t * vec); 40 | 41 | void pkg_vec_insert_merge(pkg_vec_t * vec, pkg_t * pkg, int set_status); 42 | void pkg_vec_insert(pkg_vec_t * vec, const pkg_t * pkg); 43 | int pkg_vec_contains(pkg_vec_t * vec, pkg_t * apkg); 44 | 45 | typedef int (*compare_fcn_t) (const void *, const void *); 46 | void pkg_vec_sort(pkg_vec_t * vec, compare_fcn_t compar); 47 | 48 | int pkg_vec_clear_marks(pkg_vec_t * vec); 49 | int pkg_vec_mark_if_matches(pkg_vec_t * vec, const char *pattern); 50 | 51 | abstract_pkg_vec_t *abstract_pkg_vec_alloc(void); 52 | void abstract_pkg_vec_free(abstract_pkg_vec_t * vec); 53 | void abstract_pkg_vec_insert(abstract_pkg_vec_t * vec, abstract_pkg_t * pkg); 54 | abstract_pkg_t *abstract_pkg_vec_get(abstract_pkg_vec_t * vec, int i); 55 | int abstract_pkg_vec_contains(abstract_pkg_vec_t * vec, abstract_pkg_t * apkg); 56 | void abstract_pkg_vec_sort(abstract_pkg_vec_t * vec, compare_fcn_t compar); 57 | 58 | int pkg_compare_names(const void *p1, const void *p2); 59 | #endif 60 | -------------------------------------------------------------------------------- /libopkg/void_list.h: -------------------------------------------------------------------------------- 1 | /* void_list.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef VOID_LIST_H 19 | #define VOID_LIST_H 20 | 21 | #include "list.h" 22 | 23 | typedef struct void_list_elt void_list_elt_t; 24 | struct void_list_elt { 25 | struct list_head node; 26 | void *data; 27 | }; 28 | 29 | typedef struct void_list void_list_t; 30 | struct void_list { 31 | struct list_head head; 32 | }; 33 | 34 | static inline int void_list_empty(void_list_t * list) 35 | { 36 | return list_empty(&list->head); 37 | } 38 | 39 | void void_list_elt_init(void_list_elt_t * elt, void *data); 40 | void void_list_elt_deinit(void_list_elt_t * elt); 41 | 42 | void void_list_init(void_list_t * list); 43 | void void_list_deinit(void_list_t * list); 44 | 45 | void void_list_append(void_list_t * list, void *data); 46 | void void_list_push(void_list_t * list, void *data); 47 | void_list_elt_t *void_list_pop(void_list_t * list); 48 | 49 | void *void_list_remove(void_list_t * list, void_list_elt_t ** iter); 50 | /* remove element containing elt data, using cmp(elt->data, target_data) == 0. */ 51 | typedef int (*void_list_cmp_t) (const void *, const void *); 52 | void *void_list_remove_elt(void_list_t * list, const void *target_data, 53 | void_list_cmp_t cmp); 54 | 55 | void_list_elt_t *void_list_first(void_list_t * list); 56 | void_list_elt_t *void_list_prev(void_list_t * list, void_list_elt_t * node); 57 | void_list_elt_t *void_list_next(void_list_t * list, void_list_elt_t * node); 58 | void_list_elt_t *void_list_last(void_list_t * list); 59 | 60 | void void_list_purge(void_list_t * list); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /libbb/mode_string.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) many different people. If you wrote this, please 6 | * acknowledge your work. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 | * USA 22 | */ 23 | 24 | #include 25 | #include "libbb.h" 26 | 27 | #define TYPEINDEX(mode) (((mode) >> 12) & 0x0f) 28 | #define TYPECHAR(mode) ("0pcCd?bB-?l?s???" [TYPEINDEX(mode)]) 29 | 30 | /* The special bits. If set, display SMODE0/1 instead of MODE0/1 */ 31 | static const mode_t SBIT[] = { 32 | 0, 0, S_ISUID, 33 | 0, 0, S_ISGID, 34 | 0, 0, S_ISVTX 35 | }; 36 | 37 | /* The 9 mode bits to test */ 38 | static const mode_t MBIT[] = { 39 | S_IRUSR, S_IWUSR, S_IXUSR, 40 | S_IRGRP, S_IWGRP, S_IXGRP, 41 | S_IROTH, S_IWOTH, S_IXOTH 42 | }; 43 | 44 | static const char MODE1[] = "rwxrwxrwx"; 45 | static const char MODE0[] = "---------"; 46 | static const char SMODE1[] = "..s..s..t"; 47 | static const char SMODE0[] = "..S..S..T"; 48 | 49 | /* 50 | * Return the standard ls-like mode string from a file mode. 51 | * This is static and so is overwritten on each call. 52 | */ 53 | const char *mode_string(int mode) 54 | { 55 | static char buf[12]; 56 | 57 | int i; 58 | 59 | buf[0] = TYPECHAR(mode); 60 | for (i = 0; i < 9; i++) { 61 | if (mode & SBIT[i]) 62 | buf[i + 1] = (mode & MBIT[i]) ? SMODE1[i] : SMODE0[i]; 63 | else 64 | buf[i + 1] = (mode & MBIT[i]) ? MODE1[i] : MODE0[i]; 65 | } 66 | return buf; 67 | } 68 | 69 | /* END CODE */ 70 | /* 71 | Local Variables: 72 | c-file-style: "linux" 73 | c-basic-offset: 4 74 | tab-width: 4 75 | End: 76 | */ 77 | -------------------------------------------------------------------------------- /libopkg/opkg.h: -------------------------------------------------------------------------------- 1 | /* opkg.h - the opkg package management system 2 | 3 | Thomas Wood 4 | 5 | Copyright (C) 2008 OpenMoko Inc 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_H 19 | #define OPKG_H 20 | 21 | #include "pkg.h" 22 | #include "opkg_message.h" 23 | 24 | typedef struct _opkg_progress_data_t opkg_progress_data_t; 25 | 26 | typedef void (*opkg_progress_callback_t) (const opkg_progress_data_t * progress, 27 | void *user_data); 28 | typedef void (*opkg_package_callback_t) (pkg_t * pkg, void *user_data); 29 | 30 | enum _opkg_action_t { 31 | OPKG_INSTALL, 32 | OPKG_REMOVE, 33 | OPKG_DOWNLOAD 34 | }; 35 | 36 | struct _opkg_progress_data_t { 37 | int percentage; 38 | int action; 39 | pkg_t *pkg; 40 | }; 41 | 42 | int opkg_new(void); 43 | void opkg_free(void); 44 | int opkg_re_read_config_files(void); 45 | void opkg_get_option(char *option, void **value); 46 | void opkg_set_option(char *option, void *value); 47 | 48 | int opkg_install_package(const char *package_name, 49 | opkg_progress_callback_t callback, void *user_data); 50 | int opkg_remove_package(const char *package_name, 51 | opkg_progress_callback_t callback, void *user_data); 52 | int opkg_upgrade_package(const char *package_name, 53 | opkg_progress_callback_t callback, void *user_data); 54 | int opkg_upgrade_all(opkg_progress_callback_t callback, void *user_data); 55 | int opkg_update_package_lists(opkg_progress_callback_t callback, 56 | void *user_data); 57 | 58 | int opkg_list_packages(opkg_package_callback_t callback, void *user_data); 59 | int opkg_list_upgradable_packages(opkg_package_callback_t callback, 60 | void *user_data); 61 | pkg_t *opkg_find_package(const char *name, const char *version, 62 | const char *architecture, const char *repository); 63 | 64 | int opkg_repository_accessibility_check(void); 65 | 66 | #endif /* OPKG_H */ 67 | -------------------------------------------------------------------------------- /libbb/xfuncs.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) 1999,2000,2001 by Erik Andersen 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "libbb.h" 27 | 28 | extern void *xmalloc(size_t size) 29 | { 30 | void *ptr = malloc(size); 31 | if (ptr == NULL && size != 0) 32 | perror_msg_and_die("malloc"); 33 | return ptr; 34 | } 35 | 36 | extern void *xrealloc(void *ptr, size_t size) 37 | { 38 | ptr = realloc(ptr, size); 39 | if (ptr == NULL && size != 0) 40 | perror_msg_and_die("realloc"); 41 | return ptr; 42 | } 43 | 44 | extern void *xcalloc(size_t nmemb, size_t size) 45 | { 46 | void *ptr = calloc(nmemb, size); 47 | if (ptr == NULL && nmemb != 0 && size != 0) 48 | perror_msg_and_die("calloc"); 49 | return ptr; 50 | } 51 | 52 | extern char *xstrdup(const char *s) 53 | { 54 | char *t; 55 | 56 | if (s == NULL) 57 | return NULL; 58 | 59 | t = strdup(s); 60 | 61 | if (t == NULL) 62 | perror_msg_and_die("strdup"); 63 | 64 | return t; 65 | } 66 | 67 | extern char *xstrndup(const char *s, int n) 68 | { 69 | char *t; 70 | 71 | if (s == NULL) 72 | error_msg_and_die("xstrndup bug"); 73 | 74 | t = xmalloc(++n); 75 | 76 | return safe_strncpy(t, s, n); 77 | } 78 | 79 | FILE *xfopen(const char *path, const char *mode) 80 | { 81 | FILE *fp; 82 | if ((fp = fopen(path, mode)) == NULL) 83 | perror_msg_and_die("%s", path); 84 | return fp; 85 | } 86 | 87 | /* END CODE */ 88 | /* 89 | Local Variables: 90 | c-file-style: "linux" 91 | c-basic-offset: 4 92 | tab-width: 4 93 | End: 94 | */ 95 | -------------------------------------------------------------------------------- /libopkg/pkg_dest.c: -------------------------------------------------------------------------------- 1 | /* pkg_dest.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | 20 | #include "pkg_dest.h" 21 | #include "file_util.h" 22 | #include "sprintf_alloc.h" 23 | #include "opkg_conf.h" 24 | #include "opkg_cmd.h" 25 | #include "opkg_defines.h" 26 | #include "libbb/libbb.h" 27 | 28 | int pkg_dest_init(pkg_dest_t * dest, const char *name, const char *root_dir, 29 | const char *lists_dir) 30 | { 31 | dest->name = xstrdup(name); 32 | 33 | /* Guarantee that dest->root_dir ends with a '/' */ 34 | if (root_dir[strlen(root_dir) - 1] == '/') { 35 | dest->root_dir = xstrdup(root_dir); 36 | } else { 37 | sprintf_alloc(&dest->root_dir, "%s/", root_dir); 38 | } 39 | file_mkdir_hier(dest->root_dir, 0755); 40 | 41 | sprintf_alloc(&dest->opkg_dir, "%s%s", 42 | dest->root_dir, OPKG_STATE_DIR_PREFIX); 43 | file_mkdir_hier(dest->opkg_dir, 0755); 44 | 45 | if (lists_dir[0] == '/') 46 | sprintf_alloc(&dest->lists_dir, "%s", lists_dir); 47 | else 48 | sprintf_alloc(&dest->lists_dir, "/%s", lists_dir); 49 | 50 | file_mkdir_hier(dest->lists_dir, 0755); 51 | 52 | sprintf_alloc(&dest->info_dir, "%s/%s", 53 | dest->opkg_dir, OPKG_INFO_DIR_SUFFIX); 54 | file_mkdir_hier(dest->info_dir, 0755); 55 | 56 | sprintf_alloc(&dest->status_file_name, "%s/%s", 57 | dest->opkg_dir, OPKG_STATUS_FILE_SUFFIX); 58 | 59 | return 0; 60 | } 61 | 62 | void pkg_dest_deinit(pkg_dest_t * dest) 63 | { 64 | free(dest->name); 65 | dest->name = NULL; 66 | 67 | free(dest->root_dir); 68 | dest->root_dir = NULL; 69 | 70 | free(dest->opkg_dir); 71 | dest->opkg_dir = NULL; 72 | 73 | free(dest->lists_dir); 74 | dest->lists_dir = NULL; 75 | 76 | free(dest->info_dir); 77 | dest->info_dir = NULL; 78 | 79 | free(dest->status_file_name); 80 | dest->status_file_name = NULL; 81 | 82 | dest->root_dir = NULL; 83 | } 84 | -------------------------------------------------------------------------------- /libopkg/pkg_hash.h: -------------------------------------------------------------------------------- 1 | /* pkg_hash.h - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_HASH_H 19 | #define PKG_HASH_H 20 | 21 | #include "pkg.h" 22 | #include "pkg_src.h" 23 | #include "pkg_dest.h" 24 | #include "hash_table.h" 25 | 26 | void pkg_hash_init(void); 27 | void pkg_hash_deinit(void); 28 | 29 | void pkg_hash_fetch_available(pkg_vec_t * available); 30 | 31 | int pkg_hash_add_from_file(const char *file_name, pkg_src_t * src, 32 | pkg_dest_t * dest, int is_status_file, int state_flags, 33 | void (*cb)(pkg_t *, void *), void *priv); 34 | int pkg_hash_load_feeds(int state_flags, void (*cb)(pkg_t *, void *), void *priv); 35 | int pkg_hash_load_status_files(void (*cb)(pkg_t *, void *), void *priv); 36 | int pkg_hash_load_package_details(void); 37 | 38 | void hash_insert_pkg(pkg_t * pkg, int set_status); 39 | 40 | static inline abstract_pkg_t *abstract_pkg_fetch_by_name(const char *pkg_name) 41 | { 42 | return (abstract_pkg_t *) hash_table_get(&conf->pkg_hash, pkg_name); 43 | } 44 | 45 | abstract_pkg_t *ensure_abstract_pkg_by_name(const char *pkg_name); 46 | void pkg_hash_fetch_all_installed(pkg_vec_t * installed); 47 | pkg_t *pkg_hash_fetch_by_name_version(const char *pkg_name, 48 | const char *version); 49 | pkg_t *pkg_hash_fetch_best_installation_candidate(abstract_pkg_t * apkg, 50 | int (*constraint_fcn) (pkg_t * 51 | pkg, 52 | void 53 | *data), 54 | void *cdata, int quiet); 55 | pkg_t *pkg_hash_fetch_best_installation_candidate_by_name(const char *name); 56 | pkg_t *pkg_hash_fetch_installed_by_name(const char *pkg_name); 57 | pkg_t *pkg_hash_fetch_installed_by_name_dest(const char *pkg_name, 58 | pkg_dest_t * dest); 59 | 60 | void file_hash_remove(const char *file_name); 61 | pkg_t *file_hash_get_file_owner(const char *file_name); 62 | void file_hash_set_file_owner(const char *file_name, pkg_t * pkg); 63 | 64 | #endif 65 | -------------------------------------------------------------------------------- /libbb/make_directory.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Mini make_directory implementation for busybox 4 | * 5 | * Copyright (C) 2001 Matt Kraai. 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | * General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 | * 21 | */ 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "libbb.h" 32 | 33 | /* Create the directory PATH with mode MODE, or the default if MODE is -1. 34 | * Also create parent directories as necessary if flags contains 35 | * FILEUTILS_RECUR. */ 36 | 37 | int make_directory(const char *path, long mode, int flags) 38 | { 39 | if (!(flags & FILEUTILS_RECUR)) { 40 | if (mkdir(path, 0777) < 0) { 41 | perror_msg("Cannot create directory `%s'", path); 42 | return -1; 43 | } 44 | 45 | if (mode != -1 && chmod(path, mode) < 0) { 46 | perror_msg("Cannot set permissions of directory `%s'", 47 | path); 48 | return -1; 49 | } 50 | } else { 51 | struct stat st; 52 | 53 | if (stat(path, &st) < 0 && errno == ENOENT) { 54 | int status; 55 | char *pathcopy, *parent, *parentcopy; 56 | mode_t mask; 57 | 58 | mask = umask(0); 59 | umask(mask); 60 | 61 | /* dirname is unsafe, it may both modify the 62 | memory of the path argument and may return 63 | a pointer to static memory, which can then 64 | be modified by consequtive calls to dirname */ 65 | 66 | pathcopy = xstrdup(path); 67 | parent = dirname(pathcopy); 68 | parentcopy = xstrdup(parent); 69 | status = make_directory(parentcopy, (0777 & ~mask) 70 | | 0300, FILEUTILS_RECUR); 71 | free(pathcopy); 72 | free(parentcopy); 73 | 74 | if (status < 0 || make_directory(path, mode, 0) < 0) 75 | return -1; 76 | } 77 | } 78 | 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /tests/opkg_hash_test.c: -------------------------------------------------------------------------------- 1 | /* opkg_hash_test.c - the itsy package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | int main(int argc, char *argv[]) 25 | { 26 | opkg_conf_t conf; 27 | hash_table_t *hash = &conf.pkg_hash; 28 | pkg_vec_t *pkg_vec; 29 | 30 | if (argc < 3) { 31 | fprintf(stderr, 32 | "Usage: %s [pkg_name...]\n", 33 | argv[0]); 34 | exit(1); 35 | } 36 | pkg_hash_init("test", hash, 1024); 37 | 38 | pkg_hash_add_from_file(&conf, argv[1], NULL, NULL, 0, NULL, NULL); 39 | pkg_hash_add_from_file(&conf, argv[2], NULL, NULL, 0, NULL, NULL); 40 | 41 | if (argc < 4) { 42 | pkg_print_info(pkg_hash_fetch_by_name_version 43 | (hash, "libc6", "2.2.3-2"), stdout); 44 | /* for(i = 0; i < pkg_vec->len; i++) 45 | pkg_print(pkg_vec->pkgs[i], stdout); 46 | */ 47 | } else { 48 | int i, j, k; 49 | char **unresolved; 50 | 51 | pkg_vec_t *dep_vec; 52 | for (i = 3; i < argc; i++) { 53 | pkg_vec = pkg_vec_fetch_by_name(hash, argv[i]); 54 | if (pkg_vec == NULL) { 55 | fprintf(stderr, 56 | "*** WARNING: Unknown package: %s\n\n", 57 | argv[i]); 58 | continue; 59 | } 60 | 61 | for (j = 0; j < pkg_vec->len; j++) { 62 | pkg_print_info(pkg_vec->pkgs[j], stdout); 63 | dep_vec = pkg_vec_alloc(); 64 | pkg_hash_fetch_unsatisfied_dependencies(&conf, 65 | pkg_vec-> 66 | pkgs[j], 67 | dep_vec, 68 | &unresolved); 69 | if (dep_vec) { 70 | fprintf(stderr, 71 | "and the unsatisfied dependencies are:\n"); 72 | for (k = 0; k < dep_vec->len; k++) { 73 | fprintf(stderr, 74 | "%s version %s\n", 75 | dep_vec->pkgs[k]->name, 76 | dep_vec->pkgs[k]-> 77 | version); 78 | } 79 | } 80 | 81 | fputs("", stdout); 82 | 83 | } 84 | } 85 | } 86 | 87 | pkg_hash_deinit(hash); 88 | 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /libopkg/nv_pair_list.c: -------------------------------------------------------------------------------- 1 | /* nv_pair_list.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "nv_pair.h" 19 | #include "void_list.h" 20 | #include "nv_pair_list.h" 21 | #include "libbb/libbb.h" 22 | 23 | void nv_pair_list_init(nv_pair_list_t * list) 24 | { 25 | void_list_init((void_list_t *) list); 26 | } 27 | 28 | void nv_pair_list_deinit(nv_pair_list_t * list) 29 | { 30 | nv_pair_list_elt_t *pos; 31 | nv_pair_t *nv_pair; 32 | 33 | while (!void_list_empty(list)) { 34 | pos = nv_pair_list_pop(list); 35 | if (!pos) 36 | break; 37 | nv_pair = (nv_pair_t *) pos->data; 38 | nv_pair_deinit(nv_pair); 39 | /* malloced in nv_pair_list_append */ 40 | free(nv_pair); 41 | pos->data = NULL; 42 | free(pos); 43 | } 44 | void_list_deinit((void_list_t *) list); 45 | } 46 | 47 | nv_pair_t *nv_pair_list_append(nv_pair_list_t * list, const char *name, 48 | const char *value) 49 | { 50 | /* freed in nv_pair_list_deinit */ 51 | nv_pair_t *nv_pair = xcalloc(1, sizeof(nv_pair_t)); 52 | nv_pair_init(nv_pair, name, value); 53 | void_list_append((void_list_t *) list, nv_pair); 54 | 55 | return nv_pair; 56 | } 57 | 58 | void nv_pair_list_push(nv_pair_list_t * list, nv_pair_t * data) 59 | { 60 | void_list_push((void_list_t *) list, data); 61 | } 62 | 63 | nv_pair_list_elt_t *nv_pair_list_pop(nv_pair_list_t * list) 64 | { 65 | return (nv_pair_list_elt_t *) void_list_pop((void_list_t *) list); 66 | } 67 | 68 | char *nv_pair_list_find(nv_pair_list_t * list, char *name) 69 | { 70 | nv_pair_list_elt_t *iter; 71 | nv_pair_t *nv_pair; 72 | 73 | list_for_each_entry(iter, &list->head, node) { 74 | nv_pair = (nv_pair_t *) iter->data; 75 | if (strcmp(nv_pair->name, name) == 0) { 76 | return nv_pair->value; 77 | } 78 | } 79 | return NULL; 80 | } 81 | 82 | nv_pair_list_elt_t *nv_pair_list_first(nv_pair_list_t * list) 83 | { 84 | return (nv_pair_list_elt_t *) void_list_first((void_list_t *) list); 85 | } 86 | 87 | nv_pair_list_elt_t *nv_pair_list_next(nv_pair_list_t * list, 88 | nv_pair_list_elt_t * node) 89 | { 90 | return (nv_pair_list_elt_t *) void_list_next((void_list_t *) list, 91 | (void_list_elt_t *) node); 92 | } 93 | -------------------------------------------------------------------------------- /libopkg/str_list.c: -------------------------------------------------------------------------------- 1 | /* str_list.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "str_list.h" 19 | #include "libbb/libbb.h" 20 | 21 | void str_list_elt_init(str_list_elt_t * elt, char *data) 22 | { 23 | void_list_elt_init((void_list_elt_t *) elt, data); 24 | } 25 | 26 | void str_list_elt_deinit(str_list_elt_t * elt) 27 | { 28 | if (elt->data) 29 | free(elt->data); 30 | void_list_elt_deinit((void_list_elt_t *) elt); 31 | } 32 | 33 | str_list_t *str_list_alloc() 34 | { 35 | str_list_t *list = xcalloc(1, sizeof(str_list_t)); 36 | str_list_init(list); 37 | return list; 38 | } 39 | 40 | void str_list_init(str_list_t * list) 41 | { 42 | void_list_init((void_list_t *) list); 43 | } 44 | 45 | void str_list_deinit(str_list_t * list) 46 | { 47 | str_list_elt_t *elt; 48 | while (!void_list_empty(list)) { 49 | elt = str_list_first(list); 50 | if (!elt) 51 | return; 52 | list_del_init(&elt->node); 53 | free(elt->data); 54 | elt->data = NULL; 55 | free(elt); 56 | } 57 | } 58 | 59 | void str_list_append(str_list_t * list, char *data) 60 | { 61 | void_list_append((void_list_t *) list, xstrdup(data)); 62 | } 63 | 64 | str_list_elt_t *str_list_pop(str_list_t * list) 65 | { 66 | return (str_list_elt_t *) void_list_pop((void_list_t *) list); 67 | } 68 | 69 | void str_list_remove(str_list_t * list, str_list_elt_t ** iter) 70 | { 71 | char *str = void_list_remove((void_list_t *) list, 72 | (void_list_elt_t **) iter); 73 | 74 | if (str) 75 | free(str); 76 | } 77 | 78 | void str_list_remove_elt(str_list_t * list, const char *target_str) 79 | { 80 | char *str = void_list_remove_elt((void_list_t *) list, 81 | (void *)target_str, 82 | (void_list_cmp_t) strcmp); 83 | if (str) 84 | free(str); 85 | } 86 | 87 | str_list_elt_t *str_list_first(str_list_t * list) 88 | { 89 | return (str_list_elt_t *) void_list_first((void_list_t *) list); 90 | } 91 | 92 | str_list_elt_t *str_list_next(str_list_t * list, str_list_elt_t * node) 93 | { 94 | return (str_list_elt_t *) void_list_next((void_list_t *) list, 95 | (void_list_elt_t *) node); 96 | } 97 | 98 | void str_list_purge(str_list_t * list) 99 | { 100 | str_list_deinit(list); 101 | free(list); 102 | } 103 | -------------------------------------------------------------------------------- /libopkg/pkg_extract.c: -------------------------------------------------------------------------------- 1 | /* pkg_extract.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | 20 | #include "pkg_extract.h" 21 | #include "libbb/libbb.h" 22 | #include "file_util.h" 23 | #include "sprintf_alloc.h" 24 | 25 | int pkg_extract_control_file_to_stream(pkg_t * pkg, FILE * stream) 26 | { 27 | int err; 28 | deb_extract(pkg_get_string(pkg, PKG_LOCAL_FILENAME), stream, 29 | extract_control_tar_gz 30 | | extract_to_stream, NULL, "control", &err); 31 | return err; 32 | } 33 | 34 | int 35 | pkg_extract_control_files_to_dir_with_prefix(pkg_t * pkg, const char *dir, 36 | const char *prefix) 37 | { 38 | int err; 39 | char *dir_with_prefix; 40 | 41 | sprintf_alloc(&dir_with_prefix, "%s/%s", dir, prefix); 42 | 43 | deb_extract(pkg_get_string(pkg, PKG_LOCAL_FILENAME), stderr, 44 | extract_control_tar_gz 45 | | extract_all_to_fs | extract_preserve_date 46 | | extract_unconditional, dir_with_prefix, NULL, &err); 47 | 48 | free(dir_with_prefix); 49 | return err; 50 | } 51 | 52 | int pkg_extract_control_files_to_dir(pkg_t * pkg, const char *dir) 53 | { 54 | return pkg_extract_control_files_to_dir_with_prefix(pkg, dir, ""); 55 | } 56 | 57 | int pkg_extract_data_files_to_dir(pkg_t * pkg, const char *dir) 58 | { 59 | int err; 60 | 61 | deb_extract(pkg_get_string(pkg, PKG_LOCAL_FILENAME), stderr, 62 | extract_data_tar_gz 63 | | extract_all_to_fs | extract_preserve_date 64 | | extract_unconditional, dir, NULL, &err); 65 | 66 | return err; 67 | } 68 | 69 | int pkg_extract_data_file_names_to_stream(pkg_t * pkg, FILE * stream) 70 | { 71 | int err; 72 | 73 | /* XXX: DPKG_INCOMPATIBILITY: deb_extract will extract all of the 74 | data file names with a '.' as the first character. I've taught 75 | opkg how to cope with the presence or absence of the '.', but 76 | this may trip up dpkg. 77 | 78 | For all I know, this could actually be a bug in opkg-build. So, 79 | I'll have to try installing some .debs and comparing the *.list 80 | files. 81 | 82 | If we wanted to, we could workaround the deb_extract behavior 83 | right here, by writing to a tmpfile, then munging things as we 84 | wrote to the actual stream. */ 85 | 86 | deb_extract(pkg_get_string(pkg, PKG_LOCAL_FILENAME), stream, 87 | extract_quiet | extract_data_tar_gz | extract_list, 88 | NULL, NULL, &err); 89 | 90 | return err; 91 | } 92 | -------------------------------------------------------------------------------- /tests/regress/opk.py: -------------------------------------------------------------------------------- 1 | import tarfile, os 2 | import cfg 3 | 4 | class Opk: 5 | valid_control_fields = ["Package", "Version", "Depends", "Provides",\ 6 | "Replaces", "Conflicts", "Suggests", "Recommends",\ 7 | "Section", "Architecture", "Maintainer", "MD5Sum",\ 8 | "Size", "InstalledSize", "Filename", "Source",\ 9 | "Description", "OE", "Homepage", "Priority",\ 10 | "Conffiles"] 11 | 12 | def __init__(self, **control): 13 | for k in control.keys(): 14 | if k not in self.valid_control_fields: 15 | raise Exception("Invalid control field: " 16 | "{}".format(k)) 17 | self.control = control 18 | 19 | def write(self, tar_not_ar=False, data_files=None): 20 | filename = "{Package}_{Version}_{Architecture}.opk"\ 21 | .format(**self.control) 22 | if os.path.exists(filename): 23 | os.unlink(filename) 24 | if os.path.exists("control"): 25 | os.unlink("control") 26 | if os.path.exists("control.tar.gz"): 27 | os.unlink("control.tar.gz") 28 | if os.path.exists("data.tar.gz"): 29 | os.unlink("data.tar.gz") 30 | 31 | f = open("control", "w") 32 | for k in self.control.keys(): 33 | f.write("{}: {}\n".format(k, self.control[k])) 34 | f.close() 35 | 36 | tar = tarfile.open("control.tar.gz", "w:gz") 37 | tar.add("control") 38 | tar.close() 39 | 40 | tar = tarfile.open("data.tar.gz", "w:gz") 41 | if data_files: 42 | for df in data_files: 43 | tar.add(df) 44 | tar.close() 45 | 46 | 47 | if tar_not_ar: 48 | tar = tarfile.open(filename, "w:gz") 49 | tar.add("control.tar.gz") 50 | tar.add("data.tar.gz") 51 | tar.close() 52 | else: 53 | os.system("ar q {} control.tar.gz data.tar.gz \ 54 | 2>/dev/null".format(filename)) 55 | 56 | os.unlink("control") 57 | os.unlink("control.tar.gz") 58 | os.unlink("data.tar.gz") 59 | 60 | class OpkGroup: 61 | def __init__(self): 62 | self.opk_list = [] 63 | 64 | def add(self, **control): 65 | self.opk_list.append(Opk(**control)) 66 | 67 | def write_opk(self, tar_not_ar=False): 68 | for o in self.opk_list: 69 | o.write(tar_not_ar) 70 | 71 | def write_list(self, filename="Packages"): 72 | f = open(filename, "w") 73 | for opk in self.opk_list: 74 | for k in opk.control.keys(): 75 | f.write("{}: {}\n".format(k, opk.control[k])) 76 | f.write("Filename: {Package}_{Version}_{Architecture}" 77 | ".opk\n".format(**opk.control)) 78 | f.write("\n") 79 | f.close() 80 | 81 | 82 | def regress_init(): 83 | """ 84 | Initialisation and sanity checking. 85 | """ 86 | 87 | if not os.access(cfg.opkgcl, os.X_OK): 88 | print("Cannot exec {}".format(cfg.opkgcl)) 89 | exit(False) 90 | 91 | os.chdir(cfg.opkdir) 92 | 93 | os.system("rm -fr {}".format(cfg.offline_root)) 94 | 95 | os.makedirs("{}/usr/lib/opkg".format(cfg.offline_root)) 96 | os.makedirs("{}/etc/opkg".format(cfg.offline_root)) 97 | 98 | f = open("{}/etc/opkg/opkg.conf".format(cfg.offline_root), "w") 99 | f.write("arch all 1\n") 100 | f.write("src test file:{}\n".format(cfg.opkdir)) 101 | f.close() 102 | -------------------------------------------------------------------------------- /libopkg/opkg_message.c: -------------------------------------------------------------------------------- 1 | /* opkg_message.c - the opkg package management system 2 | 3 | Copyright (C) 2009 Ubiq Technologies 4 | Copyright (C) 2003 Daniele Nicolodi 5 | 6 | This program is free software; you can redistribute it and/or 7 | modify it under the terms of the GNU General Public License as 8 | published by the Free Software Foundation; either version 2, or (at 9 | your option) any later version. 10 | 11 | This program is distributed in the hope that it will be useful, but 12 | WITHOUT ANY WARRANTY; without even the implied warranty of 13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | General Public License for more details. 15 | */ 16 | 17 | #include 18 | 19 | #include "opkg_conf.h" 20 | #include "opkg_message.h" 21 | #include "libbb/libbb.h" 22 | 23 | struct errlist { 24 | char *errmsg; 25 | struct errlist *next; 26 | }; 27 | 28 | static struct errlist *error_list_head, *error_list_tail; 29 | 30 | static void push_error_list(char *msg) 31 | { 32 | struct errlist *e; 33 | 34 | e = xcalloc(1, sizeof(struct errlist)); 35 | e->errmsg = xstrdup(msg); 36 | e->next = NULL; 37 | 38 | if (error_list_head) { 39 | error_list_tail->next = e; 40 | error_list_tail = e; 41 | } else { 42 | error_list_head = error_list_tail = e; 43 | } 44 | } 45 | 46 | void free_error_list(void) 47 | { 48 | struct errlist *err, *err_tmp; 49 | 50 | err = error_list_head; 51 | while (err != NULL) { 52 | free(err->errmsg); 53 | err_tmp = err; 54 | err = err->next; 55 | free(err_tmp); 56 | } 57 | } 58 | 59 | void print_error_list(void) 60 | { 61 | struct errlist *err = error_list_head; 62 | 63 | if (err) { 64 | fprintf(stderr, "Collected errors:\n"); 65 | /* Here we print the errors collected and free the list */ 66 | while (err != NULL) { 67 | fprintf(stderr, " * %s", err->errmsg); 68 | err = err->next; 69 | } 70 | } 71 | } 72 | 73 | void opkg_message(message_level_t level, const char *fmt, ...) 74 | { 75 | va_list ap; 76 | 77 | if (conf->verbosity < level) 78 | return; 79 | 80 | if (conf->opkg_vmessage) { 81 | /* Pass the message to libopkg users. */ 82 | va_start(ap, fmt); 83 | conf->opkg_vmessage(level, fmt, ap); 84 | va_end(ap); 85 | return; 86 | } 87 | 88 | va_start(ap, fmt); 89 | 90 | if (level == ERROR) { 91 | #define MSG_LEN 4096 92 | char msg[MSG_LEN]; 93 | int ret; 94 | ret = vsnprintf(msg, MSG_LEN, fmt, ap); 95 | if (ret < 0) { 96 | fprintf(stderr, "%s: encountered an output or encoding" 97 | " error during vsnprintf.\n", __FUNCTION__); 98 | va_end(ap); 99 | exit(EXIT_FAILURE); 100 | } 101 | if (ret >= MSG_LEN) { 102 | fprintf(stderr, "%s: Message truncated.\n", 103 | __FUNCTION__); 104 | } 105 | push_error_list(msg); 106 | } else { 107 | if (vprintf(fmt, ap) < 0) { 108 | fprintf(stderr, "%s: encountered an output or encoding" 109 | " error during vprintf.\n", __FUNCTION__); 110 | exit(EXIT_FAILURE); 111 | } 112 | } 113 | 114 | va_end(ap); 115 | } 116 | -------------------------------------------------------------------------------- /libopkg/pkg_depends.h: -------------------------------------------------------------------------------- 1 | /* pkg_depends.h - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_DEPENDS_H 19 | #define PKG_DEPENDS_H 20 | 21 | #include "pkg.h" 22 | #include "pkg_hash.h" 23 | 24 | enum depend_type { 25 | UNSPEC, 26 | PREDEPEND, 27 | DEPEND, 28 | CONFLICTS, 29 | GREEDY_DEPEND, 30 | RECOMMEND, 31 | SUGGEST 32 | }; 33 | typedef enum depend_type depend_type_t; 34 | 35 | enum version_constraint { 36 | NONE, 37 | EARLIER, 38 | EARLIER_EQUAL, 39 | EQUAL, 40 | LATER_EQUAL, 41 | LATER 42 | }; 43 | typedef enum version_constraint version_constraint_t; 44 | 45 | struct depend { 46 | version_constraint_t constraint; 47 | char *version; 48 | abstract_pkg_t *pkg; 49 | }; 50 | typedef struct depend depend_t; 51 | 52 | struct compound_depend { 53 | depend_type_t type; 54 | int possibility_count; 55 | struct depend **possibilities; 56 | }; 57 | typedef struct compound_depend compound_depend_t; 58 | 59 | void buildProvides(abstract_pkg_t * ab_pkg, pkg_t * pkg); 60 | void buildConflicts(pkg_t * pkg); 61 | void buildReplaces(abstract_pkg_t * ab_pkg, pkg_t * pkg); 62 | void buildDepends(pkg_t * pkg); 63 | 64 | void parse_deplist(pkg_t *pkg, enum depend_type type, char *list); 65 | 66 | abstract_pkg_t **init_providelist(pkg_t *pkg, int *count); 67 | void parse_providelist(pkg_t *pkg, char *list); 68 | void parse_replacelist(pkg_t *pkg, char *list); 69 | 70 | /** 71 | * pkg_replaces returns 1 if pkg->replaces contains one of replacee's provides and 0 72 | * otherwise. 73 | */ 74 | int pkg_replaces(pkg_t * pkg, pkg_t * replacee); 75 | 76 | /** 77 | * pkg_conflicts_abstract returns 1 if pkg->conflicts contains conflictee provides and 0 78 | * otherwise. 79 | */ 80 | int pkg_conflicts_abstract(pkg_t * pkg, abstract_pkg_t * conflicts); 81 | 82 | /** 83 | * pkg_conflicts returns 1 if pkg->conflicts contains one of conflictee's provides and 0 84 | * otherwise. 85 | */ 86 | int pkg_conflicts(pkg_t * pkg, pkg_t * conflicts); 87 | 88 | char *pkg_depend_str(pkg_t * pkg, int index); 89 | void buildDependedUponBy(pkg_t * pkg, abstract_pkg_t * ab_pkg); 90 | int version_constraints_satisfied(depend_t * depends, pkg_t * pkg); 91 | int pkg_hash_fetch_unsatisfied_dependencies(pkg_t * pkg, pkg_vec_t * depends, 92 | char ***unresolved, int pre_check); 93 | pkg_vec_t *pkg_hash_fetch_conflicts(pkg_t * pkg); 94 | int pkg_dependence_satisfiable(depend_t * depend); 95 | const char *constraint_to_str(enum version_constraint c); 96 | 97 | compound_depend_t *pkg_get_depends(pkg_t *pkg, enum depend_type type); 98 | 99 | #endif 100 | -------------------------------------------------------------------------------- /libbb/parse_mode.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) many different people. If you wrote this, please 6 | * acknowledge your work. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 | * USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include "libbb.h" 27 | 28 | /* This function parses the sort of string you might pass 29 | * to chmod (i.e., [ugoa]{+|-|=}[rwxst] ) and returns the 30 | * correct mode described by the string. */ 31 | extern int parse_mode(const char *s, mode_t * theMode) 32 | { 33 | static const mode_t group_set[] = { 34 | S_ISUID | S_IRWXU, /* u */ 35 | S_ISGID | S_IRWXG, /* g */ 36 | S_IRWXO, /* o */ 37 | S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO /* a */ 38 | }; 39 | 40 | static const mode_t mode_set[] = { 41 | S_IRUSR | S_IRGRP | S_IROTH, /* r */ 42 | S_IWUSR | S_IWGRP | S_IWOTH, /* w */ 43 | S_IXUSR | S_IXGRP | S_IXOTH, /* x */ 44 | S_ISUID | S_ISGID, /* s */ 45 | S_ISVTX /* t */ 46 | }; 47 | 48 | static const char group_chars[] = "ugoa"; 49 | static const char mode_chars[] = "rwxst"; 50 | 51 | const char *p; 52 | 53 | mode_t andMode = 54 | S_ISVTX | S_ISUID | S_ISGID | S_IRWXU | S_IRWXG | S_IRWXO; 55 | mode_t orMode = 0; 56 | mode_t mode; 57 | mode_t groups; 58 | char type; 59 | char c; 60 | 61 | if (s == NULL) { 62 | return (FALSE); 63 | } 64 | 65 | do { 66 | mode = 0; 67 | groups = 0; 68 | NEXT_GROUP: 69 | if ((c = *s++) == '\0') { 70 | return -1; 71 | } 72 | for (p = group_chars; *p; p++) { 73 | if (*p == c) { 74 | groups |= group_set[(int)(p - group_chars)]; 75 | goto NEXT_GROUP; 76 | } 77 | } 78 | switch (c) { 79 | case '=': 80 | case '+': 81 | case '-': 82 | type = c; 83 | if (groups == 0) { /* The default is "all" */ 84 | groups |= S_ISUID | S_ISGID | S_ISVTX 85 | | S_IRWXU | S_IRWXG | S_IRWXO; 86 | } 87 | break; 88 | default: 89 | if ((c < '0') || (c > '7') || (mode | groups)) { 90 | return (FALSE); 91 | } else { 92 | *theMode = strtol(--s, NULL, 8); 93 | return (TRUE); 94 | } 95 | } 96 | 97 | NEXT_MODE: 98 | if (((c = *s++) != '\0') && (c != ',')) { 99 | for (p = mode_chars; *p; p++) { 100 | if (*p == c) { 101 | mode |= mode_set[(int)(p - mode_chars)]; 102 | goto NEXT_MODE; 103 | } 104 | } 105 | break; /* We're done so break out of loop. */ 106 | } 107 | switch (type) { 108 | case '=': 109 | andMode &= ~(groups); /* Now fall through. */ 110 | case '+': 111 | orMode |= mode & groups; 112 | break; 113 | case '-': 114 | andMode &= ~(mode & groups); 115 | orMode &= ~(mode & groups); 116 | break; 117 | } 118 | } while (c == ','); 119 | 120 | *theMode &= andMode; 121 | *theMode |= orMode; 122 | 123 | return TRUE; 124 | } 125 | 126 | /* END CODE */ 127 | /* 128 | Local Variables: 129 | c-file-style: "linux" 130 | c-basic-offset: 4 131 | tab-width: 4 132 | End: 133 | */ 134 | -------------------------------------------------------------------------------- /libopkg/opkg_conf.h: -------------------------------------------------------------------------------- 1 | /* opkg_conf.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef OPKG_CONF_H 19 | #define OPKG_CONF_H 20 | 21 | typedef struct opkg_conf opkg_conf_t; 22 | extern opkg_conf_t *conf; 23 | 24 | #include 25 | #include /* FNM_CASEFOLD */ 26 | 27 | #include "hash_table.h" 28 | #include "pkg_src_list.h" 29 | #include "pkg_dest_list.h" 30 | #include "nv_pair_list.h" 31 | 32 | #define OPKG_CONF_DEFAULT_TMP_DIR_BASE "/tmp" 33 | #define OPKG_CONF_TMP_DIR_SUFFIX "opkg-XXXXXX" 34 | #define OPKG_CONF_LISTS_DIR OPKG_STATE_DIR_PREFIX "/lists" 35 | 36 | #define OPKG_CONF_DEFAULT_CONF_FILE_DIR OPKGETCDIR"/opkg" 37 | 38 | #define OPKG_CONF_DEFAULT_VERIFY_PROGRAM "/usr/sbin/opkg-key" 39 | 40 | /* In case the config file defines no dest */ 41 | #define OPKG_CONF_DEFAULT_DEST_NAME "root" 42 | #define OPKG_CONF_DEFAULT_DEST_ROOT_DIR "/" 43 | 44 | #define OPKG_CONF_DEFAULT_HASH_LEN 1024 45 | 46 | struct opkg_conf { 47 | pkg_src_list_t pkg_src_list; 48 | pkg_dest_list_t pkg_dest_list; 49 | pkg_dest_list_t tmp_dest_list; 50 | nv_pair_list_t arch_list; 51 | 52 | int restrict_to_default_dest; 53 | pkg_dest_t *default_dest; 54 | char *dest_str; 55 | 56 | char *conf_file; 57 | 58 | char *tmp_dir; 59 | char *lists_dir; 60 | 61 | unsigned int pfm; /* package field mask */ 62 | 63 | /* For libopkg users to capture messages. */ 64 | void (*opkg_vmessage) (int, const char *fmt, va_list ap); 65 | 66 | /* options */ 67 | int autoremove; 68 | int force_depends; 69 | int force_defaults; 70 | int force_maintainer; 71 | int force_overwrite; 72 | int force_downgrade; 73 | int force_reinstall; 74 | int force_space; 75 | int force_removal_of_dependent_packages; 76 | int force_removal_of_essential_packages; 77 | int force_postinstall; 78 | int force_remove; 79 | int force_checksum; 80 | int check_signature; 81 | int force_signature; 82 | int no_check_certificate; 83 | int nodeps; /* do not follow dependencies */ 84 | int nocase; /* perform case insensitive matching */ 85 | char *offline_root; 86 | char *overlay_root; 87 | int query_all; 88 | int verbosity; 89 | char *verify_program; 90 | int noaction; 91 | int size; 92 | int strip_abi; 93 | int download_only; 94 | char *cache; 95 | 96 | /* proxy options */ 97 | char *http_proxy; 98 | char *http_timeout; 99 | char *https_proxy; 100 | char *ftp_proxy; 101 | char *no_proxy; 102 | char *proxy_user; 103 | char *proxy_passwd; 104 | 105 | char *signature_ca_file; 106 | char *signature_ca_path; 107 | 108 | hash_table_t pkg_hash; 109 | hash_table_t file_hash; 110 | hash_table_t obs_file_hash; 111 | }; 112 | 113 | enum opkg_option_type { 114 | OPKG_OPT_TYPE_BOOL, 115 | OPKG_OPT_TYPE_INT, 116 | OPKG_OPT_TYPE_STRING 117 | }; 118 | typedef enum opkg_option_type opkg_option_type_t; 119 | 120 | typedef struct opkg_option opkg_option_t; 121 | struct opkg_option { 122 | const char *name; 123 | const opkg_option_type_t type; 124 | void *const value; 125 | }; 126 | 127 | int opkg_conf_init(void); 128 | int opkg_conf_load(void); 129 | void opkg_conf_deinit(void); 130 | 131 | int opkg_conf_write_status_files(void); 132 | char *root_filename_alloc(char *filename); 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /libopkg/sha256.h: -------------------------------------------------------------------------------- 1 | /* Declarations of functions and data types used for SHA256 and SHA224 sum 2 | library functions. 3 | Copyright (C) 2005, 2006 Free Software Foundation, Inc. 4 | 5 | This program is free software; you can redistribute it and/or modify it 6 | under the terms of the GNU General Public License as published by the 7 | Free Software Foundation; either version 2, or (at your option) any 8 | later version. 9 | 10 | This program is distributed in the hope that it will be useful, 11 | but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 | GNU General Public License for more details. 14 | 15 | You should have received a copy of the GNU General Public License 16 | along with this program; if not, write to the Free Software Foundation, 17 | Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ 18 | 19 | #ifndef SHA256_H 20 | #define SHA256_H 1 21 | 22 | #include 23 | #include 24 | 25 | /* Structure to save state of computation between the single steps. */ 26 | struct sha256_ctx { 27 | uint32_t state[8]; 28 | 29 | uint32_t total[2]; 30 | uint32_t buflen; 31 | uint32_t buffer[32]; 32 | }; 33 | 34 | /* Initialize structure containing state of computation. */ 35 | extern void sha256_init_ctx(struct sha256_ctx *ctx); 36 | extern void sha224_init_ctx(struct sha256_ctx *ctx); 37 | 38 | /* Starting with the result of former calls of this function (or the 39 | initialization function update the context for the next LEN bytes 40 | starting at BUFFER. 41 | It is necessary that LEN is a multiple of 64!!! */ 42 | extern void sha256_process_block(const void *buffer, size_t len, 43 | struct sha256_ctx *ctx); 44 | 45 | /* Starting with the result of former calls of this function (or the 46 | initialization function update the context for the next LEN bytes 47 | starting at BUFFER. 48 | It is NOT required that LEN is a multiple of 64. */ 49 | extern void sha256_process_bytes(const void *buffer, size_t len, 50 | struct sha256_ctx *ctx); 51 | 52 | /* Process the remaining bytes in the buffer and put result from CTX 53 | in first 32 (28) bytes following RESBUF. The result is always in little 54 | endian byte order, so that a byte-wise output yields to the wanted 55 | ASCII representation of the message digest. 56 | 57 | IMPORTANT: On some systems it is required that RESBUF be correctly 58 | aligned for a 32 bits value. */ 59 | extern void *sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf); 60 | extern void *sha224_finish_ctx(struct sha256_ctx *ctx, void *resbuf); 61 | 62 | /* Put result from CTX in first 32 (28) bytes following RESBUF. The result is 63 | always in little endian byte order, so that a byte-wise output yields 64 | to the wanted ASCII representation of the message digest. 65 | 66 | IMPORTANT: On some systems it is required that RESBUF is correctly 67 | aligned for a 32 bits value. */ 68 | extern void *sha256_read_ctx(const struct sha256_ctx *ctx, void *resbuf); 69 | extern void *sha224_read_ctx(const struct sha256_ctx *ctx, void *resbuf); 70 | 71 | /* Compute SHA256 (SHA224) message digest for bytes read from STREAM. The 72 | resulting message digest number will be written into the 32 (28) bytes 73 | beginning at RESBLOCK. */ 74 | extern int sha256_stream(FILE * stream, void *resblock); 75 | extern int sha224_stream(FILE * stream, void *resblock); 76 | 77 | /* Compute SHA256 (SHA224) message digest for LEN bytes beginning at BUFFER. The 78 | result is always in little endian byte order, so that a byte-wise 79 | output yields to the wanted ASCII representation of the message 80 | digest. */ 81 | extern void *sha256_buffer(const char *buffer, size_t len, void *resblock); 82 | extern void *sha224_buffer(const char *buffer, size_t len, void *resblock); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /libbb/libbb.h: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Busybox main internal header file 4 | * 5 | * This program is free software; you can redistribute it and/or modify 6 | * it under the terms of the GNU General Public License as published by 7 | * the Free Software Foundation; either version 2 of the License, or 8 | * (at your option) any later version. 9 | * 10 | * This program is distributed in the hope that it will be useful, 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | * General Public License for more details. 14 | * 15 | * You should have received a copy of the GNU General Public License 16 | * along with this program; if not, write to the Free Software 17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 | */ 19 | 20 | #ifndef __LIBBB_H__ 21 | #define __LIBBB_H__ 1 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | 30 | #include "../libopkg/opkg_message.h" 31 | 32 | #ifndef FALSE 33 | #define FALSE ((int) 0) 34 | #endif 35 | 36 | #ifndef TRUE 37 | #define TRUE ((int) 1) 38 | #endif 39 | 40 | #define error_msg(fmt, args...) opkg_msg(ERROR, fmt"\n", ##args) 41 | #define perror_msg(fmt, args...) opkg_perror(ERROR, fmt, ##args) 42 | #define error_msg_and_die(fmt, args...) \ 43 | do { \ 44 | error_msg(fmt, ##args); \ 45 | exit(EXIT_FAILURE); \ 46 | } while (0) 47 | #define perror_msg_and_die(fmt, args...) \ 48 | do { \ 49 | perror_msg(fmt, ##args); \ 50 | exit(EXIT_FAILURE); \ 51 | } while (0) 52 | 53 | extern void archive_xread_all(int fd, char *buf, size_t count); 54 | 55 | const char *mode_string(int mode); 56 | const char *time_string(time_t timeVal); 57 | 58 | int copy_file(const char *source, const char *dest, int flags); 59 | int copy_file_chunk(FILE * src_file, FILE * dst_file, 60 | unsigned long long chunksize); 61 | ssize_t safe_read(int fd, void *buf, size_t count); 62 | ssize_t full_read(int fd, char *buf, int len); 63 | 64 | extern int parse_mode(const char *s, mode_t * theMode); 65 | 66 | extern FILE *wfopen(const char *path, const char *mode); 67 | extern FILE *xfopen(const char *path, const char *mode); 68 | 69 | extern void *xmalloc(size_t size); 70 | extern void *xrealloc(void *old, size_t size); 71 | extern void *xcalloc(size_t nmemb, size_t size); 72 | extern char *xstrdup(const char *s); 73 | extern char *xstrndup(const char *s, int n); 74 | extern char *safe_strncpy(char *dst, const char *src, size_t size); 75 | 76 | char *xreadlink(const char *path); 77 | char *concat_path_file(const char *path, const char *filename); 78 | char *last_char_is(const char *s, int c); 79 | 80 | typedef struct file_headers_s { 81 | char *name; 82 | char *link_name; 83 | off_t size; 84 | uid_t uid; 85 | gid_t gid; 86 | mode_t mode; 87 | time_t mtime; 88 | dev_t device; 89 | } file_header_t; 90 | 91 | enum extract_functions_e { 92 | extract_verbose_list = 1, 93 | extract_list = 2, 94 | extract_one_to_buffer = 4, 95 | extract_to_stream = 8, 96 | extract_all_to_fs = 16, 97 | extract_preserve_date = 32, 98 | extract_data_tar_gz = 64, 99 | extract_control_tar_gz = 128, 100 | extract_unzip_only = 256, 101 | extract_unconditional = 512, 102 | extract_create_leading_dirs = 1024, 103 | extract_quiet = 2048, 104 | extract_exclude_list = 4096 105 | }; 106 | 107 | char *deb_extract(const char *package_filename, FILE * out_stream, 108 | const int extract_function, const char *prefix, 109 | const char *filename, int *err); 110 | 111 | extern int unzip(FILE * l_in_file, FILE * l_out_file); 112 | extern int gz_close(int gunzip_pid); 113 | extern FILE *gz_open(FILE * compressed_file, int *pid); 114 | 115 | int make_directory(const char *path, long mode, int flags); 116 | 117 | enum { 118 | FILEUTILS_PRESERVE_STATUS = 1, 119 | FILEUTILS_PRESERVE_SYMLINKS = 2, 120 | FILEUTILS_RECUR = 4, 121 | FILEUTILS_FORCE = 8, 122 | }; 123 | 124 | #endif /* __LIBBB_H__ */ 125 | -------------------------------------------------------------------------------- /libopkg/active_list.c: -------------------------------------------------------------------------------- 1 | /* active_list.h - the opkg package management system 2 | 3 | Tick Chen 4 | 5 | Copyright (C) 2008 Openmoko Inc. 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "active_list.h" 19 | #include 20 | #include 21 | #include 22 | 23 | #include "libbb/libbb.h" 24 | 25 | void active_list_init(struct active_list *ptr) 26 | { 27 | INIT_LIST_HEAD(&ptr->node); 28 | INIT_LIST_HEAD(&ptr->depend); 29 | ptr->depended = NULL; 30 | } 31 | 32 | /** 33 | */ 34 | struct active_list *active_list_next(struct active_list *head, 35 | struct active_list *ptr) 36 | { 37 | struct active_list *next = NULL; 38 | if (!head) { 39 | opkg_msg(ERROR, "Internal error: head=%p, ptr=%p\n", head, ptr); 40 | return NULL; 41 | } 42 | if (!ptr) 43 | ptr = head; 44 | next = list_entry(ptr->node.next, struct active_list, node); 45 | if (next == head) { 46 | return NULL; 47 | } 48 | if (ptr->depended && &ptr->depended->depend == ptr->node.next) { 49 | return ptr->depended; 50 | } 51 | while (next->depend.next != &next->depend) { 52 | next = list_entry(next->depend.next, struct active_list, node); 53 | } 54 | return next; 55 | } 56 | 57 | struct active_list *active_list_prev(struct active_list *head, 58 | struct active_list *ptr) 59 | { 60 | struct active_list *prev = NULL; 61 | if (!head) { 62 | opkg_msg(ERROR, "Internal error: head=%p, ptr=%p\n", head, ptr); 63 | return NULL; 64 | } 65 | if (!ptr) 66 | ptr = head; 67 | if (ptr->depend.prev != &ptr->depend) { 68 | prev = list_entry(ptr->depend.prev, struct active_list, node); 69 | return prev; 70 | } 71 | if (ptr->depended && ptr->depended != head 72 | && &ptr->depended->depend == ptr->node.prev) { 73 | prev = 74 | list_entry(ptr->depended->node.prev, struct active_list, 75 | node); 76 | } else 77 | prev = list_entry(ptr->node.prev, struct active_list, node); 78 | if (prev == head) 79 | return NULL; 80 | return prev; 81 | } 82 | 83 | struct active_list *active_list_move_node(struct active_list *old_head, 84 | struct active_list *new_head, 85 | struct active_list *node) 86 | { 87 | struct active_list *prev; 88 | if (!old_head || !new_head || !node) 89 | return NULL; 90 | if (old_head == new_head) 91 | return node; 92 | prev = active_list_prev(old_head, node); 93 | active_list_add(new_head, node); 94 | return prev; 95 | } 96 | 97 | static void list_head_clear(struct list_head *head) 98 | { 99 | struct active_list *next; 100 | struct list_head *n, *ptr; 101 | if (!head) 102 | return; 103 | list_for_each_safe(ptr, n, head) { 104 | next = list_entry(ptr, struct active_list, node); 105 | if (next->depend.next != &next->depend) { 106 | list_head_clear(&next->depend); 107 | } 108 | active_list_init(next); 109 | } 110 | } 111 | 112 | void active_list_clear(struct active_list *head) 113 | { 114 | list_head_clear(&head->node); 115 | if (head->depend.next != &head->depend) { 116 | list_head_clear(&head->depend); 117 | } 118 | active_list_init(head); 119 | } 120 | 121 | void active_list_add(struct active_list *head, struct active_list *node) 122 | { 123 | list_del_init(&node->node); 124 | list_add_tail(&node->node, &head->node); 125 | node->depended = head; 126 | } 127 | 128 | struct active_list *active_list_head_new(void) 129 | { 130 | struct active_list *head = xcalloc(1, sizeof(struct active_list)); 131 | active_list_init(head); 132 | return head; 133 | } 134 | 135 | void active_list_head_delete(struct active_list *head) 136 | { 137 | active_list_clear(head); 138 | free(head); 139 | } 140 | -------------------------------------------------------------------------------- /libbb/gz_open.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Utility routines. 4 | * 5 | * Copyright (C) many different people. If you wrote this, please 6 | * acknowledge your work. 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, but 14 | * WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21 | * USA 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include "libbb.h" 31 | 32 | static int gz_use_vfork; 33 | 34 | FILE *gz_open(FILE * compressed_file, int *pid) 35 | { 36 | int unzip_pipe[2]; 37 | off_t floc; 38 | int cfile = -1; 39 | 40 | gz_use_vfork = (getenv("OPKG_USE_VFORK") != NULL); 41 | 42 | if (gz_use_vfork) { 43 | /* Create a new file descriptor for the input stream 44 | * (it *must* be associated with a file), and lseek() 45 | * to the same position in that fd as the stream. 46 | */ 47 | cfile = dup(fileno(compressed_file)); 48 | floc = ftello(compressed_file); 49 | lseek(cfile, floc, SEEK_SET); 50 | setenv("GZIP", "--quiet", 0); 51 | } 52 | 53 | if (pipe(unzip_pipe) != 0) { 54 | perror_msg("pipe"); 55 | return (NULL); 56 | } 57 | 58 | /* If we don't flush, we end up with two copies of anything pending, 59 | one from the parent, one from the child */ 60 | fflush(stdout); 61 | fflush(stderr); 62 | 63 | if (gz_use_vfork) { 64 | *pid = vfork(); 65 | } else { 66 | *pid = fork(); 67 | } 68 | 69 | if (*pid < 0) { 70 | perror_msg("fork"); 71 | return (NULL); 72 | } 73 | 74 | if (*pid == 0) { 75 | /* child process */ 76 | close(unzip_pipe[0]); 77 | if (gz_use_vfork) { 78 | dup2(unzip_pipe[1], 1); 79 | dup2(cfile, 0); 80 | execlp("gunzip", "gunzip", NULL); 81 | /* If we get here, we had a failure */ 82 | _exit(EXIT_FAILURE); 83 | } else { 84 | unzip(compressed_file, fdopen(unzip_pipe[1], "w")); 85 | fflush(NULL); 86 | fclose(compressed_file); 87 | close(unzip_pipe[1]); 88 | _exit(EXIT_SUCCESS); 89 | } 90 | } 91 | /* Parent process is executing here */ 92 | if (gz_use_vfork) { 93 | close(cfile); 94 | } 95 | close(unzip_pipe[1]); 96 | return (fdopen(unzip_pipe[0], "r")); 97 | } 98 | 99 | int gz_close(int gunzip_pid) 100 | { 101 | int status; 102 | int ret; 103 | 104 | if (gz_use_vfork) { 105 | /* The gunzip process remains running in the background if we 106 | * used the vfork()/exec() technique - so we have to kill it 107 | * forcibly. There might be a better way to do this, but that 108 | * affect a lot of other parts of opkg, and this works fine. 109 | */ 110 | if (kill(gunzip_pid, SIGTERM) == -1) { 111 | perror_msg("gz_close(): unable to kill gunzip pid."); 112 | return -1; 113 | } 114 | } 115 | 116 | if (waitpid(gunzip_pid, &status, 0) == -1) { 117 | perror_msg("waitpid"); 118 | return -1; 119 | } 120 | 121 | if (gz_use_vfork) { 122 | /* Bail out here if we used the vfork()/exec() technique. */ 123 | return 0; 124 | } 125 | 126 | if (WIFSIGNALED(status)) { 127 | error_msg("Unzip process killed by signal %d.\n", 128 | WTERMSIG(status)); 129 | return -1; 130 | } 131 | 132 | if (!WIFEXITED(status)) { 133 | /* shouldn't happen */ 134 | error_msg 135 | ("Your system is broken: got status %d from waitpid.\n", 136 | status); 137 | return -1; 138 | } 139 | 140 | if ((ret = WEXITSTATUS(status))) { 141 | error_msg("Unzip process failed with return code %d.\n", ret); 142 | return -1; 143 | } 144 | 145 | return 0; 146 | } 147 | -------------------------------------------------------------------------------- /libopkg/opkg_upgrade.c: -------------------------------------------------------------------------------- 1 | /* opkg_upgrade.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | Copyright (C) 2001 University of Southern California 5 | 6 | Copyright (C) 2003 Daniele Nicolodi 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2, or (at 11 | your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | General Public License for more details. 17 | */ 18 | 19 | #include 20 | #include 21 | 22 | #include "opkg_install.h" 23 | #include "opkg_upgrade.h" 24 | #include "opkg_message.h" 25 | 26 | int opkg_upgrade_pkg(pkg_t * old) 27 | { 28 | pkg_t *new; 29 | int cmp; 30 | char *old_version, *new_version; 31 | 32 | if (old->state_flag & SF_HOLD) { 33 | opkg_msg(NOTICE, "Not upgrading package %s which is marked " 34 | "hold (flags=%#x).\n", old->name, old->state_flag); 35 | return 0; 36 | } 37 | 38 | new = pkg_hash_fetch_best_installation_candidate_by_name(old->name); 39 | if (new == NULL) { 40 | old_version = pkg_version_str_alloc(old); 41 | opkg_msg(NOTICE, "Assuming locally installed package %s (%s) " 42 | "is up to date.\n", old->name, old_version); 43 | free(old_version); 44 | return 0; 45 | } 46 | 47 | old_version = pkg_version_str_alloc(old); 48 | new_version = pkg_version_str_alloc(new); 49 | 50 | cmp = pkg_compare_versions(old, new); 51 | opkg_msg(DEBUG, "Comparing visible versions of pkg %s:" 52 | "\n\t%s is installed " 53 | "\n\t%s is available " 54 | "\n\t%d was comparison result\n", 55 | old->name, old_version, new_version, cmp); 56 | if (cmp == 0) { 57 | opkg_msg(INFO, 58 | "Package %s (%s) installed in %s is up to date.\n", 59 | old->name, old_version, old->dest->name); 60 | free(old_version); 61 | free(new_version); 62 | return 0; 63 | } else if (cmp > 0) { 64 | opkg_msg(NOTICE, 65 | "Not downgrading package %s on %s from %s to %s.\n", 66 | old->name, old->dest->name, old_version, new_version); 67 | free(old_version); 68 | free(new_version); 69 | return 0; 70 | } else if (cmp < 0) { 71 | new->dest = old->dest; 72 | old->state_want = SW_DEINSTALL; 73 | } 74 | 75 | free(old_version); 76 | free(new_version); 77 | new->state_flag |= SF_USER; 78 | return opkg_install_pkg(new, 1); 79 | } 80 | 81 | static void 82 | pkg_hash_check_installed_pkg_helper(const char *pkg_name, void *entry, 83 | void *data) 84 | { 85 | struct active_list *item, *head = (struct active_list *)data; 86 | abstract_pkg_t *ab_pkg = (abstract_pkg_t *) entry; 87 | pkg_vec_t *pkg_vec = ab_pkg->pkgs; 88 | int j; 89 | 90 | if (!pkg_vec) 91 | return; 92 | 93 | for (j = 0; j < pkg_vec->len; j++) { 94 | pkg_t *pkg = pkg_vec->pkgs[j]; 95 | if (pkg->state_status == SS_INSTALLED 96 | || pkg->state_status == SS_UNPACKED) { 97 | item = active_list_head_new(); 98 | item->pkg = pkg; 99 | active_list_add(head, item); 100 | } 101 | } 102 | } 103 | 104 | struct active_list *prepare_upgrade_list(void) 105 | { 106 | struct active_list *head = active_list_head_new(); 107 | struct active_list *all = active_list_head_new(); 108 | struct active_list *node = NULL; 109 | 110 | /* ensure all data is valid */ 111 | pkg_info_preinstall_check(); 112 | 113 | hash_table_foreach(&conf->pkg_hash, pkg_hash_check_installed_pkg_helper, 114 | all); 115 | for (node = active_list_next(all, all); node; 116 | node = active_list_next(all, node)) { 117 | pkg_t *old, *new; 118 | int cmp; 119 | 120 | old = node->pkg; 121 | new = 122 | pkg_hash_fetch_best_installation_candidate_by_name(old-> 123 | name); 124 | 125 | if (new == NULL) 126 | continue; 127 | 128 | cmp = pkg_compare_versions(old, new); 129 | 130 | if (cmp < 0) { 131 | node = active_list_move_node(all, head, node); 132 | } 133 | } 134 | active_list_head_delete(all); 135 | return head; 136 | } 137 | -------------------------------------------------------------------------------- /tests/opkg_active_list_test.c: -------------------------------------------------------------------------------- 1 | /* opkg_active_list.c - the opkg package management system 2 | 3 | Tick Chen 4 | 5 | Copyright (C) 2008 Openmoko 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include 22 | 23 | struct active_test { 24 | char *str; 25 | struct active_list list; 26 | }; 27 | 28 | static struct active_test *active_test_new(char *str) 29 | { 30 | struct active_test *ans = 31 | (struct active_test *)calloc(1, sizeof(struct active_test)); 32 | ans->str = str; 33 | active_list_init(&ans->list); 34 | return ans; 35 | } 36 | 37 | static void active_test_add(struct active_list *head, struct active_test *node) 38 | { 39 | active_list_add(head, &node->list); 40 | } 41 | 42 | /* 43 | .--A---B----C----D-----E----F 44 | | |__k---L 45 | | |_ N 46 | |__ G ---H ---I---J 47 | |_M |_O 48 | 49 | Then the sequence will be 50 | +: G M H I O J A B K N L C D E F 51 | -: F E D C L N K B A J O I H M G 52 | */ 53 | static void make_list(struct active_list *head) 54 | { 55 | struct active_test *A = active_test_new("A"); 56 | struct active_test *B = active_test_new("B"); 57 | struct active_test *C = active_test_new("C"); 58 | struct active_test *D = active_test_new("D"); 59 | struct active_test *E = active_test_new("E"); 60 | struct active_test *F = active_test_new("F"); 61 | struct active_test *G = active_test_new("G"); 62 | struct active_test *H = active_test_new("H"); 63 | struct active_test *I = active_test_new("I"); 64 | struct active_test *J = active_test_new("J"); 65 | struct active_test *K = active_test_new("K"); 66 | struct active_test *L = active_test_new("L"); 67 | struct active_test *M = active_test_new("M"); 68 | struct active_test *N = active_test_new("N"); 69 | struct active_test *O = active_test_new("O"); 70 | 71 | active_test_add(head, A); 72 | active_test_add(head, B); 73 | active_test_add(head, C); 74 | active_test_add(head, D); 75 | active_test_add(head, E); 76 | active_test_add(head, F); 77 | active_test_add(head, G); 78 | active_test_add(head, H); 79 | active_test_add(head, I); 80 | active_test_add(head, J); 81 | active_test_add(head, K); 82 | active_test_add(head, L); 83 | active_test_add(head, M); 84 | active_test_add(head, N); 85 | active_test_add(head, O); 86 | } 87 | 88 | static void show_list(struct active_list *head) 89 | { 90 | struct active_list *ptr; 91 | struct active_test *test; 92 | for (ptr = active_list_next(head, NULL); ptr; 93 | ptr = active_list_next(head, ptr)) { 94 | test = list_entry(ptr, struct active_test, list); 95 | printf("%s ", test->str); 96 | } 97 | printf("\n"); 98 | } 99 | 100 | int main(void) 101 | { 102 | struct active_list head; 103 | struct active_list *ptr; 104 | struct active_test *test; 105 | active_list_init(&head); 106 | make_list(&head); 107 | 108 | printf("pos order: "); 109 | show_list(&head); 110 | /* for(ptr = active_list_next(&head, &head); ptr ;ptr = active_list_next(&head, ptr)) { 111 | test = list_entry(ptr, struct active_test, list); 112 | printf ("%s ",test->str); 113 | }*/ 114 | printf("neg order: "); 115 | for (ptr = active_list_prev(&head, &head); ptr; 116 | ptr = active_list_prev(&head, ptr)) { 117 | test = list_entry(ptr, struct active_test, list); 118 | printf("%s ", test->str); 119 | } 120 | printf("after clear: "); 121 | active_list_clear(&head); 122 | for (ptr = active_list_next(&head, NULL); ptr; 123 | ptr = active_list_next(&head, ptr)) { 124 | test = list_entry(ptr, struct active_test, list); 125 | printf("%s ", test->str); 126 | } 127 | printf("\n"); 128 | 129 | } 130 | -------------------------------------------------------------------------------- /libopkg/parse_util.c: -------------------------------------------------------------------------------- 1 | /* parse_util.c - the opkg package management system 2 | 3 | Copyright (C) 2009 Ubiq Technologies 4 | 5 | Steven M. Ayer 6 | Copyright (C) 2002 Compaq Computer Corporation 7 | 8 | This program is free software; you can redistribute it and/or 9 | modify it under the terms of the GNU General Public License as 10 | published by the Free Software Foundation; either version 2, or (at 11 | your option) any later version. 12 | 13 | This program is distributed in the hope that it will be useful, but 14 | WITHOUT ANY WARRANTY; without even the implied warranty of 15 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | General Public License for more details. 17 | */ 18 | 19 | #include 20 | 21 | #include "opkg_utils.h" 22 | #include "libbb/libbb.h" 23 | 24 | #include "parse_util.h" 25 | #include "pkg_parse.h" 26 | 27 | int is_field(const char *type, const char *line) 28 | { 29 | if (!strncmp(line, type, strlen(type))) 30 | return 1; 31 | return 0; 32 | } 33 | 34 | char *parse_simple(const char *type, const char *line) 35 | { 36 | char *field = trim_xstrdup(line + strlen(type) + 1); 37 | if (strlen(field) == 0) { 38 | free(field); 39 | return NULL; 40 | } 41 | return field; 42 | } 43 | 44 | /* 45 | * Parse a comma separated string into an array. 46 | */ 47 | char **parse_list(const char *raw, unsigned int *count, const char sep, 48 | int skip_field) 49 | { 50 | char **depends = NULL; 51 | const char *start, *end; 52 | int line_count = 0; 53 | 54 | /* skip past the "Field:" marker */ 55 | if (!skip_field) { 56 | while (*raw && *raw != ':') 57 | raw++; 58 | raw++; 59 | } 60 | 61 | if (line_is_blank(raw)) { 62 | *count = line_count; 63 | return NULL; 64 | } 65 | 66 | while (*raw) { 67 | depends = xrealloc(depends, sizeof(char *) * (line_count + 1)); 68 | 69 | while (isspace(*raw)) 70 | raw++; 71 | 72 | start = raw; 73 | while (*raw != sep && *raw) 74 | raw++; 75 | end = raw; 76 | 77 | while (end > start && isspace(*end)) 78 | end--; 79 | 80 | if (sep == ' ') 81 | end++; 82 | 83 | depends[line_count] = xstrndup(start, end - start); 84 | 85 | line_count++; 86 | if (*raw == sep) 87 | raw++; 88 | } 89 | 90 | *count = line_count; 91 | return depends; 92 | } 93 | 94 | int 95 | parse_from_stream_nomalloc(parse_line_t parse_line, void *item, FILE * fp, 96 | uint mask, char **buf0, size_t buf0len) 97 | { 98 | int ret, lineno; 99 | char *buf, *nl; 100 | size_t buflen; 101 | 102 | lineno = 1; 103 | ret = 0; 104 | 105 | buflen = buf0len; 106 | buf = *buf0; 107 | buf[0] = '\0'; 108 | 109 | while (1) { 110 | if (fgets(buf, (int)buflen, fp) == NULL) { 111 | if (ferror(fp)) { 112 | opkg_perror(ERROR, "fgets"); 113 | ret = -1; 114 | } else if (strlen(*buf0) == buf0len - 1) { 115 | opkg_msg(ERROR, "Missing new line character" 116 | " at end of file!\n"); 117 | parse_line(item, *buf0, mask); 118 | } 119 | break; 120 | } 121 | 122 | nl = strchr(buf, '\n'); 123 | if (nl == NULL) { 124 | if (strlen(buf) < buflen - 1) { 125 | /* 126 | * Line could be exactly buflen-1 long and 127 | * missing a newline, but we won't know until 128 | * fgets fails to read more data. 129 | */ 130 | opkg_msg(ERROR, "Missing new line character" 131 | " at end of file!\n"); 132 | parse_line(item, *buf0, mask); 133 | break; 134 | } 135 | if (buf0len >= EXCESSIVE_LINE_LEN) { 136 | opkg_msg(ERROR, "Excessively long line at " 137 | "%d. Corrupt file?\n", lineno); 138 | ret = -1; 139 | break; 140 | } 141 | 142 | /* 143 | * Realloc and point buf past the data already read, 144 | * at the NULL terminator inserted by fgets. 145 | * |<--------------- buf0len ----------------->| 146 | * | |<------- buflen ---->| 147 | * |---------------------|---------------------| 148 | * buf0 buf 149 | */ 150 | buflen = buf0len + 1; 151 | buf0len *= 2; 152 | *buf0 = xrealloc(*buf0, buf0len); 153 | buf = *buf0 + buflen - 2; 154 | 155 | continue; 156 | } 157 | 158 | *nl = '\0'; 159 | 160 | lineno++; 161 | 162 | if (parse_line(item, *buf0, mask)) 163 | break; 164 | 165 | buf = *buf0; 166 | buflen = buf0len; 167 | buf[0] = '\0'; 168 | } 169 | 170 | return ret; 171 | } 172 | -------------------------------------------------------------------------------- /libopkg/void_list.c: -------------------------------------------------------------------------------- 1 | /* void_list.c - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include "void_list.h" 19 | #include "libbb/libbb.h" 20 | 21 | void void_list_elt_init(void_list_elt_t * elt, void *data) 22 | { 23 | INIT_LIST_HEAD(&elt->node); 24 | elt->data = data; 25 | } 26 | 27 | static void_list_elt_t *void_list_elt_new(void *data) 28 | { 29 | void_list_elt_t *elt; 30 | /* freed in void_list_elt_deinit */ 31 | elt = xcalloc(1, sizeof(void_list_elt_t)); 32 | void_list_elt_init(elt, data); 33 | return elt; 34 | } 35 | 36 | void void_list_elt_deinit(void_list_elt_t * elt) 37 | { 38 | list_del_init(&elt->node); 39 | void_list_elt_init(elt, NULL); 40 | free(elt); 41 | } 42 | 43 | void void_list_init(void_list_t * list) 44 | { 45 | INIT_LIST_HEAD(&list->head); 46 | } 47 | 48 | void void_list_deinit(void_list_t * list) 49 | { 50 | void_list_elt_t *elt; 51 | 52 | while (!void_list_empty(list)) { 53 | elt = void_list_pop(list); 54 | void_list_elt_deinit(elt); 55 | } 56 | INIT_LIST_HEAD(&list->head); 57 | } 58 | 59 | void void_list_append(void_list_t * list, void *data) 60 | { 61 | void_list_elt_t *elt = void_list_elt_new(data); 62 | list_add_tail(&elt->node, &list->head); 63 | } 64 | 65 | void void_list_push(void_list_t * list, void *data) 66 | { 67 | void_list_elt_t *elt = void_list_elt_new(data); 68 | list_add(&elt->node, &list->head); 69 | } 70 | 71 | void_list_elt_t *void_list_pop(void_list_t * list) 72 | { 73 | struct list_head *node; 74 | 75 | if (void_list_empty(list)) 76 | return NULL; 77 | node = list->head.next; 78 | list_del_init(node); 79 | return list_entry(node, void_list_elt_t, node); 80 | } 81 | 82 | void *void_list_remove(void_list_t * list, void_list_elt_t ** iter) 83 | { 84 | void_list_elt_t *pos, *n; 85 | void_list_elt_t *old_elt; 86 | void *old_data = NULL; 87 | 88 | old_elt = *iter; 89 | if (!old_elt) 90 | return old_data; 91 | old_data = old_elt->data; 92 | 93 | list_for_each_entry_safe(pos, n, &list->head, node) { 94 | if (pos == old_elt) 95 | break; 96 | } 97 | if (pos != old_elt) { 98 | opkg_msg(ERROR, "Internal error: element not found in list.\n"); 99 | return NULL; 100 | } 101 | 102 | *iter = list_entry(pos->node.prev, void_list_elt_t, node); 103 | void_list_elt_deinit(pos); 104 | 105 | return old_data; 106 | } 107 | 108 | /* remove element containing elt data, using cmp(elt->data, target_data) == 0. */ 109 | void *void_list_remove_elt(void_list_t * list, const void *target_data, 110 | void_list_cmp_t cmp) 111 | { 112 | void_list_elt_t *pos, *n; 113 | void *old_data = NULL; 114 | list_for_each_entry_safe(pos, n, &list->head, node) { 115 | if (pos->data && cmp(pos->data, target_data) == 0) { 116 | old_data = pos->data; 117 | void_list_elt_deinit(pos); 118 | break; 119 | } 120 | } 121 | return old_data; 122 | } 123 | 124 | void_list_elt_t *void_list_first(void_list_t * list) 125 | { 126 | struct list_head *elt; 127 | if (!list) 128 | return NULL; 129 | elt = list->head.next; 130 | if (elt == &list->head) { 131 | return NULL; 132 | } 133 | return list_entry(elt, void_list_elt_t, node); 134 | } 135 | 136 | void_list_elt_t *void_list_prev(void_list_t * list, void_list_elt_t * node) 137 | { 138 | struct list_head *elt; 139 | if (!list || !node) 140 | return NULL; 141 | elt = node->node.prev; 142 | if (elt == &list->head) { 143 | return NULL; 144 | } 145 | return list_entry(elt, void_list_elt_t, node); 146 | } 147 | 148 | void_list_elt_t *void_list_next(void_list_t * list, void_list_elt_t * node) 149 | { 150 | struct list_head *elt; 151 | if (!list || !node) 152 | return NULL; 153 | elt = node->node.next; 154 | if (elt == &list->head) { 155 | return NULL; 156 | } 157 | return list_entry(elt, void_list_elt_t, node); 158 | } 159 | 160 | void_list_elt_t *void_list_last(void_list_t * list) 161 | { 162 | struct list_head *elt; 163 | if (!list) 164 | return NULL; 165 | elt = list->head.prev; 166 | if (elt == &list->head) { 167 | return NULL; 168 | } 169 | return list_entry(elt, void_list_elt_t, node); 170 | } 171 | -------------------------------------------------------------------------------- /libopkg/pkg_alternatives.c: -------------------------------------------------------------------------------- 1 | /* pkg_alternatives.c - the opkg package management system 2 | 3 | Copyright (C) 2017 Yousong Zhou 4 | 5 | This program is free software; you can redistribute it and/or 6 | modify it under the terms of the GNU General Public License as 7 | published by the Free Software Foundation; either version 2, or (at 8 | your option) any later version. 9 | 10 | This program is distributed in the hope that it will be useful, but 11 | WITHOUT ANY WARRANTY; without even the implied warranty of 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | General Public License for more details. 14 | */ 15 | 16 | #include 17 | #include /* stat */ 18 | #include 19 | #include /* dirname */ 20 | #include 21 | 22 | #include "file_util.h" 23 | #include "libbb/libbb.h" 24 | #include "opkg_message.h" 25 | #include "pkg.h" 26 | #include "pkg_hash.h" 27 | #include "pkg_alternatives.h" 28 | #include "sprintf_alloc.h" 29 | 30 | struct alternative_provider { 31 | char *name; 32 | char *altpath; 33 | }; 34 | 35 | static const struct alternative_provider providers[] = { 36 | { 37 | .name = "busybox", 38 | .altpath = "/bin/busybox", 39 | }, 40 | }; 41 | 42 | static const char *pkg_alternatives_check_providers(const char *path) 43 | { 44 | pkg_t *pkg; 45 | str_list_t *files; 46 | str_list_elt_t *iter; 47 | int i; 48 | 49 | for (i = 0; i < ARRAY_SIZE(providers); i++) { 50 | pkg = pkg_hash_fetch_installed_by_name(providers[i].name); 51 | if (!pkg) { 52 | continue; 53 | } 54 | files = pkg_get_installed_files(pkg); 55 | for (iter = str_list_first(files); iter; iter = str_list_next(files, iter)) { 56 | if (!strcmp(path, (char *)(iter->data))) { 57 | pkg_free_installed_files(pkg); 58 | return providers[i].altpath; 59 | } 60 | } 61 | pkg_free_installed_files(pkg); 62 | } 63 | return NULL; 64 | } 65 | 66 | static int pkg_alternatives_update_path(pkg_t *pkg, const pkg_vec_t *installed, const char *path) 67 | { 68 | struct pkg_alternatives *pkg_alts; 69 | struct pkg_alternative *the_alt = NULL; 70 | pkg_t *the_pkg = pkg; 71 | int i, j; 72 | int r; 73 | char *path_in_dest; 74 | const char *target_path = NULL; 75 | 76 | for (i = 0; i < installed->len; i++) { 77 | pkg_t *pkg = installed->pkgs[i]; 78 | pkg_alts = pkg_get_ptr(pkg, PKG_ALTERNATIVES); 79 | if (!pkg_alts) 80 | continue; 81 | 82 | for (j = 0; j < pkg_alts->nalts; j++) { 83 | struct pkg_alternative *alt = pkg_alts->alts[j]; 84 | 85 | if (strcmp(path, alt->path)) 86 | continue; 87 | if (!the_alt || the_alt->prio < alt->prio) { 88 | the_pkg = pkg; 89 | the_alt = alt; 90 | } 91 | } 92 | } 93 | 94 | /* path is assumed to be an absolute one */ 95 | sprintf_alloc(&path_in_dest, "%s%s", the_pkg->dest->root_dir, &path[1]); 96 | if (!path_in_dest) 97 | return -1; 98 | 99 | if (the_alt) { 100 | target_path = the_alt->altpath; 101 | } else { 102 | target_path = pkg_alternatives_check_providers(path); 103 | } 104 | 105 | if (target_path) { 106 | struct stat sb; 107 | 108 | r = lstat(path_in_dest, &sb); 109 | if (!r) { 110 | char *realpath; 111 | 112 | if (!S_ISLNK(sb.st_mode)) { 113 | opkg_msg(ERROR, "%s exists but is not a symlink\n", path_in_dest); 114 | r = -1; 115 | goto out; 116 | } 117 | realpath = xreadlink(path_in_dest); 118 | if (realpath && strcmp(realpath, target_path)) 119 | unlink(path_in_dest); 120 | free(realpath); 121 | } else if (errno != ENOENT) { 122 | goto out; 123 | } 124 | { 125 | char *path_copy = xstrdup(path_in_dest); 126 | char *path_parent = dirname(path_copy); 127 | 128 | r = file_mkdir_hier(path_parent, 0755); 129 | free(path_copy); 130 | if (r) { 131 | goto out; 132 | } 133 | r = symlink(target_path, path_in_dest); 134 | if (r && errno == EEXIST) { 135 | /* 136 | * the strcmp & unlink check above will make sure that if EEXIST 137 | * happens, the symlink target also matches 138 | */ 139 | r = 0; 140 | } 141 | if (r) { 142 | opkg_perror(ERROR, "failed symlinking %s -> %s", path_in_dest, target_path); 143 | } 144 | } 145 | } else { 146 | unlink(path_in_dest); 147 | r = 0; 148 | } 149 | 150 | out: 151 | free(path_in_dest); 152 | return r; 153 | } 154 | 155 | int pkg_alternatives_update(pkg_t * pkg) 156 | { 157 | int r = 0; 158 | int i; 159 | struct pkg_alternatives *pkg_alts; 160 | struct pkg_alternative *alt = NULL; 161 | pkg_vec_t *installed; 162 | 163 | pkg_alts = pkg_get_ptr(pkg, PKG_ALTERNATIVES); 164 | if (!pkg_alts) 165 | return 0; 166 | 167 | installed = pkg_vec_alloc(); 168 | pkg_hash_fetch_all_installed(installed); 169 | for (i = 0; i < pkg_alts->nalts; i++) { 170 | alt = pkg_alts->alts[i]; 171 | r |= pkg_alternatives_update_path(pkg, installed, alt->path); 172 | } 173 | pkg_vec_free(installed); 174 | 175 | return r; 176 | } 177 | -------------------------------------------------------------------------------- /libbb/gzip.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2016 Jo-Philipp Wich 3 | * Copyright (C) 2016 Felix Fietkau 4 | * 5 | * Zlib decrompression utility routines. 6 | * 7 | * This program is free software; you can redistribute it and/or modify 8 | * it under the terms of the GNU General Public License as published by 9 | * the Free Software Foundation; either version 2 of the License, or 10 | * (at your option) any later version. 11 | * 12 | * This program is distributed in the hope that it will be useful, 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | * GNU Library General Public License for more details. 16 | * 17 | * You should have received a copy of the GNU General Public License 18 | * along with this program; if not, write to the Free Software 19 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 | */ 21 | 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | 31 | #include "gzip.h" 32 | 33 | static void to_devnull(int fd) 34 | { 35 | int devnull = open("/dev/null", fd ? O_WRONLY : O_RDONLY); 36 | 37 | if (devnull >= 0) 38 | dup2(devnull, fd); 39 | 40 | if (devnull > STDERR_FILENO) 41 | close(devnull); 42 | } 43 | 44 | static void *gzip_thread(void *ptr) 45 | { 46 | struct gzip_handle *zh = ptr; 47 | char buf[4096]; 48 | int len = 0, ret; 49 | 50 | while (1) { 51 | if (zh->file) 52 | len = fread(buf, 1, sizeof(buf), zh->file); 53 | else if (zh->gzip) 54 | len = gzip_read(zh->gzip, buf, sizeof(buf)); 55 | 56 | if (len <= 0) 57 | break; 58 | 59 | do { 60 | ret = write(zh->wfd, buf, len); 61 | } while (ret == -1 && errno == EINTR); 62 | } 63 | 64 | close(zh->wfd); 65 | zh->wfd = -1; 66 | 67 | return NULL; 68 | } 69 | 70 | int gzip_exec(struct gzip_handle *zh, const char *filename) 71 | { 72 | int rpipe[2] = { -1, -1 }, wpipe[2] = { 73 | -1, -1}; 74 | struct sigaction pipe_sa = {.sa_handler = SIG_IGN }; 75 | 76 | zh->rfd = -1; 77 | zh->wfd = -1; 78 | 79 | if (sigaction(SIGPIPE, &pipe_sa, &zh->pipe_sa) < 0) 80 | return -1; 81 | 82 | if (pipe(rpipe) < 0) 83 | return -1; 84 | 85 | if (!filename && pipe(wpipe) < 0) { 86 | close(rpipe[0]); 87 | close(rpipe[1]); 88 | return -1; 89 | } 90 | 91 | zh->pid = vfork(); 92 | 93 | switch (zh->pid) { 94 | case -1: 95 | return -1; 96 | 97 | case 0: 98 | to_devnull(STDERR_FILENO); 99 | 100 | if (filename) { 101 | to_devnull(STDIN_FILENO); 102 | } else { 103 | dup2(wpipe[0], STDIN_FILENO); 104 | close(wpipe[0]); 105 | close(wpipe[1]); 106 | } 107 | 108 | dup2(rpipe[1], STDOUT_FILENO); 109 | close(rpipe[0]); 110 | close(rpipe[1]); 111 | 112 | execlp("gzip", "gzip", "-d", "-c", filename, NULL); 113 | exit(-1); 114 | 115 | default: 116 | zh->rfd = rpipe[0]; 117 | zh->wfd = wpipe[1]; 118 | 119 | fcntl(zh->rfd, F_SETFD, fcntl(zh->rfd, F_GETFD) | FD_CLOEXEC); 120 | close(rpipe[1]); 121 | 122 | if (zh->wfd >= 0) { 123 | fcntl(zh->wfd, F_SETFD, 124 | fcntl(zh->wfd, F_GETFD) | FD_CLOEXEC); 125 | close(wpipe[0]); 126 | pthread_create(&zh->thread, NULL, gzip_thread, zh); 127 | } 128 | } 129 | 130 | return 0; 131 | } 132 | 133 | ssize_t gzip_read(struct gzip_handle * zh, void *buf, ssize_t len) 134 | { 135 | ssize_t ret; 136 | 137 | do { 138 | ret = read(zh->rfd, buf, len); 139 | } while (ret == -1 && errno != EINTR); 140 | 141 | return ret; 142 | } 143 | 144 | ssize_t gzip_copy(struct gzip_handle * zh, FILE * out, ssize_t len) 145 | { 146 | char buf[4096]; 147 | ssize_t rlen, total = 0; 148 | 149 | while (len > 0) { 150 | rlen = gzip_read(zh, buf, 151 | (len > sizeof(buf)) ? sizeof(buf) : len); 152 | 153 | if (rlen <= 0) 154 | break; 155 | 156 | if (out != NULL) { 157 | if (fwrite(buf, 1, rlen, out) != rlen) 158 | break; 159 | } 160 | 161 | len -= rlen; 162 | total += rlen; 163 | } 164 | 165 | return total; 166 | } 167 | 168 | FILE *gzip_fdopen(struct gzip_handle * zh, const char *filename) 169 | { 170 | memset(zh, 0, sizeof(*zh)); 171 | 172 | if (!filename || gzip_exec(zh, filename) < 0) 173 | return NULL; 174 | 175 | fcntl(zh->rfd, F_SETFL, fcntl(zh->rfd, F_GETFL) & ~O_NONBLOCK); 176 | 177 | return fdopen(zh->rfd, "r"); 178 | } 179 | 180 | int gzip_close(struct gzip_handle *zh) 181 | { 182 | int code = -1; 183 | 184 | if (zh->rfd >= 0) 185 | close(zh->rfd); 186 | 187 | if (zh->wfd >= 0) 188 | close(zh->wfd); 189 | 190 | if (zh->pid > 0) { 191 | kill(zh->pid, SIGKILL); 192 | waitpid(zh->pid, &code, 0); 193 | } 194 | 195 | if (zh->file) 196 | fclose(zh->file); 197 | 198 | if (zh->thread) 199 | pthread_join(zh->thread, NULL); 200 | 201 | sigaction(SIGPIPE, &zh->pipe_sa, NULL); 202 | 203 | return WIFEXITED(code) ? WEXITSTATUS(code) : -1; 204 | } 205 | -------------------------------------------------------------------------------- /utils/update-alternatives.in: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # update-alternatives 3 | # 4 | # Copyright (C) 2001 Carl D. Worth 5 | # 6 | # This program was inspired by the Debian update-alternatives program 7 | # which is Copyright (C) 1995 Ian Jackson. This version of 8 | # update-alternatives is command-line compatible with Debian's for a 9 | # subset of the options, (only --install, --remove, and --help) 10 | # 11 | # This program is free software; you can redistribute it and/or modify 12 | # it under the terms of the GNU General Public License as published by 13 | # the Free Software Foundation; either version 2, or (at your option) 14 | # any later version. 15 | # 16 | # This program is distributed in the hope that it will be useful, 17 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 18 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 | # GNU General Public License for more details. 20 | 21 | set -e 22 | 23 | # admin dir 24 | ad="$OPKG_OFFLINE_ROOT@opkglibdir@/opkg/alternatives" 25 | 26 | usage() { 27 | echo "update-alternatives: $* 28 | 29 | Usage: update-alternatives --install 30 | update-alternatives --remove 31 | update-alternatives --help 32 | is the link pointing to the provided path (ie. /usr/bin/foo). 33 | is the name in $ad/alternatives (ie. foo) 34 | is the name referred to (ie. /usr/bin/foo-extra-spiffy) 35 | is an integer; options with higher numbers are chosen. 36 | " >&2 37 | exit 2 38 | } 39 | 40 | quit() { 41 | echo "update-alternatives: $*" >&2 42 | exit 2 43 | } 44 | 45 | register_alt() { 46 | [ $# -lt 2 ] && return 1 47 | local name="$1" 48 | local link="$2" 49 | 50 | if [ ! -d $ad ]; then 51 | mkdir -p $ad 52 | fi 53 | 54 | if [ -e "$ad/$name" ]; then 55 | local olink=`head -n 1 $ad/$name` 56 | if [ "$link" != "$olink" ]; then 57 | echo "update-alternatives: Error: cannot register alternative $name to $link since it is already registered to $olink" >&2 58 | return 1 59 | fi 60 | else 61 | echo "$link" > "$ad/$name" 62 | fi 63 | 64 | return 0 65 | } 66 | 67 | protect_slashes() { 68 | sed -e 's/\//\\\//g' 69 | } 70 | 71 | remove_alt() { 72 | [ $# -lt 2 ] && return 1 73 | local name="$1" 74 | local path="$2" 75 | 76 | [ ! -f $ad/$name ] && return 0 77 | 78 | path=`echo $path | protect_slashes` 79 | sed -ne "/^$path\>.*/!p" $ad/$name > $ad/$name.new 80 | mv $ad/$name.new $ad/$name 81 | } 82 | 83 | add_alt() { 84 | [ $# -lt 3 ] && return 1 85 | local name="$1" 86 | local path="$2" 87 | local priority="$3" 88 | remove_alt $name $path 89 | echo "$path $priority" >> $ad/$name 90 | } 91 | 92 | find_best_alt() { 93 | [ $# -lt 1 ] && return 1 94 | [ ! -f $ad/$name ] && return 0 95 | 96 | link=$OPKG_OFFLINE_ROOT/`head -n 1 $ad/$name` 97 | 98 | prio=`sed -ne "1!p" $ad/$name | sed -e "s/\(.*\) \(.*\)/\2 \1/g" | sort -nr | head -n 1 | sed 's/ [^ ]*$//'` 99 | if [ -z "$prio" ]; then 100 | echo "update-alternatives: removing $link as no more alternatives exist for it" 101 | rm $ad/$name 102 | if [ -L $link ]; then 103 | rm $link 104 | fi 105 | return 0 106 | fi 107 | 108 | ## Find last line with highest priority. 109 | path=`grep "${prio}$" $ad/$name | tail -n 1 | sed 's/ [^ ]*$//'` 110 | 111 | if [ ! -e $link -o -L $link ]; then 112 | local link_dir=`dirname $link` 113 | if [ ! -d $link_dir ]; then 114 | mkdir -p $link_dir 115 | fi 116 | if [ -h $link -a -d $link ]; then 117 | # If $link exists and the target is a directory, 118 | # 'ln -sf $path $link' doesn't replace the link to 119 | # that directory, it creates new link inside. 120 | echo "update-alternatives: Removing $link". 121 | rm -f $link 122 | fi 123 | ln -sf $path $link 124 | echo "update-alternatives: Linking $link to $path" 125 | else 126 | echo "update-alternatives: Error: not linking $link to $path since $link exists and is not a link" 127 | return 1 128 | fi 129 | 130 | return 0 131 | } 132 | 133 | do_install() { 134 | if [ $# -lt 4 ]; then 135 | usage "--install needs " 136 | fi 137 | local link="$1" 138 | local name="$2" 139 | local path="$3" 140 | local priority="$4" 141 | 142 | path=`echo $path | sed 's|/\+|/|g'` 143 | 144 | # This is a bad hack, but I haven't thought of a cleaner solution yet... 145 | [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"` 146 | 147 | register_alt $name $link 148 | add_alt $name $path $priority 149 | find_best_alt $name 150 | } 151 | 152 | do_remove() { 153 | if [ $# -lt 2 ]; then 154 | usage "--remove needs " 155 | fi 156 | local name="$1" 157 | local path="$2" 158 | 159 | path=`echo $path | sed 's|/\+|/|g'` 160 | 161 | # This is a bad hack, but I haven't thought of a cleaner solution yet... 162 | [ -n "$OPKG_OFFLINE_ROOT" ] && path=`echo $path | sed "s|^$OPKG_OFFLINE_ROOT/*|/|"` 163 | 164 | remove_alt $name $path 165 | find_best_alt $name 166 | } 167 | 168 | ### 169 | # update-alternatives "main" 170 | ### 171 | 172 | while [ $# -gt 0 ]; do 173 | arg="$1" 174 | shift 175 | 176 | case $arg in 177 | --help) 178 | usage "help:" 179 | exit 0 180 | ;; 181 | --install) 182 | do_install $* 183 | exit $? 184 | ;; 185 | --remove) 186 | do_remove $* 187 | exit $? 188 | ;; 189 | *) 190 | usage "unknown argument \`$arg'" 191 | ;; 192 | esac 193 | done 194 | 195 | usage "at least one of --install or --remove must appear" 196 | 197 | exit 0 198 | -------------------------------------------------------------------------------- /tests/libopkg_test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | int opkg_state_changed; 9 | pkg_t *find_pkg = NULL; 10 | 11 | #define TEST_PACKAGE "aspell" 12 | 13 | static void progress_callback(const opkg_progress_data_t * progress, void *data) 14 | { 15 | printf("\r%s %3d%%\n", (char *)data, progress->percentage); 16 | fflush(stdout); 17 | } 18 | 19 | static void list_pkg(pkg_t * pkg) 20 | { 21 | char *v = pkg_version_str_alloc(pkg); 22 | printf("%s - %s\n", pkg->name, v); 23 | free(v); 24 | } 25 | 26 | static void package_list_installed_callback(pkg_t * pkg, void *data) 27 | { 28 | if (pkg->state_status == SS_INSTALLED) 29 | list_pkg(pkg); 30 | } 31 | 32 | static void package_list_callback(pkg_t * pkg, void *data) 33 | { 34 | static int install_count = 0; 35 | static int total_count = 0; 36 | 37 | if (pkg->state_status == SS_INSTALLED) 38 | install_count++; 39 | 40 | total_count++; 41 | 42 | printf("\rPackage count: %d Installed, %d Total Available", 43 | install_count, total_count); 44 | fflush(stdout); 45 | 46 | if (!find_pkg) { 47 | /* store the first package to print out later */ 48 | find_pkg = pkg; 49 | } 50 | } 51 | 52 | static void package_list_upgradable_callback(pkg_t * pkg, void *data) 53 | { 54 | list_pkg(pkg); 55 | } 56 | 57 | static void print_package(pkg_t * pkg) 58 | { 59 | char *v = pkg_version_str_alloc(pkg); 60 | const char *tags = pkg_get_string(pkg, PKG_TAGS); 61 | 62 | printf("Name: %s\n" 63 | "Version: %s\n" 64 | "Repository: %s\n" 65 | "Architecture: %s\n" 66 | "Description: %s\n" 67 | "Tags: %s\n" 68 | "Size: %lu\n" 69 | "Status: %d\n", 70 | pkg->name, 71 | v, 72 | pkg->src->name, 73 | pkg_get_architecture(pkg), 74 | pkg_get_string(pkg, PKG_DESCRIPTION), 75 | tags ? tags : "", 76 | (unsigned long) pkg_get_int(pkg, PKG_SIZE), pkg->state_status); 77 | free(v); 78 | } 79 | 80 | int main(int argc, char **argv) 81 | { 82 | pkg_t *pkg; 83 | int err; 84 | 85 | if (argc < 2) { 86 | printf("Usage: %s command\n" 87 | "\nCommands:\n" 88 | "\tupdate - Update package lists\n" 89 | "\tfind [package] - Print details of the specified package\n" 90 | "\tinstall [package] - Install the specified package\n" 91 | "\tupgrade [package] - Upgrade the specified package\n" 92 | "\tlist upgrades - List the available upgrades\n" 93 | "\tlist all - List all available packages\n" 94 | "\tlist installed - List all the installed packages\n" 95 | "\tremove [package] - Remove the specified package\n" 96 | "\trping - Reposiroties ping, check the accessibility of repositories\n" 97 | "\ttest - Run test script\n", basename(argv[0])); 98 | exit(0); 99 | } 100 | 101 | setenv("OFFLINE_ROOT", "/tmp", 0); 102 | 103 | if (opkg_new()) { 104 | printf("opkg_new() failed. This sucks.\n"); 105 | print_error_list(); 106 | return 1; 107 | } 108 | 109 | switch (argv[1][0]) { 110 | case 'f': 111 | pkg = opkg_find_package(argv[2], NULL, NULL, NULL); 112 | if (pkg) { 113 | print_package(pkg); 114 | } else 115 | printf("Package \"%s\" not found!\n", find_pkg->name); 116 | break; 117 | case 'i': 118 | err = 119 | opkg_install_package(argv[2], progress_callback, 120 | "Installing..."); 121 | printf("\nopkg_install_package returned %d\n", err); 122 | break; 123 | 124 | case 'u': 125 | if (argv[1][2] == 'd') { 126 | err = 127 | opkg_update_package_lists(progress_callback, 128 | "Updating..."); 129 | printf("\nopkg_update_package_lists returned %d\n", 130 | err); 131 | break; 132 | } else { 133 | if (argc < 3) { 134 | err = 135 | opkg_upgrade_all(progress_callback, 136 | "Upgrading all..."); 137 | printf("\nopkg_upgrade_all returned %d\n", err); 138 | } else { 139 | err = 140 | opkg_upgrade_package(argv[2], 141 | progress_callback, 142 | "Upgrading..."); 143 | printf("\nopkg_upgrade_package returned %d\n", 144 | err); 145 | } 146 | } 147 | break; 148 | 149 | case 'l': 150 | if (argc < 3) { 151 | printf 152 | ("Please specify one either all, installed or upgrades\n"); 153 | } else { 154 | switch (argv[2][0]) { 155 | case 'u': 156 | printf("Listing upgradable packages...\n"); 157 | opkg_list_upgradable_packages 158 | (package_list_upgradable_callback, NULL); 159 | break; 160 | case 'a': 161 | printf("Listing all packages...\n"); 162 | opkg_list_packages(package_list_callback, NULL); 163 | printf("\n"); 164 | break; 165 | case 'i': 166 | printf("Listing installed packages...\n"); 167 | opkg_list_packages 168 | (package_list_installed_callback, NULL); 169 | break; 170 | default: 171 | printf("Unknown list option \"%s\"\n", argv[2]); 172 | } 173 | } 174 | break; 175 | 176 | case 'r': 177 | if (argv[1][1] == 'e') { 178 | err = 179 | opkg_remove_package(argv[2], progress_callback, 180 | "Removing..."); 181 | printf("\nopkg_remove_package returned %d\n", err); 182 | break; 183 | } else if (argv[1][1] == 'p') { 184 | err = opkg_repository_accessibility_check(); 185 | printf 186 | ("\nopkg_repository_accessibility_check returned (%d)\n", 187 | err); 188 | break; 189 | } 190 | 191 | default: 192 | printf("Unknown command \"%s\"\n", argv[1]); 193 | } 194 | 195 | opkg_free(); 196 | 197 | return 0; 198 | } 199 | -------------------------------------------------------------------------------- /libopkg/hash_table.c: -------------------------------------------------------------------------------- 1 | /* hash.c - hash tables for opkg 2 | 3 | Steven M. Ayer, Jamey Hicks 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include 20 | #include 21 | #include "hash_table.h" 22 | #include "opkg_message.h" 23 | #include "libbb/libbb.h" 24 | 25 | static unsigned long djb2_hash(const unsigned char *str) 26 | { 27 | unsigned long hash = 5381; 28 | int c; 29 | while ((c = *str++)) 30 | hash = ((hash << 5) + hash) + c; /* hash * 33 + c */ 31 | return hash; 32 | } 33 | 34 | static int hash_index(hash_table_t * hash, const char *key) 35 | { 36 | return djb2_hash((const unsigned char *)key) % hash->n_buckets; 37 | } 38 | 39 | /* 40 | * this is an open table keyed by strings 41 | */ 42 | void hash_table_init(const char *name, hash_table_t * hash, int len) 43 | { 44 | if (hash->entries != NULL) { 45 | opkg_msg(ERROR, "Internal error: non empty hash table.\n"); 46 | return; 47 | } 48 | 49 | memset(hash, 0, sizeof(hash_table_t)); 50 | 51 | hash->name = name; 52 | hash->n_buckets = len; 53 | hash->entries = xcalloc(hash->n_buckets, sizeof(hash_entry_t)); 54 | } 55 | 56 | void hash_print_stats(hash_table_t * hash) 57 | { 58 | printf("hash_table: %s, %d bytes\n" 59 | "\tn_buckets=%d, n_elements=%d, n_collisions=%d\n" 60 | "\tmax_bucket_len=%d, n_used_buckets=%d, ave_bucket_len=%.2f\n" 61 | "\tn_hits=%d, n_misses=%d\n", 62 | hash->name, 63 | hash->n_buckets * (int)sizeof(hash_entry_t), 64 | hash->n_buckets, 65 | hash->n_elements, 66 | hash->n_collisions, 67 | hash->max_bucket_len, 68 | hash->n_used_buckets, 69 | (hash->n_used_buckets ? 70 | ((float)hash->n_elements) / hash->n_used_buckets : 0.0f), 71 | hash->n_hits, hash->n_misses); 72 | } 73 | 74 | void hash_table_deinit(hash_table_t * hash) 75 | { 76 | int i; 77 | if (!hash) 78 | return; 79 | 80 | /* free the reminaing entries */ 81 | for (i = 0; i < hash->n_buckets; i++) { 82 | hash_entry_t *hash_entry = (hash->entries + i); 83 | free(hash_entry->key); 84 | /* skip the first entry as this is part of the array */ 85 | hash_entry = hash_entry->next; 86 | while (hash_entry) { 87 | hash_entry_t *old = hash_entry; 88 | hash_entry = hash_entry->next; 89 | free(old->key); 90 | free(old); 91 | } 92 | } 93 | 94 | free(hash->entries); 95 | 96 | hash->entries = NULL; 97 | hash->n_buckets = 0; 98 | } 99 | 100 | void *hash_table_get(hash_table_t * hash, const char *key) 101 | { 102 | int ndx = hash_index(hash, key); 103 | hash_entry_t *hash_entry = hash->entries + ndx; 104 | while (hash_entry) { 105 | if (hash_entry->key) { 106 | if (strcmp(key, hash_entry->key) == 0) { 107 | hash->n_hits++; 108 | return hash_entry->data; 109 | } 110 | } 111 | hash_entry = hash_entry->next; 112 | } 113 | hash->n_misses++; 114 | return NULL; 115 | } 116 | 117 | int hash_table_insert(hash_table_t * hash, const char *key, void *value) 118 | { 119 | int bucket_len = 0; 120 | int ndx = hash_index(hash, key); 121 | hash_entry_t *hash_entry = hash->entries + ndx; 122 | if (hash_entry->key) { 123 | if (strcmp(hash_entry->key, key) == 0) { 124 | /* alread in table, update the value */ 125 | hash_entry->data = value; 126 | return 0; 127 | } else { 128 | /* 129 | * if this is a collision, we have to go to the end of the ll, 130 | * then add a new entry 131 | * before we can hook up the value 132 | */ 133 | while (hash_entry->next) { 134 | hash_entry = hash_entry->next; 135 | if (strcmp(hash_entry->key, key) == 0) { 136 | hash_entry->data = value; 137 | return 0; 138 | } 139 | bucket_len++; 140 | } 141 | hash_entry->next = xcalloc(1, sizeof(hash_entry_t)); 142 | hash_entry = hash_entry->next; 143 | hash_entry->next = NULL; 144 | 145 | hash->n_collisions++; 146 | if (++bucket_len > hash->max_bucket_len) 147 | hash->max_bucket_len = bucket_len; 148 | } 149 | } else 150 | hash->n_used_buckets++; 151 | 152 | hash->n_elements++; 153 | hash_entry->key = xstrdup(key); 154 | hash_entry->data = value; 155 | 156 | return 0; 157 | } 158 | 159 | int hash_table_remove(hash_table_t * hash, const char *key) 160 | { 161 | int ndx = hash_index(hash, key); 162 | hash_entry_t *hash_entry = hash->entries + ndx; 163 | hash_entry_t *next_entry = NULL, *last_entry = NULL; 164 | while (hash_entry) { 165 | if (hash_entry->key) { 166 | if (strcmp(key, hash_entry->key) == 0) { 167 | free(hash_entry->key); 168 | if (last_entry) { 169 | last_entry->next = hash_entry->next; 170 | free(hash_entry); 171 | } else { 172 | next_entry = hash_entry->next; 173 | if (next_entry) { 174 | memmove(hash_entry, next_entry, 175 | sizeof(hash_entry_t)); 176 | free(next_entry); 177 | } else { 178 | memset(hash_entry, 0, 179 | sizeof(hash_entry_t)); 180 | } 181 | } 182 | return 1; 183 | } 184 | } 185 | last_entry = hash_entry; 186 | hash_entry = hash_entry->next; 187 | } 188 | return 0; 189 | } 190 | 191 | void hash_table_foreach(hash_table_t * hash, 192 | void (*f) (const char *key, void *entry, void *data), 193 | void *data) 194 | { 195 | int i; 196 | if (!hash || !f) 197 | return; 198 | 199 | for (i = 0; i < hash->n_buckets; i++) { 200 | hash_entry_t *hash_entry = (hash->entries + i); 201 | do { 202 | if (hash_entry->key) { 203 | f(hash_entry->key, hash_entry->data, data); 204 | } 205 | } while ((hash_entry = hash_entry->next)); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /libopkg/pkg_vec.c: -------------------------------------------------------------------------------- 1 | /* pkg_vec.c - the opkg package management system 2 | 3 | Steven M. Ayer 4 | 5 | Copyright (C) 2002 Compaq Computer Corporation 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #include 19 | #include 20 | 21 | #include "pkg.h" 22 | #include "opkg_message.h" 23 | #include "libbb/libbb.h" 24 | 25 | pkg_vec_t *pkg_vec_alloc(void) 26 | { 27 | pkg_vec_t *vec = xcalloc(1, sizeof(pkg_vec_t)); 28 | vec->pkgs = NULL; 29 | vec->len = 0; 30 | 31 | return vec; 32 | } 33 | 34 | void pkg_vec_free(pkg_vec_t * vec) 35 | { 36 | if (!vec) 37 | return; 38 | 39 | if (vec->pkgs) 40 | free(vec->pkgs); 41 | 42 | free(vec); 43 | } 44 | 45 | /* 46 | * assumption: all names in a vector are identical 47 | * assumption: all version strings are trimmed, 48 | * so identical versions have identical version strings, 49 | * implying identical packages; let's marry these 50 | */ 51 | void pkg_vec_insert_merge(pkg_vec_t * vec, pkg_t * pkg, int set_status) 52 | { 53 | int i; 54 | int found = 0; 55 | char *pkg_version = pkg_get_string(pkg, PKG_VERSION); 56 | char *pkg_architecture = pkg_get_architecture(pkg); 57 | char *vec_architecture; 58 | 59 | /* look for a duplicate pkg by name, version, and architecture */ 60 | for (i = 0; i < vec->len; i++) { 61 | vec_architecture = pkg_get_architecture(vec->pkgs[i]); 62 | 63 | opkg_msg(DEBUG2, "%s %s arch=%s vs. %s %s arch=%s.\n", 64 | pkg->name, pkg_version, pkg_architecture, 65 | vec->pkgs[i]->name, pkg_get_string(vec->pkgs[i], PKG_VERSION), 66 | vec_architecture); 67 | /* if the name,ver,arch matches, or the name matches and the 68 | * package is marked deinstall/hold */ 69 | if ((!strcmp(pkg->name, vec->pkgs[i]->name)) 70 | && ((pkg->state_want == SW_DEINSTALL 71 | && (pkg->state_flag & SF_HOLD)) 72 | || ((pkg_compare_versions(pkg, vec->pkgs[i]) == 0) 73 | && (!strcmp(pkg_architecture, vec_architecture))))) { 74 | found = 1; 75 | opkg_msg(DEBUG2, 76 | "Duplicate for pkg=%s version=%s arch=%s.\n", 77 | pkg->name, pkg_version, pkg_architecture); 78 | break; 79 | } 80 | } 81 | 82 | /* we didn't find one, add it */ 83 | if (!found) { 84 | opkg_msg(DEBUG2, "Adding new pkg=%s version=%s arch=%s.\n", 85 | pkg->name, pkg_version, pkg_architecture); 86 | pkg_vec_insert(vec, pkg); 87 | return; 88 | } 89 | 90 | /* update the one that we have */ 91 | opkg_msg(DEBUG2, "Merging %s %s arch=%s, set_status=%d.\n", 92 | pkg->name, pkg_version, pkg_architecture, set_status); 93 | if (set_status) { 94 | /* This is from the status file, 95 | * so need to merge with existing database */ 96 | pkg_merge(pkg, vec->pkgs[i]); 97 | } 98 | 99 | /* overwrite the old one */ 100 | pkg_deinit(vec->pkgs[i]); 101 | free(vec->pkgs[i]); 102 | vec->pkgs[i] = pkg; 103 | } 104 | 105 | void pkg_vec_insert(pkg_vec_t * vec, const pkg_t * pkg) 106 | { 107 | vec->pkgs = xrealloc(vec->pkgs, (vec->len + 1) * sizeof(pkg_t *)); 108 | vec->pkgs[vec->len] = (pkg_t *) pkg; 109 | vec->len++; 110 | } 111 | 112 | int pkg_vec_contains(pkg_vec_t * vec, pkg_t * apkg) 113 | { 114 | int i; 115 | for (i = 0; i < vec->len; i++) 116 | if (vec->pkgs[i] == apkg) 117 | return 1; 118 | return 0; 119 | } 120 | 121 | void pkg_vec_sort(pkg_vec_t * vec, compare_fcn_t compar) 122 | { 123 | qsort(vec->pkgs, vec->len, sizeof(pkg_t *), compar); 124 | } 125 | 126 | int pkg_vec_clear_marks(pkg_vec_t * vec) 127 | { 128 | int npkgs = vec->len; 129 | int i; 130 | for (i = 0; i < npkgs; i++) { 131 | pkg_t *pkg = vec->pkgs[i]; 132 | pkg->state_flag &= ~SF_MARKED; 133 | } 134 | return 0; 135 | } 136 | 137 | int pkg_vec_mark_if_matches(pkg_vec_t * vec, const char *pattern) 138 | { 139 | int matching_count = 0; 140 | pkg_t **pkgs = vec->pkgs; 141 | int npkgs = vec->len; 142 | int i; 143 | abstract_pkg_t **providers, *provider; 144 | 145 | for (i = 0; i < npkgs; i++) { 146 | pkg_t *pkg = pkgs[i]; 147 | if (fnmatch(pattern, pkg->name, 0) == 0) { 148 | pkg->state_flag |= SF_MARKED; 149 | matching_count++; 150 | } 151 | else { 152 | providers = pkg_get_ptr(pkg, PKG_PROVIDES); 153 | while (providers && *providers) { 154 | provider = *providers++; 155 | if (fnmatch(pattern, provider->name, 0) == 0) { 156 | pkg->state_flag |= SF_MARKED; 157 | matching_count++; 158 | } 159 | } 160 | } 161 | } 162 | return matching_count; 163 | } 164 | 165 | abstract_pkg_vec_t *abstract_pkg_vec_alloc(void) 166 | { 167 | abstract_pkg_vec_t *vec; 168 | vec = xcalloc(1, sizeof(abstract_pkg_vec_t)); 169 | vec->pkgs = NULL; 170 | vec->len = 0; 171 | 172 | return vec; 173 | } 174 | 175 | void abstract_pkg_vec_free(abstract_pkg_vec_t * vec) 176 | { 177 | if (!vec) 178 | return; 179 | free(vec->pkgs); 180 | free(vec); 181 | } 182 | 183 | /* 184 | * assumption: all names in a vector are unique 185 | */ 186 | void abstract_pkg_vec_insert(abstract_pkg_vec_t * vec, abstract_pkg_t * pkg) 187 | { 188 | vec->pkgs = 189 | xrealloc(vec->pkgs, (vec->len + 1) * sizeof(abstract_pkg_t *)); 190 | vec->pkgs[vec->len] = pkg; 191 | vec->len++; 192 | } 193 | 194 | abstract_pkg_t *abstract_pkg_vec_get(abstract_pkg_vec_t * vec, int i) 195 | { 196 | if (vec->len > i) 197 | return vec->pkgs[i]; 198 | else 199 | return NULL; 200 | } 201 | 202 | int abstract_pkg_vec_contains(abstract_pkg_vec_t * vec, abstract_pkg_t * apkg) 203 | { 204 | int i; 205 | for (i = 0; i < vec->len; i++) 206 | if (vec->pkgs[i] == apkg) 207 | return 1; 208 | return 0; 209 | } 210 | 211 | void abstract_pkg_vec_sort(abstract_pkg_vec_t * vec, compare_fcn_t compar) 212 | { 213 | qsort(vec->pkgs, vec->len, sizeof(pkg_t *), compar); 214 | } 215 | 216 | int pkg_compare_names(const void *p1, const void *p2) 217 | { 218 | const pkg_t *pkg1 = *(const pkg_t **)p1; 219 | const pkg_t *pkg2 = *(const pkg_t **)p2; 220 | if (pkg1->name == NULL) 221 | return 1; 222 | if (pkg2->name == NULL) 223 | return -1; 224 | return (strcmp(pkg1->name, pkg2->name)); 225 | } 226 | -------------------------------------------------------------------------------- /libbb/copy_file.c: -------------------------------------------------------------------------------- 1 | /* vi: set sw=4 ts=4: */ 2 | /* 3 | * Mini copy_file implementation for busybox 4 | * 5 | * 6 | * Copyright (C) 2001 by Matt Kraai 7 | * 8 | * This program is free software; you can redistribute it and/or modify 9 | * it under the terms of the GNU General Public License as published by 10 | * the Free Software Foundation; either version 2 of the License, or 11 | * (at your option) any later version. 12 | * 13 | * This program is distributed in the hope that it will be useful, 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 | * General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU General Public License 19 | * along with this program; if not, write to the Free Software 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 | * 22 | */ 23 | 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | #include "libbb.h" 35 | 36 | int copy_file(const char *source, const char *dest, int flags) 37 | { 38 | struct stat source_stat; 39 | struct stat dest_stat; 40 | int dest_exists = 1; 41 | int status = 0; 42 | 43 | if (((flags & FILEUTILS_PRESERVE_SYMLINKS) && 44 | lstat(source, &source_stat) < 0) || 45 | (!(flags & FILEUTILS_PRESERVE_SYMLINKS) && 46 | stat(source, &source_stat) < 0)) { 47 | perror_msg("%s", source); 48 | return -1; 49 | } 50 | 51 | if (stat(dest, &dest_stat) < 0) { 52 | if (errno != ENOENT) { 53 | perror_msg("unable to stat `%s'", dest); 54 | return -1; 55 | } 56 | dest_exists = 0; 57 | } 58 | 59 | if (dest_exists && source_stat.st_rdev == dest_stat.st_rdev && 60 | source_stat.st_ino == dest_stat.st_ino) { 61 | error_msg("`%s' and `%s' are the same file", source, dest); 62 | return -1; 63 | } 64 | 65 | if (S_ISDIR(source_stat.st_mode)) { 66 | DIR *dp; 67 | struct dirent *d; 68 | mode_t saved_umask = 0; 69 | 70 | if (!(flags & FILEUTILS_RECUR)) { 71 | error_msg("%s: omitting directory", source); 72 | return -1; 73 | } 74 | 75 | /* Create DEST. */ 76 | if (dest_exists) { 77 | if (!S_ISDIR(dest_stat.st_mode)) { 78 | error_msg("`%s' is not a directory", dest); 79 | return -1; 80 | } 81 | } else { 82 | mode_t mode; 83 | saved_umask = umask(0); 84 | 85 | mode = source_stat.st_mode; 86 | if (!(flags & FILEUTILS_PRESERVE_STATUS)) 87 | mode = source_stat.st_mode & ~saved_umask; 88 | mode |= S_IRWXU; 89 | 90 | if (mkdir(dest, mode) < 0) { 91 | umask(saved_umask); 92 | perror_msg("cannot create directory `%s'", 93 | dest); 94 | return -1; 95 | } 96 | 97 | umask(saved_umask); 98 | } 99 | 100 | /* Recursively copy files in SOURCE. */ 101 | if ((dp = opendir(source)) == NULL) { 102 | perror_msg("unable to open directory `%s'", source); 103 | status = -1; 104 | goto end; 105 | } 106 | 107 | while ((d = readdir(dp)) != NULL) { 108 | char *new_source, *new_dest; 109 | 110 | if (strcmp(d->d_name, ".") == 0 || 111 | strcmp(d->d_name, "..") == 0) 112 | continue; 113 | 114 | new_source = concat_path_file(source, d->d_name); 115 | new_dest = concat_path_file(dest, d->d_name); 116 | if (copy_file(new_source, new_dest, flags) < 0) 117 | status = -1; 118 | free(new_source); 119 | free(new_dest); 120 | } 121 | 122 | /* ??? What if an error occurs in readdir? */ 123 | 124 | if (closedir(dp) < 0) { 125 | perror_msg("unable to close directory `%s'", source); 126 | status = -1; 127 | } 128 | 129 | if (!dest_exists && 130 | chmod(dest, source_stat.st_mode & ~saved_umask) < 0) { 131 | perror_msg("unable to change permissions of `%s'", 132 | dest); 133 | status = -1; 134 | } 135 | } else if (S_ISREG(source_stat.st_mode)) { 136 | FILE *sfp, *dfp; 137 | 138 | if (dest_exists) { 139 | if ((dfp = fopen(dest, "w")) == NULL) { 140 | if (!(flags & FILEUTILS_FORCE)) { 141 | perror_msg("unable to open `%s'", dest); 142 | return -1; 143 | } 144 | 145 | if (unlink(dest) < 0) { 146 | perror_msg("unable to remove `%s'", 147 | dest); 148 | return -1; 149 | } 150 | 151 | dest_exists = 0; 152 | } 153 | } 154 | 155 | if (!dest_exists) { 156 | int fd; 157 | 158 | if ((fd = 159 | open(dest, O_WRONLY | O_CREAT, 160 | source_stat.st_mode)) < 0 161 | || (dfp = fdopen(fd, "w")) == NULL) { 162 | if (fd >= 0) 163 | close(fd); 164 | perror_msg("unable to open `%s'", dest); 165 | return -1; 166 | } 167 | } 168 | 169 | if ((sfp = fopen(source, "r")) == NULL) { 170 | fclose(dfp); 171 | perror_msg("unable to open `%s'", source); 172 | status = -1; 173 | goto end; 174 | } 175 | 176 | if (copy_file_chunk(sfp, dfp, -1) < 0) 177 | status = -1; 178 | 179 | if (fclose(dfp) < 0) { 180 | perror_msg("unable to close `%s'", dest); 181 | status = -1; 182 | } 183 | 184 | if (fclose(sfp) < 0) { 185 | perror_msg("unable to close `%s'", source); 186 | status = -1; 187 | } 188 | } else if (S_ISBLK(source_stat.st_mode) || S_ISCHR(source_stat.st_mode) 189 | || S_ISSOCK(source_stat.st_mode)) { 190 | if (mknod(dest, source_stat.st_mode, source_stat.st_rdev) < 0) { 191 | perror_msg("unable to create `%s'", dest); 192 | return -1; 193 | } 194 | } else if (S_ISFIFO(source_stat.st_mode)) { 195 | if (mkfifo(dest, source_stat.st_mode) < 0) { 196 | perror_msg("cannot create fifo `%s'", dest); 197 | return -1; 198 | } 199 | } else if (S_ISLNK(source_stat.st_mode)) { 200 | char *lpath = xreadlink(source); 201 | if (symlink(lpath, dest) < 0) { 202 | perror_msg("cannot create symlink `%s'", dest); 203 | return -1; 204 | } 205 | free(lpath); 206 | 207 | #if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1) 208 | if (flags & FILEUTILS_PRESERVE_STATUS) 209 | if (lchown(dest, source_stat.st_uid, source_stat.st_gid) 210 | < 0) 211 | perror_msg 212 | ("unable to preserve ownership of `%s'", 213 | dest); 214 | #endif 215 | return 0; 216 | } else { 217 | error_msg("internal error: unrecognized file type"); 218 | return -1; 219 | } 220 | 221 | end: 222 | 223 | if (flags & FILEUTILS_PRESERVE_STATUS) { 224 | struct utimbuf times; 225 | 226 | times.actime = source_stat.st_atime; 227 | times.modtime = source_stat.st_mtime; 228 | if (utime(dest, ×) < 0) 229 | perror_msg("unable to preserve times of `%s'", dest); 230 | if (chown(dest, source_stat.st_uid, source_stat.st_gid) < 0) { 231 | source_stat.st_mode &= ~(S_ISUID | S_ISGID); 232 | perror_msg("unable to preserve ownership of `%s'", 233 | dest); 234 | } 235 | if (chmod(dest, source_stat.st_mode) < 0) 236 | perror_msg("unable to preserve permissions of `%s'", 237 | dest); 238 | } 239 | 240 | return status; 241 | } 242 | -------------------------------------------------------------------------------- /libopkg/pkg.h: -------------------------------------------------------------------------------- 1 | /* pkg.h - the opkg package management system 2 | 3 | Carl D. Worth 4 | 5 | Copyright (C) 2001 University of Southern California 6 | 7 | This program is free software; you can redistribute it and/or 8 | modify it under the terms of the GNU General Public License as 9 | published by the Free Software Foundation; either version 2, or (at 10 | your option) any later version. 11 | 12 | This program is distributed in the hope that it will be useful, but 13 | WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 | General Public License for more details. 16 | */ 17 | 18 | #ifndef PKG_H 19 | #define PKG_H 20 | 21 | #include 22 | #include 23 | 24 | #include "pkg_vec.h" 25 | #include "str_list.h" 26 | #include "active_list.h" 27 | #include "pkg_src.h" 28 | #include "pkg_dest.h" 29 | #include "opkg_conf.h" 30 | #include "conffile_list.h" 31 | 32 | struct opkg_conf; 33 | 34 | #ifndef ARRAY_SIZE 35 | #define ARRAY_SIZE(array) sizeof(array) / sizeof((array)[0]) 36 | #endif 37 | 38 | /* I think "Size" is currently the shortest field name */ 39 | #define PKG_MINIMUM_FIELD_NAME_LEN 4 40 | 41 | enum pkg_state_want { 42 | SW_UNKNOWN = 1, 43 | SW_INSTALL, 44 | SW_DEINSTALL, 45 | SW_PURGE, 46 | SW_LAST_STATE_WANT 47 | }; 48 | typedef enum pkg_state_want pkg_state_want_t; 49 | 50 | enum pkg_state_flag { 51 | SF_OK = 0, 52 | SF_REINSTREQ = 1, 53 | SF_HOLD = 2, /* do not upgrade version */ 54 | SF_REPLACE = 4, /* replace this package */ 55 | SF_NOPRUNE = 8, /* do not remove obsolete files */ 56 | SF_PREFER = 16, /* prefer this version */ 57 | SF_OBSOLETE = 32, /* old package in upgrade pair */ 58 | SF_MARKED = 64, /* temporary mark */ 59 | SF_FILELIST_CHANGED = 128, /* needs filelist written */ 60 | SF_USER = 256, 61 | SF_NEED_DETAIL = 512, 62 | SF_LAST_STATE_FLAG 63 | }; 64 | typedef enum pkg_state_flag pkg_state_flag_t; 65 | #define SF_NONVOLATILE_FLAGS (SF_HOLD|SF_NOPRUNE|SF_PREFER|SF_OBSOLETE|SF_USER) 66 | 67 | enum pkg_state_status { 68 | SS_NOT_INSTALLED = 1, 69 | SS_UNPACKED, 70 | SS_HALF_CONFIGURED, 71 | SS_INSTALLED, 72 | SS_HALF_INSTALLED, 73 | SS_CONFIG_FILES, 74 | SS_POST_INST_FAILED, 75 | SS_REMOVAL_FAILED, 76 | SS_LAST_STATE_STATUS 77 | }; 78 | typedef enum pkg_state_status pkg_state_status_t; 79 | 80 | enum pkg_fields { 81 | PKG_MAINTAINER, 82 | PKG_PRIORITY, 83 | PKG_SOURCE, 84 | PKG_TAGS, 85 | PKG_SECTION, 86 | PKG_EPOCH, 87 | PKG_FILENAME, 88 | PKG_LOCAL_FILENAME, 89 | PKG_VERSION, 90 | PKG_REVISION, 91 | PKG_DESCRIPTION, 92 | PKG_MD5SUM, 93 | PKG_SHA256SUM, 94 | PKG_SIZE, 95 | PKG_INSTALLED_SIZE, 96 | PKG_INSTALLED_TIME, 97 | PKG_TMP_UNPACK_DIR, 98 | PKG_REPLACES, 99 | PKG_PROVIDES, 100 | PKG_DEPENDS, 101 | PKG_CONFLICTS, 102 | PKG_CONFFILES, 103 | PKG_ALTERNATIVES, 104 | PKG_ABIVERSION, 105 | }; 106 | 107 | struct abstract_pkg { 108 | char *name; 109 | pkg_vec_t *pkgs; 110 | 111 | /* XXX: This should be abstract_pkg_vec_t for consistency. */ 112 | struct abstract_pkg **depended_upon_by; 113 | 114 | abstract_pkg_vec_t *provided_by; 115 | abstract_pkg_vec_t *replaced_by; 116 | 117 | char dependencies_checked; 118 | char pre_dependencies_checked; 119 | pkg_state_status_t state_status:4; 120 | pkg_state_flag_t state_flag:11; 121 | }; 122 | 123 | #include "pkg_depends.h" 124 | 125 | enum pkg_alternative_field { 126 | PAF_PRIO, 127 | PAF_PATH, 128 | PAF_ALTPATH, 129 | __PAF_MAX, 130 | }; 131 | 132 | struct pkg_alternative { 133 | int prio; 134 | char *path; 135 | char *altpath; 136 | }; 137 | 138 | struct pkg_alternatives { 139 | int nalts; 140 | struct pkg_alternative **alts; 141 | }; 142 | 143 | /* XXX: CLEANUP: I'd like to clean up pkg_t in several ways: 144 | 145 | The 3 version fields should go into a single version struct. (This 146 | is especially important since, currently, pkg->version can easily 147 | be mistaken for pkg_verson_str_alloc(pkg) although they are very 148 | distinct. This has been the source of multiple bugs. 149 | 150 | The 3 state fields could possibly also go into their own struct. 151 | 152 | All fields which deal with lists of packages, (Depends, 153 | Pre-Depends, Provides, Suggests, Recommends, Enhances), should each 154 | be handled by a single struct in pkg_t 155 | 156 | All string fields for which there is a small set of possible 157 | values, (section, maintainer, architecture, maybe version?), that 158 | are reused among different packages -- for all such packages we 159 | should move from "char *"s to some atom datatype to share data 160 | storage and use less memory. We might even do reference counting, 161 | but probably not since most often we only create new pkg_t structs, 162 | we don't often free them. */ 163 | struct pkg { 164 | char *name; 165 | pkg_src_t *src; 166 | pkg_dest_t *dest; 167 | pkg_state_want_t state_want:3; 168 | pkg_state_flag_t state_flag:11; 169 | pkg_state_status_t state_status:4; 170 | 171 | abstract_pkg_t *parent; 172 | 173 | /* As pointer for lazy evaluation */ 174 | str_list_t *installed_files; 175 | /* XXX: CLEANUP: I'd like to perhaps come up with a better 176 | mechanism to avoid the problem here, (which is that the 177 | installed_files list was being freed from an inner loop while 178 | still being used within an outer loop. */ 179 | int installed_files_ref_cnt; 180 | 181 | unsigned int essential:1; 182 | /* Adding this flag, to "force" opkg to choose a "provided_by_hand" package, if there are multiple choice */ 183 | unsigned int provided_by_hand:1; 184 | 185 | /* this flag specifies whether the package was installed to satisfy another 186 | * package's dependancies */ 187 | unsigned int auto_installed:1; 188 | unsigned int is_upgrade:1; 189 | 190 | unsigned int arch_index:3; 191 | 192 | struct blob_buf blob; 193 | }; 194 | 195 | pkg_t *pkg_new(void); 196 | void pkg_deinit(pkg_t * pkg); 197 | int pkg_init_from_file(pkg_t * pkg, const char *filename); 198 | 199 | void *pkg_set_raw(pkg_t *pkg, int id, const void *val, size_t len); 200 | void *pkg_get_raw(const pkg_t *pkg, int id); 201 | 202 | static inline int pkg_set_int(pkg_t *pkg, int id, int val) 203 | { 204 | int *res = pkg_set_raw(pkg, id, &val, sizeof(val)); 205 | return res ? *res : 0; 206 | } 207 | 208 | static inline int pkg_get_int(const pkg_t *pkg, int id) 209 | { 210 | int *ptr = pkg_get_raw(pkg, id); 211 | return ptr ? *ptr : 0; 212 | } 213 | 214 | char *pkg_set_string(pkg_t *pkg, int id, const char *s); 215 | 216 | static inline char *pkg_get_string(const pkg_t *pkg, int id) 217 | { 218 | return (char *) pkg_get_raw(pkg, id); 219 | } 220 | 221 | static inline void * pkg_set_ptr(pkg_t *pkg, int id, void *ptr) 222 | { 223 | void **res = pkg_set_raw(pkg, id, &ptr, sizeof(ptr)); 224 | return res ? *res : NULL; 225 | } 226 | 227 | static inline void * pkg_get_ptr(const pkg_t *pkg, int id) 228 | { 229 | void **ptr = pkg_get_raw(pkg, id); 230 | return ptr ? *ptr : NULL; 231 | } 232 | 233 | char *pkg_set_architecture(pkg_t *pkg, const char *architecture, ssize_t len); 234 | char *pkg_get_architecture(const pkg_t *pkg); 235 | int pkg_get_arch_priority(const pkg_t *pkg); 236 | 237 | char *pkg_get_md5(const pkg_t *pkg); 238 | char *pkg_set_md5(pkg_t *pkg, const char *cksum); 239 | 240 | char *pkg_get_sha256(const pkg_t *pkg); 241 | char *pkg_set_sha256(pkg_t *pkg, const char *cksum); 242 | 243 | abstract_pkg_t *abstract_pkg_new(void); 244 | 245 | /* 246 | * merges fields from newpkg into oldpkg. 247 | * Forcibly sets oldpkg state_status, state_want and state_flags 248 | */ 249 | int pkg_merge(pkg_t * oldpkg, pkg_t * newpkg); 250 | 251 | char *pkg_version_str_alloc(pkg_t * pkg); 252 | 253 | int pkg_compare_versions(const pkg_t *pkg, const pkg_t *ref_pkg); 254 | int pkg_name_version_and_architecture_compare(const void *a, const void *b); 255 | int abstract_pkg_name_compare(const void *a, const void *b); 256 | 257 | void pkg_formatted_info(FILE * fp, pkg_t * pkg); 258 | void pkg_formatted_field(FILE * fp, pkg_t * pkg, const char *field); 259 | 260 | void pkg_print_status(pkg_t * pkg, FILE * file); 261 | str_list_t *pkg_get_installed_files(pkg_t * pkg); 262 | void pkg_free_installed_files(pkg_t * pkg); 263 | void pkg_remove_installed_files_list(pkg_t * pkg); 264 | conffile_t *pkg_get_conffile(pkg_t * pkg, const char *file_name); 265 | int pkg_run_script(pkg_t * pkg, const char *script, const char *args); 266 | 267 | /* enum mappings */ 268 | pkg_state_want_t pkg_state_want_from_str(char *str); 269 | pkg_state_flag_t pkg_state_flag_from_str(const char *str); 270 | pkg_state_status_t pkg_state_status_from_str(const char *str); 271 | 272 | int pkg_version_satisfied(pkg_t * it, pkg_t * ref, const char *op); 273 | 274 | int pkg_arch_supported(pkg_t * pkg); 275 | void pkg_info_preinstall_check(void); 276 | 277 | int pkg_write_filelist(pkg_t * pkg); 278 | int pkg_write_changed_filelists(void); 279 | 280 | #endif 281 | --------------------------------------------------------------------------------