├── .gitignore ├── CMakeLists.txt ├── ChangeLog ├── LICENSE ├── RDS ├── .gitignore ├── CMakeLists.txt └── main.c ├── README.md ├── build ├── suppress-cl.supp └── suppress-srv.supp ├── cmake ├── Config │ └── version_conf.h.in └── Modules │ └── FindCheck.cmake ├── connection.cfg ├── distro └── rds.spec ├── docs ├── RTFM.txt ├── garbage_collector_usage_documentation.txt └── ssds.xmind ├── etc ├── rds-client.conf └── rds-server.conf ├── libhif-test ├── makefile └── test.cpp ├── man └── rds.1 ├── protocol.txt ├── required_repos_list.txt ├── requirements.txt ├── src ├── CMakeLists.txt ├── bugzilla │ ├── Makefile │ ├── Makefile_hawkey │ ├── bug.patch │ └── lr_handle_free_issue.c ├── client │ ├── CMakeLists.txt │ ├── README │ ├── client.c │ ├── client.h │ └── client_main.c ├── common │ ├── Makefile │ ├── README │ ├── cfg_parsing.c │ ├── cfg_parsing.h │ ├── detect_missing_repos.c │ ├── detect_missing_repos.h │ ├── errors.h │ ├── globvar.h │ ├── includes.h │ ├── json_create.c │ ├── json_handler.h │ ├── json_read.c │ ├── log_handler.c │ ├── log_handler.h │ ├── mem_management.c │ ├── mem_management.h │ ├── network_security.c │ ├── network_security.h │ ├── network_util.c │ ├── network_util.h │ ├── packages.c │ ├── packages.h │ ├── params.c │ ├── params.h │ ├── repo_handler.c │ ├── repo_handler.h │ ├── repo_metadata.c │ ├── solving.c │ ├── solving.h │ ├── ssds.dtd │ ├── util.c │ └── util.h ├── examples │ ├── Makefile_log │ ├── Makefile_params │ ├── client.c │ ├── hawkey_ex.c │ ├── hawkey_ex.h │ ├── json_improved.c │ ├── json_improved.h │ ├── log_example.c │ ├── param_ex.c │ └── server.c └── server │ ├── Makefile │ ├── README │ ├── server.c │ ├── server.h │ └── server_main.c └── tests ├── CMakeLists.txt ├── test_cfg_parsing.c ├── test_cfg_parsing.h ├── test_dummy.c ├── test_dummy.h ├── test_gc.c ├── test_gc.h ├── test_main.c ├── test_missing_repos.c ├── test_missing_repos.h ├── test_params.c ├── test_params.h ├── test_template.c └── test_template.h /.gitignore: -------------------------------------------------------------------------------- 1 | *CMakeFiles 2 | *Cache.txt 3 | *.o 4 | *ssds-client 5 | *rds-client 6 | build/librepo-* 7 | libhif-test/test 8 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #CMAKE BUILD 1.3 2 | #Usage in CLI: "cmake .","make"; executables are in "/build" folder 3 | 4 | 5 | CMAKE_MINIMUM_REQUIRED(VERSION 2.6.2) 6 | SET(CMAKE_COLOR_MAKEFILE ON) 7 | SET(CMAKE_VERBOSE_MAKEFILE ON) 8 | SET(CMAKE_INCLUDE_CURRENT_DIR TRUE) 9 | 10 | PROJECT(rds) 11 | SET(rds_VERSION_MAJOR 0) 12 | SET(rds_VERSION_MINOR 2) 13 | SET(rds_VERSION_BUILD 0) 14 | SET(rds_VERSION 15 | "${rds_VERSION_MAJOR}.${rds_VERSION_MINOR}.${rds_VERSION_BUILD}") 16 | SET(PACKAGE_VERSION 17 | "${rds_VERSION_MAJOR}.${rds_VERSION_MINOR}.${rds_VERSION_BUILD}") 18 | 19 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules/") 20 | 21 | #pkg-config is needed to find and properly link some libraries 22 | FIND_PACKAGE(PkgConfig) 23 | INCLUDE(FindPkgConfig) 24 | 25 | #GLIB-2.0 26 | PKG_CHECK_MODULES(GLIB2 glib-2.0 REQUIRED) 27 | if (NOT GLIB2_FOUND) 28 | message(FATAL_ERROR "Library Glib-2.0 not found.") 29 | else (NOT GLIB2_FOUND) 30 | include_directories(${GLIB2_INCLUDE_DIRS}) 31 | endif(NOT GLIB2_FOUND) 32 | 33 | #JSON-GLIB-1.0 34 | PKG_CHECK_MODULES(JSON json-glib-1.0 REQUIRED) 35 | if(NOT JSON_FOUND) 36 | message(FATAL_ERROR "Library json-glib-devel not found.") 37 | else (NOT JSON_FOUND) 38 | include_directories(${JSON_INCLUDE_DIRS}) 39 | endif(NOT JSON_FOUND) 40 | 41 | #HAWKEY - 0.5.7 42 | PKG_CHECK_MODULES(LIBDNF libdnf REQUIRED) 43 | if(NOT LIBDNF_FOUND) 44 | message(FATAL_ERROR "Library libdnf not found.") 45 | else(NOT LIBDNF_FOUND) 46 | include_directories(${HAWKEY_INCLUDE_DIRS}) 47 | endif(NOT LIBDNF_FOUND) 48 | 49 | #LIBREPO 50 | PKG_CHECK_MODULES(LIBREPO librepo REQUIRED) 51 | if(NOT LIBREPO_FOUND) 52 | message(FATAL_ERROR "Library librepo not found.") 53 | else (NOT LIBREPO_FOUND) 54 | include_directories(${LIBREPO_INCLUDE_DIRS}) 55 | endif(NOT LIBREPO_FOUND) 56 | 57 | #CHECK 58 | find_package(Check REQUIRED) 59 | include_directories(${CHECKLIB_INCLUDE_DIRS}) 60 | 61 | #HAWKEY VERSION 62 | configure_file(${PROJECT_SOURCE_DIR}/cmake/Config/version_conf.h.in ${PROJECT_SOURCE_DIR}/cmake/Config/version_conf.h) 63 | include_directories(${PROJECT_SOURCE_DIR}/cmake/Config) 64 | 65 | if(CMAKE_COMPILER_IS_GNUCC) 66 | set(CMAKE_C_FLAGS ${CMAKE_C_FLAGS} "-O2 -g -Wall -Wextra -pedantic -std=c11 -fmessage-length=0 -L/usr/include/librepo/ -lrepo -lz -lm -ldl -lpthread -lhawkey -lgobject-2.0 -lrpm -lrpmio -lssl -lcrypto -L/usr/lib") 67 | #original flags for boost lib: -I/usr/local/include -L/usr/local/lib 68 | set(CMAKE_EXE_LINKER_FLAGS "-s") ## Strip binary 69 | endif() 70 | 71 | file(GLOB SRCS *.c *.h) 72 | 73 | #COMMON 74 | set (rds_common_srcs 75 | src/common/util.c 76 | src/common/json_read.c 77 | src/common/json_create.c 78 | src/common/repo_metadata.c 79 | src/common/repo_handler.c 80 | src/common/solving.c 81 | src/common/log_handler.c 82 | src/common/network_util.c 83 | src/common/params.c 84 | src/common/packages.c 85 | src/common/mem_management.c 86 | src/common/cfg_parsing.c 87 | src/common/detect_missing_repos.c 88 | src/common/network_security.c) 89 | set (rds_common_headers 90 | src/common/includes.h 91 | src/common/json_handler.h 92 | src/common/repo_handler.h 93 | src/common/solving.h 94 | src/common/log_handler.h 95 | src/common/network_util.h 96 | src/common/params.h 97 | src/common/packages.h 98 | src/common/mem_management.h 99 | src/common/cfg_parsing.h 100 | src/common/errors.h 101 | src/common/detect_missing_repos.h 102 | src/common/network_security.h) 103 | add_library(lib_rds_common SHARED ${rds_common_srcs} ${rds_common_headers}) 104 | target_link_libraries(lib_rds_common 105 | ${LIBS} 106 | ${GLIB2_LDFLAGS} 107 | ${JSON_LDFLAGS} 108 | ${HAWKEY_LDFLAGS} 109 | ${LIBREPO_LDFLAGS} 110 | ${CHECK_LDFLAGS}) 111 | 112 | #SERVER 113 | set (rds_server_srcs 114 | src/server/server_main.c 115 | src/server/server.c) 116 | set (rds_server_headers 117 | src/server/server.h) 118 | add_library(lib_rds_server STATIC ${rds_server_srcs} ${rds_server_headers}) 119 | target_link_libraries(lib_rds_server 120 | lib_rds_common 121 | ${LIBS} 122 | ${GLIB2_LDFLAGS} 123 | ${JSON_LDFLAGS} 124 | ${HAWKEY_LDFLAGS} 125 | ${LIBREPO_LDFLAGS} 126 | ${CHECK_LDFLAGS}) 127 | 128 | #CLIENT 129 | set (rds_client_srcs 130 | src/client/client_main.c 131 | src/client/client.c) 132 | set (rds_client_headers 133 | src/client/client.h) 134 | add_library(lib_rds_client STATIC ${rds_client_srcs} ${rds_client_headers}) 135 | target_link_libraries(lib_rds_client 136 | lib_rds_common 137 | ${LIBS} 138 | ${GLIB2_LDFLAGS} 139 | ${JSON_LDFLAGS} 140 | ${HAWKEY_LDFLAGS} 141 | ${LIBREPO_LDFLAGS} 142 | ${CHECK_LDFLAGS}) 143 | 144 | 145 | 146 | PROJECT(rds-server) 147 | add_executable(rds-server 148 | ${rds_server_srcs} 149 | ${rds_common_srcs}) 150 | 151 | target_compile_definitions(rds-server PUBLIC __CASE_SERVER) 152 | 153 | #add_library(lib_serv SHARED ${SERVSRC}) 154 | 155 | target_link_libraries( 156 | rds-server 157 | ${LIBS} 158 | ${GLIB2_LDFLAGS} 159 | ${JSON_LDFLAGS} 160 | ${HAWKEY_LDFLAGS} 161 | ${LIBREPO_LDFLAGS} 162 | ${CHECK_LDFLAGS}) 163 | 164 | PROJECT(rds-client) 165 | add_executable(rds-client 166 | ${rds_client_srcs} 167 | ${rds_common_srcs}) 168 | 169 | target_compile_definitions(rds-client PUBLIC __CASE_CLIENT) 170 | 171 | target_link_libraries(rds-client 172 | ${LIBS} 173 | ${GLIB2_LDFLAGS} 174 | ${JSON_LDFLAGS} 175 | ${HAWKEY_LDFLAGS} 176 | ${LIBREPO_LDFLAGS} 177 | ${CHECK_LDFLAGS}) 178 | 179 | file(MAKE_DIRECTORY /tmp/rds/) 180 | #file(MAKE_DIRECTORY /var/cache/rds/packages/) 181 | enable_testing() 182 | add_subdirectory(tests) 183 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | new version 0.3.0 2 | - client installs packages by librpm 3 | - client and server read configuration file 4 | - garbage collector implementation 5 | - several bugfixes 6 | 7 | new version 0.2.0 8 | - client installs packages by system command 9 | - server resolves dependencies 10 | - Code is written in C 11 | - protocol used for communication is JSON. 12 | 13 | new version 0.1.0 14 | - protocol definition 15 | - client class 16 | - server class 17 | - Class for parsing XML 18 | - Class for logging 19 | -------------------------------------------------------------------------------- /RDS/.gitignore: -------------------------------------------------------------------------------- 1 | # This file is used to ignore files which are generated 2 | # ---------------------------------------------------------------------------- 3 | 4 | *~ 5 | *.autosave 6 | *.a 7 | *.core 8 | *.moc 9 | *.o 10 | *.obj 11 | *.orig 12 | *.rej 13 | *.so 14 | *.so.* 15 | *_pch.h.cpp 16 | *_resource.rc 17 | *.qm 18 | .#* 19 | *.*# 20 | core 21 | !core/ 22 | tags 23 | .DS_Store 24 | .directory 25 | *.debug 26 | Makefile* 27 | *.prl 28 | *.app 29 | moc_*.cpp 30 | ui_*.h 31 | qrc_*.cpp 32 | Thumbs.db 33 | *.res 34 | *.rc 35 | /.qmake.cache 36 | /.qmake.stash 37 | 38 | # qtcreator generated files 39 | *.pro.user* 40 | 41 | # xemacs temporary files 42 | *.flc 43 | 44 | # Vim temporary files 45 | .*.swp 46 | 47 | # Visual Studio generated files 48 | *.ib_pdb_index 49 | *.idb 50 | *.ilk 51 | *.pdb 52 | *.sln 53 | *.suo 54 | *.vcproj 55 | *vcproj.*.*.user 56 | *.ncb 57 | *.sdf 58 | *.opensdf 59 | *.vcxproj 60 | *vcxproj.* 61 | 62 | # MinGW generated files 63 | *.Debug 64 | *.Release 65 | 66 | # Python byte code 67 | *.pyc 68 | 69 | # Binaries 70 | # -------- 71 | *.dll 72 | *.exe 73 | 74 | -------------------------------------------------------------------------------- /RDS/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(SSDS) 2 | cmake_minimum_required(VERSION 2.8) 3 | aux_source_directory(. SRC_LIST) 4 | add_executable(${PROJECT_NAME} ${SRC_LIST}) 5 | -------------------------------------------------------------------------------- /RDS/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char *argv[]) 4 | { 5 | printf("Hello World!\n"); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | server-side-dependency-solving - SSDS 2 | ============================== 3 | 4 | Description 5 | =========== 6 | Solving dependencies when installing new packages is a process that in some cases can be computationally very intensive. SSDS is designed to overcome this issue. Client device gathers information about installed packages and enabled repos which are then sent to a server. The server then takes care of dependency solving and the result is sent back to client device as a list of packages that are needed to proceed with the install process and without dependency solving on client. 7 | 8 | Dependencies 9 | ============ 10 | Required packages needed for successfull compilation and build. 11 | 12 | - gcc 13 | - gcc-c++ 14 | - cmake 15 | - libsolv 16 | - librepo-devel 17 | - hawkey-devel 18 | - glib2-devel 19 | - json-glib 20 | - json-glib-devel 21 | - check-devel 22 | 23 | Installation 24 | ============ 25 | This section describes how to install and compile SSDS project 26 | 27 | There is new module in librepo, but it is not among updates yet so this is what needs to be done to be able to use it: 28 | -from http://koji.fedoraproject.org/koji/taskinfo?taskID=8948750 download these: 29 | librepo, python-librepo, librepo-devel - all in the right architecture 30 | these three should be ebough but just in case you can download also librepo-debuinfo and python3-librepo 31 | there is new version with some fixes - 1.7.13-4.fc21.x86_64 32 | -install these packages at the same time like this: 33 | $sudo dnf update ... - put them all into the same command 34 | 35 | Now everything should be in order to build rds: 36 | -enter build/ and type: 37 | 38 | $mkdir build 39 | 40 | $cd build/ 41 | 42 | $cmake .. 43 | 44 | $make 45 | 46 | -two files are created - rds-client and rds-server 47 | -to test type in build/ dir: 48 | 49 | $ctest 50 | 51 | -alternatively (if $ctest runs only one test) you can run test from build/tests/ dir: 52 | 53 | $./test_main 54 | 55 | Enjoy :) 56 | 57 | Valgrind 58 | ======== 59 | If you want to test the program with valgrind, there are lots of warnings and errors that are not caused by this program. Basically these errors are couased by various shared libraries and there is nothing we can do about them. To suppress all these warnings and errors the client program needs to be run with suppression file suppress-cl.supp. The server program has suppress-srv.supp. Both files are located in the build folder. Just run the program with valgrind like this: 60 | 61 | $valgrind --suppressions=suppress-cl.supp ./rds-client ... 62 | $valgrind --suppressions=suppress-srv.supp ./rds-server ... 63 | -------------------------------------------------------------------------------- /cmake/Config/version_conf.h.in: -------------------------------------------------------------------------------- 1 | #ifndef VERSION_CONF_H 2 | #define VERSION_CONF_H 3 | 4 | #define VERSION_HAWKEY @HKY_22@ 5 | 6 | #endif // VERSION_CONF_H 7 | -------------------------------------------------------------------------------- /cmake/Modules/FindCheck.cmake: -------------------------------------------------------------------------------- 1 | include(FindPkgConfig) 2 | 3 | #CHECK 4 | PKG_CHECK_MODULES(CHECK check REQUIRED) 5 | if(NOT CHECK_FOUND) 6 | message(FATAL_ERROR "Library check not found.") 7 | endif(NOT CHECK_FOUND) 8 | 9 | 10 | -------------------------------------------------------------------------------- /connection.cfg: -------------------------------------------------------------------------------- 1 | # CFG specifies address and port(s) for connecting to server 2 | 3 | # address of server running rds-server (default 127.0.0.1) 4 | address=127.0.0.1 5 | 6 | # port for connecting to server (default 2345) 7 | port=2345 8 | -------------------------------------------------------------------------------- /distro/rds.spec: -------------------------------------------------------------------------------- 1 | Summary: Remote dependency solving is a project which solves dependencies on server side/ 2 | Name: rds 3 | Version: 0.3.0 4 | Release: 1%{?rpmrelease}%{?dist} 5 | License: GPLv2 6 | Group: Applications/File 7 | URL: https://github.com/rh-lab-q/server-side-dependency-solving 8 | 9 | BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX) 10 | 11 | Source0: https://github.com/rh-lab-q/server-side-dependency-solving/archive/v{version}.tar.gz 12 | BuildRequires: cmake 13 | BuildRequires: gcc 14 | Requires: libsolv 15 | 16 | %description 17 | Solving dependencies when installing new packages is a process 18 | that in some cases can be computationally very intensive. 19 | SSDS is designed to overcome this issue. 20 | Client device gathers information about installed packages 21 | and enabled repos which are then sent to a server. 22 | The server then takes care of dependency solving 23 | and the result is sent back to client device 24 | as a list of packages that are needed to proceed 25 | with the install process and without dependency solving on client. 26 | 27 | %prep 28 | %setup -q 29 | 30 | %build 31 | %{cmake} 32 | make %{_smpflags} 33 | 34 | %install 35 | %{__rm} -rf %{buildroot} 36 | %{__make} install DESTDIR="%{buildroot}" 37 | 38 | %clean 39 | %{__rm} -rf %{buildroot} 40 | 41 | %files 42 | %defattr(-, root, root, 0755) 43 | %license LICENSE 44 | %doc AUTHORS COPYING README 45 | %doc %{_mandir}/man8/rear.8* 46 | 47 | %changelog 48 | * Mon 14 2015 Petr Hracek - 0.3.0-1 49 | - Initial release 50 | -------------------------------------------------------------------------------- /docs/RTFM.txt: -------------------------------------------------------------------------------- 1 | For using Hawkey library: 2 | Sack object is an abstraction of package collection: 3 | creating sack - HySack sack = hy_sack_create(NULL, NULL, NULL,HY_MAKE_CACHE_DIR); 4 | for loading all repos in system - sack = hy_sack_load_system_repo(sack, NULL, HY_BUILD_CACHE) 5 | count loaded packages - hy_sack_count(sack) 6 | 7 | Also we can load repos that are not default by providing a path to dir, provided we have somehow obtained the repo metadata: 8 | HySack sack_pokus = hy_sack_create(NULL, NULL, NULL,HY_MAKE_CACHE_DIR); 9 | HyRepo repo = hy_repo_create("pokus"); 10 | hy_repo_set_string(repo, HY_REPO_MD_FN, "/var/cache/dnf/x86_64/21/fedora/repodata/repomd.xml"); 11 | hy_repo_set_string(repo, HY_REPO_PRIMARY_FN, "/var/cache/dnf/x86_64/21/fedora/repodata/e2a28baab2ea4632fad93f9f28144cda3458190888fdf7f2acc9bc289f397e96-primary.xml.gz"); 12 | hy_repo_set_string(repo, HY_REPO_FILELISTS_FN, "/var/cache/dnf/x86_64/21/fedora/repodata/abb4ea5ccb9ad46253984126c6bdc86868442a4662dbcfa0e0f51b1bb209331e-filelists.xml.gz"); 13 | 14 | hy_sack_load_yum_repo(sack_pokus, repo, 0) 15 | 16 | -but this approach load all the packages from particular repo, not only those installed on our system 17 | -hawkey doesn't provide any means to obtain those metadata - this has to be achieved some other way probably by librepo 18 | 19 | Query object: 20 | -a query about particular package is executed on a sack of packages - HyQuery query = hy_query_create(sack); 21 | -name of package needs to be filtered from the query - hy_query_filter(query, HY_PKG_NAME, HY_SUBSTR, "pkg_name"); 22 | -we want the latest package available - hy_query_filter_latest_per_arch(query, 1); 23 | 24 | PackageList Object: 25 | -we need a list of packages to be able to extract packages from query - HyPackageList plist = hy_packagelist_create(); 26 | -run query - result goes to the list - plist = hy_query_run(query); 27 | 28 | Package Object: 29 | -one package - HyPackage pkg; 30 | -package on position 0 - pkg = hy_packagelist_get(plist, 0); 31 | 32 | Goal Object 33 | -goal serves for dependency solving - HyGoal goal = hy_goal_create(sack); 34 | -solve dependencies for installing the package pkg - hy_goal_install(goal, pkg); 35 | -if the return value is 0 - libsolv byl schopen nalezt reseni dependenci - if(hy_goal_run(goal)==0) 36 | 37 | For using librepo: 38 | There is new module in librepo, but it is not among updates yet so this is what needs to be done to be able to use it: 39 | -from http://koji.fedoraproject.org/koji/taskinfo?taskID=8948750 download these: 40 | librepo, python-librepo, librepo-devel - all in the right architecture 41 | these three should be ebough but just in case you can download also librepo-debuinfo and python3-librepo 42 | there is new version with some fixes - 1.7.13-4.fc21.x86_64 43 | -install these packages at the same time like this: 44 | #sudo dnf update ... - put them all into the same command 45 | 46 | Now I think you should have everything you need to run ssds :) enjoy 47 | -------------------------------------------------------------------------------- /docs/garbage_collector_usage_documentation.txt: -------------------------------------------------------------------------------- 1 | This is short documentation of the garbage collector(GC for short) used in Server Side Dependency Solving Project. 2 | 3 | USAGE: 4 | 5 | Before any using of this GC, you have to call ssds_gc_init() function. 6 | This initializes structures needed for running it. 7 | After that you can use other allocating functions of this GC. 8 | 9 | The main idea is that user of this GC calls functions with the same interface as 10 | standard allocation functions, but with the "ssds_" prefix. 11 | For instance ssds_malloc() has the same parameters, same return value, but inserts 12 | allocated memory into GC. 13 | 14 | LIST OF FUNCTIONS USED BY YOUR PROGRAM: 15 | 16 | ssds_gc_init() 17 | - initializes GC and needs to be called before any other functions. 18 | 19 | ssds_malloc(int size), 20 | ssds_calloc(int n_items, int size), 21 | ssds_realloc(void * old_ptr, int size) 22 | - return value of these functions is the same as standard allocating functions, 23 | but allocated memory is also inserted into GC for later cleanup. 24 | 25 | ssds_socket(int domain, int type, int protocol), 26 | ssds_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) 27 | - very similiar to allocating functions in this GC, return value is the same as 28 | standard functions for creating sockets, but sockets are also inserted into GC 29 | for later cleanup. 30 | 31 | ssds_free(void * ptr), 32 | ssds_close 33 | - these functions free/close allocated memory or socket and also removes it from 34 | GC because it does not need to be freed/closed twice. Use these functions if 35 | you want to manually free or close memory or socket. 36 | 37 | ssds_gc_cleanup() 38 | - cleans (frees all memory and closes all sockets) in the GC and ALSO DESTROYS it. 39 | This function should be called before the end of the program to prevent memory leaks. 40 | If you would want to continue using GC functions, you have to call another 41 | ssds_gc_init() after calling ssds_gc_cleanup(). 42 | 43 | Other functions are auxiliary for the GC and I dont recommend using them. 44 | Their interface is documented in src/common/mem_management.h . 45 | 46 | SAMPLE CODE: 47 | 48 | int main(int argc, char * argv[]) 49 | { 50 | ssds_gc_init(); 51 | void * alloc_memory = ssds_malloc(50); 52 | int socket = ssds_socket(AF_INET, SOCK_STREAM, 0); 53 | /* 54 | * USAGE OF MEMORY 55 | */ 56 | if(error) //an error occured. 57 | { 58 | ssds_gc_cleanup(); 59 | exit(EXIT_FAILIURE); 60 | } 61 | ssds_free(alloc_memory) //frees the allocated memory correctly 62 | /* 63 | * SOME OTHER CODE 64 | */ 65 | ssds_gc_cleanup() // 66 | return EXIT_SUCCESS; 67 | } -------------------------------------------------------------------------------- /docs/ssds.xmind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rh-lab-q/remote-dependency-solving/ccb09a2d3bd2e6738b992c2cc769a87c9550516c/docs/ssds.xmind -------------------------------------------------------------------------------- /etc/rds-client.conf: -------------------------------------------------------------------------------- 1 | [rds-client] 2 | server=127.0.0.1 3 | port=2345 4 | -------------------------------------------------------------------------------- /etc/rds-server.conf: -------------------------------------------------------------------------------- 1 | [rds-server] 2 | port=2345 3 | -------------------------------------------------------------------------------- /libhif-test/makefile: -------------------------------------------------------------------------------- 1 | all: main 2 | main: 3 | g++ -std=c++11 -Wall -Wextra -g -O2 -o test -lrepo -I/usr/include/librepo/ -I/usr/include/rpm/ -I/usr/include/glib-2.0/ -I/lib64/glib-2.0/include/ -lglib-2.0 test.cpp -lrpm -lrpmio 4 | 5 | -------------------------------------------------------------------------------- /libhif-test/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | static void log_handler_cb(const gchar *log_domain G_GNUC_UNUSED, GLogLevelFlags log_level G_GNUC_UNUSED, const gchar *message, gpointer user_data G_GNUC_UNUSED){ 11 | 12 | g_print("%s\n", message); 13 | } 14 | 15 | static int pc(G_GNUC_UNUSED void *data, double total, double now){ 16 | if(total > 0){ 17 | printf("\r%s\t%.0f%%",data, (now/total)*100); 18 | fflush(stdout); 19 | } 20 | return 0; 21 | } 22 | static int ec(G_GNUC_UNUSED void *data, LrTransferStatus s, const char *msg){ 23 | if(s == LR_TRANSFER_SUCCESSFUL){ 24 | printf("\r%s\t%s\n",data,"100% - Downloaded."); 25 | }else{ 26 | printf("\r%s\t%s\n",data,msg); 27 | } 28 | fflush(stdout); 29 | } 30 | int main(){ 31 | 32 | int rc = EXIT_SUCCESS; 33 | gboolean ret; 34 | LrHandle *h; 35 | GSList *packages = NULL; 36 | LrPackageTarget *target; 37 | GError *error = NULL; 38 | 39 | // setup logging (optional) 40 | 41 | // g_log_set_handler("librepo-test", G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG | G_LOG_LEVEL_WARNING, log_handler_cb, NULL); 42 | 43 | // prepare handle 44 | system("ls"); 45 | /* char *urls[] = {"http://why.lri.fr/", "https://mirrors.fedoraproject.org/metalink?repo=fedora-21&arch=x86_64","https://mirrors.fedoraproject.org/metalink?repo=updates-released-f21&arch=x86_64",NULL}; 46 | char *name = "w/why-xemacs-el-2.34-13.fc21.noarch.rpm"; 47 | h = lr_handle_init(); 48 | lr_handle_setopt(h, NULL, LRO_URLS, urls); 49 | lr_handle_setopt(h, NULL, LRO_REPOTYPE, LR_YUMREPO); 50 | lr_handle_setopt(h, NULL, LRO_PROGRESSCB, pc); 51 | // Prepare list of target 52 | 53 | target = lr_packagetarget_new_v2(h, name, "./rpm/", LR_CHECKSUM_UNKNOWN, NULL, 0, NULL, TRUE, pc, name, ec, NULL, &error); 54 | packages = g_slist_append(packages, target); 55 | target = lr_packagetarget_new(h, "l/libwmf-lite-0.2.8.4-43.fc21.x86_64.rpm", "./rpm/", LR_CHECKSUM_UNKNOWN, NULL, 0, NULL, TRUE, NULL, NULL, &error); 56 | packages = g_slist_append(packages, target); 57 | target = lr_packagetarget_new(h, "l/libwmf-0.2.8.4-43.fc21.x86_64.rpm", "./rpm/", LR_CHECKSUM_UNKNOWN, NULL, 0, NULL, TRUE, NULL, NULL, &error); 58 | packages = g_slist_append(packages, target); 59 | target = lr_packagetarget_new(h, "b/babl-0.1.12-2.fc21.x86_64.rpm", "./rpm/", LR_CHECKSUM_UNKNOWN, NULL, 0, NULL, TRUE, NULL, NULL, &error); 60 | packages = g_slist_append(packages, target); 61 | target = lr_packagetarget_new(h, "t/tbb-4.3-1.20141204.fc21.x86_64.rpm", "./rpm/", LR_CHECKSUM_UNKNOWN, NULL, 0, NULL, TRUE, NULL, NULL, &error); 62 | packages = g_slist_append(packages, target); 63 | target = lr_packagetarget_new(h, "a/atlas-3.10.1-18.fc21.x86_64.rpm", "./rpm/", LR_CHECKSUM_UNKNOWN, NULL, 0, NULL, TRUE, NULL, NULL, &error); 64 | packages = g_slist_append(packages, target); 65 | // Download all packages 66 | ret = lr_download_packages(packages, LR_PACKAGEDOWNLOAD_FAILFAST, &error); 67 | if(!ret){ 68 | fprintf(stderr, "Error: %d: %s\n", error->code, error->message); 69 | rc = EXIT_FAILURE; 70 | g_error_free(error); 71 | } 72 | */ 73 | // Check statuses 74 | 75 | // RPM init 76 | // TODO: need to init rpmdb connection 77 | Header hdr; 78 | char *namen = "/var/cache/ssds/packages/install/gimp-2.8.14-3.fc21.x86_64.rpm"; 79 | rpmReadConfigFiles(NULL,NULL); 80 | rpmts ts = rpmtsCreate(); 81 | rpmprobFilterFlags ignoreSet = 0; 82 | rpmtsSetRootDir(ts, NULL); 83 | // for(GSList *elem = packages; elem; elem = g_slist_next(elem)){ 84 | // LrPackageTarget *t = (LrPackageTarget *)elem->data; 85 | // printf("%s: %s\n", t->local_path, t->err ? t->err : "OK"); 86 | // installing package 87 | // if(!t->err){ 88 | FD_t fd = Fopen(namen,"r.ufdio"); 89 | printf("%d\n", fd); 90 | char *msg = NULL; 91 | int rr = rpmReadPackageFile(ts,fd,namen,&hdr); 92 | // int rr = rpmReadHeader(ts,fd,&hdr,&msg); 93 | switch (rr){ 94 | case RPMRC_OK: printf("OK\n"); 95 | break; 96 | case RPMRC_NOKEY: printf("NO KEY\n"); 97 | break; 98 | case RPMRC_NOTFOUND: printf("NOT FOUND\n"); 99 | break; 100 | case RPMRC_NOTTRUSTED: printf("NOT TRUSTED\n"); 101 | break; 102 | case RPMRC_FAIL: printf("FAIL\n"); 103 | break; 104 | default: printf("unknown error %d \n", rr); 105 | break; 106 | } 107 | 108 | int upgrade = 0; 109 | //rpmRelocation rel = NULL; 110 | int r = rpmtsAddInstallElement(ts, hdr, (fnpyKey) namen ,upgrade, NULL); 111 | printf("add install element \n"); 112 | switch (r){ 113 | case RPMRC_OK: printf("OK\n"); 114 | break; 115 | case RPMRC_NOKEY: printf("NO KEY\n"); 116 | break; 117 | case RPMRC_NOTFOUND: printf("NOT FOUND\n"); 118 | break; 119 | case RPMRC_NOTTRUSTED: printf("NOT TRUSTED\n"); 120 | break; 121 | case RPMRC_FAIL: printf("FAIL\n"); 122 | break; 123 | default: printf("unknown error %d \n", r); 124 | break; 125 | } 126 | 127 | //} 128 | //} 129 | //rpmtsi tsi = rpmtsiInit(ts); 130 | if(rpmtsOrder(ts)){ 131 | printf("ERROR: some packages cannot be ordered\n"); 132 | }else{ 133 | int tsFlags = 0, notifyFlags = 0; 134 | // notifyFlags |= INSTALL_LABEL | INSTALL_HASH; 135 | rpmtsSetNotifyCallback(ts, rpmShowProgress, (void *)notifyFlags); 136 | 137 | /* Set transaction flags and run the actual transaction */ 138 | rpmtsSetFlags(ts, (rpmtransFlags)(rpmtsFlags(ts) | tsFlags)); 139 | int result = rpmtsRun(ts, NULL, ignoreSet); 140 | printf("rpmts run %s.\n", result==RPMRC_OK?"ok":"error"); 141 | switch (result){ 142 | case RPMRC_OK: printf("OK\n"); 143 | break; 144 | case RPMRC_NOKEY: printf("NO KEY\n"); 145 | break; 146 | case RPMRC_NOTFOUND: printf("NOT FOUND\n"); 147 | break; 148 | case RPMRC_NOTTRUSTED: printf("NOT TRUSTED\n"); 149 | break; 150 | case RPMRC_FAIL: printf("FAIL\n"); 151 | break; 152 | default: printf("unknown error %d \n", result); 153 | break; 154 | } 155 | 156 | } 157 | // Clean up 158 | rpmtsClean(ts); 159 | rpmtsFree(ts); 160 | g_slist_free_full(packages, (GDestroyNotify) lr_packagetarget_free); 161 | lr_handle_free(h); 162 | 163 | return rc; 164 | } 165 | -------------------------------------------------------------------------------- /man/rds.1: -------------------------------------------------------------------------------- 1 | .TH SERVER SIDE DEPENDENCY SOLVING 1 2015-12-01 "" "Linux User's Manual" 2 | .SH NAME 3 | rds-client/server \- installs/update packages based on solving received from server 4 | 5 | .SH SYNOPSIS 6 | .B rds-client 7 | [\fIOPTION\fR]... \fIPACKAGE(S)\fR 8 | 9 | .SH DESCRIPTION 10 | \fBrds-client\fP is the tool which installs packages based of dependencies 11 | calculated by rds-server. 12 | 13 | Mandatory arguments to long options are mandatory for short options too. 14 | .TP 15 | \fB\-\-install\fR 16 | installs packages based on server dependencies 17 | 18 | .TP 19 | \fB\-\-update\fR 20 | update packages based on server dependencies 21 | 22 | .TP 23 | \fB\-\-erase\fR 24 | erase packages based on server dependencies 25 | 26 | .TP 27 | \fB\-\-chkdep\fR 28 | only show required packages - do not install them 29 | 30 | .TP 31 | \fB\-\-help\fR 32 | displays help 33 | 34 | .TP 35 | \fB\-v\fR 36 | verbose mode - turned off by default 37 | 38 | .TP 39 | \fB\-d\fR 40 | debug mode - turned off by default 41 | 42 | 43 | .SH AUTHOR 44 | Written by Petr Hracek, Simon Matej, Josef Ridky, Michal Ruprich (alphabetically) 45 | -------------------------------------------------------------------------------- /protocol.txt: -------------------------------------------------------------------------------- 1 | This file describes simple structure of network protocol used by SSDS. 2 | Right now there are only few tags but in time we will add more tags to support additional functionality. 3 | 4 | The protocol between client and server has following simple JSON structure: 5 | 6 | { 7 | "code" : Number, //Code of the message identifying type of message - codes are explained later 8 | "data" : {} //The tags that are present here depend on code above 9 | } 10 | 11 | 12 | ================================================================================================ 13 | 14 | "data" object desribed here: 15 | packages requested by client to be installed, upgraded etc.: 16 | "req_pkgs" : [ "package-1", "package-2", ... "package-n"], 17 | 18 | whether client wants to install, update, upgrade etc.: 19 | "req_operation" : ["command-1", "command-2", ... "command-n"], 20 | 21 | known repos on client side: 22 | "repolist" : 23 | [ 24 | { 25 | "name" : String, //name of the repo - maybe this is not important 26 | "repo_url" : [String, String ...], //there can be more than one url to try for a repo 27 | "type" : Number //1-baseurl, 2-mirrorlist, 3-metalink 28 | }, 29 | {}... 30 | ] 31 | 32 | values from dnf.conf from client to be considered on server side when dealing with dependencies 33 | "dnf_conf" : 34 | { 35 | option-name : String, 36 | ... 37 | option-name : String 38 | } 39 | 40 | installed packages on client side - two options here: 41 | -send @System.solv as a seperate file 42 | -send @System.solv inside json 43 | 44 | Example: 45 | { 46 | "code" : 1, 47 | "data" : 48 | { 49 | "req_pkgs" : ["abakus", "emacs"], 50 | "req_operation" : ["install"], 51 | "repolist" : 52 | [ 53 | { 54 | "repo_url" : ["https://mirrors.fedoraproject.org/metalink?repo=fedora-$releasever&arch=$basearch"], 55 | "name" : "Fedora", 56 | "type" : 3 57 | }, 58 | {} 59 | ], 60 | "dnf_conf" : 61 | {} 62 | } 63 | } 64 | 65 | ================================================================================================ 66 | 67 | possible child tags of "data" sent from server side: 68 | 69 | result of dependency solving - packages to install: 70 | "install" : [ 71 | { 72 | "pkg_name": String, 73 | "pkg_loc": pkg1, 74 | "base_url": String, (even NULL) 75 | //if download_address will be removed 76 | "metalink": String 77 | //if download_address will stay 78 | "metalink": Int 79 | }, 80 | {pkg2}, {pkg3} ... ] 81 | "erase" : [pkg1, pkg2, pkg3 ...] 82 | "update" : [pkg1, pkg2, pkg3 ...] // same as in install array 83 | }, 84 | {}... 85 | ], 86 | "download_address" : [addr1, addr2, addr3 ...] 87 | 88 | 89 | Example coresponding to client example above: 90 | { 91 | "code" : 1, 92 | "data" : 93 | { 94 | "install" : 95 | [ 96 | { 97 | "pkg_name":"why-xemacs-2.34-13.fc21-noarch", 98 | "pkg_loc": "Packages/w/why-xemacs-2.34-13.fc21-noarch.rpm", 99 | "base_url": NULL, 100 | //if download_address will be removed vvvv 101 | "metalink": "https://mirrors.fedoraproject.org/metalink?repo=updates-released-f21&arch=x86_64" 102 | //if download_address will stay 103 | "metalink": 0 104 | 105 | } // vvvv same as previous 106 | 107 | "why-2.34-13.fc21-x86_64", 108 | "xemacs-21.5.34-8.20140605hgacf1c26e3019.fc21-x86_64", 109 | "Canna-libs-3.7p3-44.fc21-x86_64", 110 | "compface-1.5.2-18.fc21-x86_64", 111 | "neXtaw-0.15.1-22.fc21-x86_64", 112 | "xemacs-common-21.5.34-8.20140605hgacf1c26e3019.fc21-x86_64", 113 | "xemacs-packages-base-20140715-1.fc21-noarch", 114 | "xorg-x11-fonts-ISO8859-1-100dpi-7.5-14.fc21-noarch", 115 | "xorg-x11-fonts-ISO8859-1-75dpi-7.5-14.fc21-noarch" 116 | ], 117 | "erase" : [], 118 | "upgrade" : [] 119 | "download_address": 120 | [ 121 | "https://mirrors.fedoraproject.org/metalink?repo=updates-released-f21&arch=x86_64", 122 | "https://mirrors.fedoraproject.org/metalink?repo=fedora-21&arch=x86_64" 123 | ] 124 | }, 125 | { 126 | "name" : "abakus", 127 | "install" : ["abakus-0.92-4.fc21-x86_64"], 128 | "erase" : [], 129 | "upgrade" : [] 130 | } 131 | ], 132 | } 133 | } 134 | ================================================================================================ 135 | 136 | possible error messages from client side: 137 | 138 | 139 | 140 | ================================================================================================ 141 | 142 | possible error messages from server side: 143 | 144 | ================================================================================================ 145 | 146 | 147 | 148 | 000-099 are regular commands or info 149 | 100-199 are ssds error messages (mostly about dependency solving errors etc.) 150 | 200-299 are internal server errors 151 | -------------------------------------------------------------------------------- /required_repos_list.txt: -------------------------------------------------------------------------------- 1 | fedora.repo 2 | fedora-updates.repo 3 | fedora-updates-testing.repo 4 | google-chrome.repo 5 | ozonos.repo 6 | rpmfusion-free-rawhide.repo 7 | rpmfusion-free.repo 8 | rpmfusion-free-updates.repo 9 | rpmfusion-free-updates-testing.repo 10 | rpmfusion-nonfree-rawhide.repo 11 | rpmfusion-nonfree.repo 12 | rpmfusion-nonfree-updates.repo 13 | rpmfusion-nonfree-updates-testing.repo -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | ## required libraries and packages: 2 | 3 | boost 4 | libsolv 5 | librepo 6 | hawkey 7 | libxml2-devel 8 | xml2 9 | ## maybe even - libxml - will be requred 10 | 11 | ## librepo package 12 | librepo-devel.(version) e.g.: librepo-devel.x86_64, librepo-devel.i686 13 | glib2.0-devel 14 | 15 | ## packages for setting up development enviroment 16 | 17 | git 18 | gcc-c++ 19 | cmake 20 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(client) 2 | -------------------------------------------------------------------------------- /src/bugzilla/Makefile: -------------------------------------------------------------------------------- 1 | GCC=gcc 2 | CFLAGS=-std=c11 3 | 4 | all: lr_bug 5 | 6 | lr_bug: 7 | $(GCC) $(CFLAGS) lr_handle_free_issue.c -o lr_bug -I/usr/include/glib-2.0 -I/usr/lib64/glib-2.0/include -L/usr/include/librepo/ -lrepo -lgobject-2.0 -lglib-2.0 8 | 9 | clean: 10 | rm lr_bug -------------------------------------------------------------------------------- /src/bugzilla/Makefile_hawkey: -------------------------------------------------------------------------------- 1 | #soubor: Makefile 2 | # Michal Ruprich, xrupri00, RedHat, SSDS - hawkey example 3 | 4 | PP=g++ 5 | CPPFLAGS= -std=c++11 6 | INCLUDE=-I/usr/include/hawkey 7 | all: hawkey_bug 8 | 9 | hawkey_bug: 10 | $(PP) $(CPPFLAGS) $(INCLUDE) -l hawkey hawkey_bug.cpp -o hawkey_bug 11 | clean: 12 | rm -rf *o hawkey_bug 13 | -------------------------------------------------------------------------------- /src/bugzilla/bug.patch: -------------------------------------------------------------------------------- 1 | diff -rupN hawkey_old/subject.h hawkey/subject.h 2 | --- hawkey_old/subject.h 2015-01-28 12:43:32.039078599 +0100 3 | +++ hawkey/subject.h 2015-01-28 12:50:57.367066601 +0100 4 | @@ -32,7 +32,11 @@ 5 | extern "C" { 6 | #endif 7 | 8 | +#ifdef __cplusplus 9 | +enum _HyForm :short { 10 | +#else 11 | enum _HyForm { 12 | +#endif 13 | HY_FORM_NEVRA = 1, 14 | HY_FORM_NEVR, 15 | HY_FORM_NEV, 16 | diff -rupN hawkey_old/types.h hawkey/types.h 17 | --- hawkey_old/types.h 2015-01-28 12:43:32.038078594 +0100 18 | +++ hawkey/types.h 2015-01-28 12:55:35.517217260 +0100 19 | @@ -25,7 +25,12 @@ 20 | extern "C" { 21 | #endif 22 | 23 | +#ifdef __cplusplus 24 | +enum _HyForm :short ; 25 | +#else 26 | typedef enum _HyForm HyForm; 27 | +#endif 28 | + 29 | typedef struct _HyAdvisory * HyAdvisory; 30 | typedef struct _HyAdvisoryList * HyAdvisoryList; 31 | typedef struct _HyAdvisoryPkg * HyAdvisoryPkg; 32 | -------------------------------------------------------------------------------- /src/bugzilla/lr_handle_free_issue.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | //LIBREPO 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | LrHandleOption type; 10 | GError *tmp_err = NULL; 11 | 12 | // Download only this metadata 13 | //char *download_list[] = { "primary", "filelists", NULL}; 14 | LrHandle *h = lr_handle_init(); 15 | LrResult *r = lr_result_init(); 16 | //repo->urls[repo->count] = NULL; 17 | 18 | //find type of url in vector 19 | // switch(repo->type) 20 | // { 21 | // case 1: 22 | // type = LRO_URLS; 23 | // lr_handle_setopt(h, NULL, type, repo->urls); 24 | // break; 25 | // case 2: 26 | // type = LRO_MIRRORLISTURL; 27 | // lr_handle_setopt(h, NULL, type, repo->urls[0]); 28 | // break; 29 | // case 3: 30 | // type = LRO_METALINKURL; 31 | // lr_handle_setopt(h, NULL, type, repo->urls[0]); 32 | // break; 33 | // } 34 | char* full_path = "/tmp/ssds/pokus"; 35 | char* urls[2] = {"http://copr-be.cloud.fedoraproject.org/results/dvratil/plasma-5/fedora-21-x86_64/", NULL}; 36 | lr_handle_setopt(h, NULL, LRO_URLS, urls); 37 | lr_handle_setopt(h, NULL, LRO_REPOTYPE, LR_YUMREPO); 38 | lr_handle_setopt(h, NULL, LRO_CONNECTTIMEOUT, (long)10); 39 | lr_handle_setopt(h, NULL, LRO_DESTDIR, full_path); 40 | // lr_handle_setopt(h, NULL, LRO_PROGRESSCB, metadata_progress); 41 | // lr_handle_setopt(h, NULL, LRO_PROGRESSDATA, repo->name); 42 | 43 | gboolean ret = lr_handle_perform(h, r, &tmp_err); 44 | char *destdir; 45 | lr_handle_getinfo(h, NULL, LRI_DESTDIR, &destdir); 46 | 47 | 48 | if (ret) { 49 | printf("Metadata download successfull (Destination dir: %s).\n", destdir); 50 | 51 | LrYumRepo* lrRepo = lr_yum_repo_init(); 52 | lr_result_getinfo(r, &tmp_err, LRR_YUM_REPO, &lrRepo); 53 | 54 | // SsdsMetadataFilesLoc* loc = (SsdsMetadataFilesLoc*)ssds_malloc(sizeof(SsdsMetadataFilesLoc)); 55 | 56 | // loc->repomd = destdir; 57 | printf("Repomd is in %s/repomd.xml.\n", destdir); 58 | // loc->filelists = strdup(lr_yum_repo_path(lrRepo,"filelists")); 59 | printf("Filelists are in %s.\n", lr_yum_repo_path(lrRepo,"filelists")); 60 | // loc->primary = strdup(lr_yum_repo_path(lrRepo,"primary")); 61 | printf("Primary is in %s.\n", lr_yum_repo_path(lrRepo,"primary")); 62 | // loc->repo_name = strdup(repo->urls[0]); 63 | 64 | // list->files_locations = g_slist_append(list->files_locations, loc); 65 | lr_yum_repo_free(lrRepo); 66 | printf("lr_yum_repo_free went OK\n"); 67 | } else { 68 | fprintf(stderr, "Error encountered: %s.\n", tmp_err->message); 69 | g_error_free(tmp_err); 70 | } 71 | 72 | lr_result_free(r); 73 | printf("lr_result_free went OK\n"); 74 | lr_handle_free(h); 75 | printf("lr_handle_free went OK\n"); 76 | 77 | 78 | 79 | 80 | } -------------------------------------------------------------------------------- /src/client/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | FIND_PACKAGE(Boost COMPONENTS filesystem system REQUIRED) 2 | 3 | include_directories(${Boost_INCLUDE_DIR}) 4 | add_executable(rds-client client.c) 5 | target_link_libraries( 6 | rds-client 7 | ${Boost_SYSTEM_LIBRARY} 8 | ${Boost_FILESYSTEM_LIBRARY} 9 | ) 10 | -------------------------------------------------------------------------------- /src/client/README: -------------------------------------------------------------------------------- 1 | This part of code is used for client side 2 | -------------------------------------------------------------------------------- /src/client/client.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Server side dependency solving 3 | * transfer of dependency solving from local machine to server when installing new packages 4 | * 5 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel, Šimon Matěj 6 | * 7 | * Licensed under the GNU Lesser General Public License Version 2.1 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef _CLIENT_H 25 | #define _CLIENT_H 26 | 27 | #ifdef __cplusplus 28 | extern "C"{ 29 | #endif 30 | 31 | #include "../common/includes.h" 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | 38 | //SSDS 39 | #include "../common/log_handler.h" 40 | #include "../common/network_util.h" 41 | #include "../common/params.h" 42 | #include "../common/json_handler.h" 43 | #include "../common/repo_handler.h" 44 | #include "../common/util.h" 45 | #include "../common/mem_management.h" 46 | #include "../../cmake/Config/version_conf.h" 47 | #include "../common/errors.h" 48 | #include "../common/detect_missing_repos.h" 49 | #include "../common/packages.h" 50 | 51 | enum{ 52 | YES, 53 | NO, 54 | DOWNLOAD, 55 | YES_NO, 56 | YES_NO_DOWNLOAD, 57 | }; 58 | 59 | /** 60 | * Asking for new client ID from server. 61 | * @param socket int socket handler 62 | * @param id char** pointer to ID string 63 | * @param arch char* type of computer architecture 64 | * @param release char* version of installed system 65 | * @return Returns OK if the recieved json is valid, otherwise error code. 66 | */ 67 | int ssds_get_new_id(int socket, char **id, char *arch, char *release); 68 | 69 | /** 70 | * Send file to server. 71 | * @param socket int communication socket handler 72 | * @param type int type of file 73 | * @param path char* path to file 74 | * @return Returns OK if the recieved json is valid, otherwise error code. 75 | */ 76 | int ssds_send_file(int socket, int type, char *path); 77 | 78 | /** 79 | * Compare two files 80 | * @param fileOne char* path to first file 81 | * @param fileTwo char* path to second file 82 | * @return Returns OK if files are identical, else error code. 83 | */ 84 | int compare_files(char *fileOne, char *fileTwo); 85 | 86 | /** 87 | * Compare two files 88 | * @param source char* path to source file 89 | * @param destination char* path to destination file 90 | * @return Returns OK, else error code. 91 | */ 92 | int copy_file(char *source, char *destination); 93 | 94 | /** 95 | * Send type of operation, names of packages and addresses of repos to server. 96 | * @param params ParamOptsCl* structure of command line parsed parameters 97 | * @param arch char* type of computer architecture 98 | * @param release char* version of installed system 99 | * @param socket int socket handler 100 | * @param action int type of requested operation 101 | * @return Returns OK if the recieved json is valid, otherwise error code. 102 | */ 103 | int ssds_send_repo(ParamOptsCl* params, char *arch, char *release, int socket, int action); 104 | 105 | /** 106 | * Parse answer from server of ssds_send_repo request. 107 | * @param socket int socket handler 108 | * @param message char** message fom delivered answer. 109 | * @return Returns ANSWER_OK if and NULL in message, otherwise error code with message. 110 | */ 111 | int ssds_check_repo(int socket, char **message); 112 | 113 | /** 114 | * Parses dependency solv answer and download and install/update/erase requested packages. 115 | * @param socket int socket handler 116 | * @param action int type of requested action 117 | * @return Returns OK if the recieved json is valid, otherwise error code. 118 | */ 119 | int ssds_answer_process(int socket, int action); 120 | 121 | /** 122 | * Download requested packages. 123 | * @param answer user's answer 124 | * @param install list of packages to install 125 | * @param update list of packages to update 126 | * @param erase list of packages to erase 127 | * @return Returns OK, otherwise error code. 128 | */ 129 | int ssds_download(int answer, GSList *install, GSList *update, GSList *erase); 130 | 131 | /** 132 | * Install/update/erase requested packages. 133 | * @param install list of packages to install 134 | * @param update list of packages to update 135 | * @param erase list of packages to erase 136 | * @return Returns OK, otherwise error code. 137 | */ 138 | int ssds_rpm_process(GSList *install, GSList *update, GSList *erase); 139 | 140 | /** 141 | * Asking user for his wish. 142 | * @param question char* string for print 143 | * @param possibilities int type (number) of offered possibilities 144 | * @return Returns chosen possibility. 145 | */ 146 | int ssds_question(char* question, int possibilities); 147 | 148 | #ifdef __cplusplus 149 | } 150 | #endif 151 | 152 | #endif 153 | -------------------------------------------------------------------------------- /src/client/client_main.c: -------------------------------------------------------------------------------- 1 | #include "client.h" 2 | 3 | // #define VERSION_HAWKEY @HKY_22@ 4 | //for debugging 5 | //#define DEBUG 6 | 7 | /* Client plan: 8 | * check id (if NULL - ask for it from server by message) TODO: gen. ID on server and store it into cfg gile 9 | * connect to server - done 10 | * if new id - send @System.solv - done 11 | * parse repo - done 12 | * send repo info to server - done 13 | * if some repo on client side missing - read warning from server TODO: checking repo missing on server side 14 | * send message with requested operation and package names to server TODO: add update and erase option in json 15 | * read dep result - done 16 | * print dep result to user TODO: print that 17 | * 18 | * ----- only in update and install ----- 19 | * ask if (update/install)/download/cancel 20 | * download packages - done 21 | * install/update/erase them - done 22 | */ 23 | 24 | int main(int argc, char* argv[]){ 25 | 26 | /*******************************************************************/ 27 | /* Check root rights */ 28 | /*******************************************************************/ 29 | uid_t uid = geteuid(); 30 | if(uid != 0) 31 | { 32 | ssds_log(logERROR, "This program has to be run under the root user otherwise no packages can be installed, erased or updated.\n"); 33 | return ROOT_ERROR; 34 | } 35 | 36 | /*******************************************************************/ 37 | /* Client return code variable */ 38 | /*******************************************************************/ 39 | int status = OK; 40 | 41 | /*******************************************************************/ 42 | /* Setting up garbage collector and setting callback functions */ 43 | /*******************************************************************/ 44 | ssds_gc_init(); 45 | signal(SIGINT, ssds_signal_handler); 46 | signal(SIGBUS, ssds_signal_handler); 47 | signal(SIGSEGV, ssds_signal_handler); 48 | signal(SIGTERM, ssds_signal_handler); 49 | 50 | /*******************************************************************/ 51 | /* Parsing parameters */ 52 | /*******************************************************************/ 53 | 54 | ssds_log(logSSDS, "Client startup.\n"); 55 | 56 | ParamOptsCl* params = init_params_cl(); 57 | 58 | if(parse_params_cl(argc, argv, params) != 0) 59 | { 60 | status = PARAMS_ERROR; 61 | goto end; 62 | } 63 | 64 | ssds_log(logDEBUG, "Client params initialized.\n"); 65 | ssds_log(logDEBUG, "Client params parsed. Package count %d.\n", params->pkg_count); 66 | ssds_log(logMESSAGE, "Client startup. Required package count %d.\n", params->pkg_count); 67 | 68 | if((params->pkg_count == 0) && (params->command == PAR_UPDATE)) 69 | params->command = PAR_UPDATE_ALL; 70 | /********************************************************************/ 71 | /* Load configuration */ 72 | /********************************************************************/ 73 | 74 | char *server_address, *id; 75 | long int port; 76 | read_cfg(&id, &server_address, &port); 77 | 78 | /********************************************************************/ 79 | /* Getting architecture, release and path to @System.solv */ 80 | /********************************************************************/ 81 | char pathToOriginalSolv[100], 82 | *pathToOriginalYum = "/etc/yum.conf", 83 | *pathToBackupSolv = "/var/cache/ssds/@System.solv", 84 | *pathToBackupYum = "/var/cache/ssds/yum.conf"; 85 | 86 | char *arch = NULL, *release = NULL, *message = NULL; 87 | ssds_resolve_dependency_file_path(pathToOriginalSolv, &arch, &release); 88 | 89 | /********************************************************************/ 90 | /* Networking part - connecting to server */ 91 | /********************************************************************/ 92 | ssds_log(logDEBUG, "Network part.\n"); 93 | 94 | int socket; 95 | 96 | status = client_connect(&socket, server_address, port); 97 | 98 | if(status != OK) goto end; 99 | 100 | ssds_log(logDEBUG, "Communication socket: %d.\n", socket); 101 | 102 | /********************************************************************/ 103 | /* Checking client ID */ 104 | /********************************************************************/ 105 | 106 | if(id == NULL) 107 | { 108 | //status = ssds_get_new_id(socket, &id, arch, release); 109 | //if(status != OK) goto end; 110 | 111 | status = ssds_send_file(socket, SEND_SOLV, pathToOriginalSolv); 112 | if(status != OK) goto end; 113 | if(copy_file(pathToOriginalSolv, pathToBackupSolv) != OK) 114 | { 115 | ssds_log(logWARNING, "Unable to make @System.solv backup.\n"); 116 | } 117 | 118 | status = ssds_send_file(socket, SEND_YUM_CONF, pathToOriginalYum); 119 | if(status != OK) goto end; 120 | if(copy_file(pathToOriginalYum, pathToBackupYum) != OK) 121 | { 122 | ssds_log(logWARNING, "Unable to make yum.conf backup.\n"); 123 | } 124 | 125 | }else{ 126 | if( compare_files(pathToOriginalSolv, pathToBackupSolv) != OK ){ 127 | int ans = ssds_question("DNF install packages by themself. We need to make initial steps again. If you don't want to use RDS call rds-client --disconnect. Do you agree to make initial steps again?", YES_NO); 128 | 129 | if(ans == NO) 130 | { 131 | ssds_log(logMESSAGE,"Action interupted by user.\n"); 132 | goto end; 133 | } 134 | 135 | status = ssds_send_file(socket, SEND_SOLV, pathToOriginalSolv); 136 | if(status != OK) goto end; 137 | if(copy_file(pathToOriginalSolv, pathToBackupSolv) != OK) 138 | { 139 | ssds_log(logWARNING, "Unable to make @System.solv backup.\n"); 140 | } 141 | } 142 | 143 | if( compare_files(pathToOriginalYum, pathToBackupYum) != OK ){ 144 | int ans = ssds_question("New yum configuration will be sent to server. Do yout agree?", YES_NO); 145 | if(ans == NO){ 146 | ssds_log(logMESSAGE,"Action interupted by user.\n"); 147 | goto end; 148 | } 149 | 150 | status = ssds_send_file(socket, SEND_YUM_CONF, pathToOriginalYum); 151 | if(status != OK) goto end; 152 | if(copy_file(pathToOriginalYum, pathToBackupYum) != OK) 153 | { 154 | ssds_log(logWARNING, "Unable to make yum.conf backup.\n"); 155 | } 156 | } 157 | } 158 | 159 | 160 | // this switch is now just for info about selected command 161 | switch(params->command) 162 | { 163 | 164 | case PAR_INSTALL: 165 | ssds_log(logMESSAGE, "Installation of packages was selected.\n"); 166 | 167 | status = ssds_send_repo(params, arch, release, socket, GET_INSTALL); 168 | if(status != OK) break; 169 | 170 | if(ssds_check_repo(socket, &message) != ANSWER_OK) 171 | { 172 | ssds_log(logWARNING,"%s\n", message); 173 | } 174 | 175 | 176 | status = ssds_answer_process(socket, GET_INSTALL); 177 | break; 178 | 179 | case PAR_UPDATE: 180 | ssds_log(logMESSAGE, "Update of packages was selected.\n"); 181 | ssds_log(logERROR, "Update option has not been implemented yet.\n"); 182 | 183 | status = ssds_send_repo(params, arch, release, socket, GET_UPDATE); 184 | if(status != OK) break; 185 | 186 | if(ssds_check_repo(socket, &message) != ANSWER_OK) 187 | { 188 | ssds_log(logWARNING,"%s\n", message); 189 | } 190 | 191 | status = ssds_answer_process(socket, GET_UPDATE); 192 | 193 | break; 194 | 195 | case PAR_ERASE: 196 | ssds_log(logMESSAGE, "Erase of packages was selected.\n"); 197 | 198 | status = ssds_send_repo(params, arch, release, socket, GET_ERASE); 199 | if(status != OK) break; 200 | 201 | if(ssds_check_repo(socket, &message) != ANSWER_OK) 202 | { 203 | ssds_log(logWARNING,"%s\n", message); 204 | } 205 | 206 | status = ssds_answer_process(socket, GET_ERASE); 207 | 208 | break; 209 | 210 | case PAR_CHK_DEP: 211 | ssds_log(logMESSAGE, "Dependency check of packages was selected.\n"); 212 | ssds_log(logERROR, "Dependency check option has not been implemented yet.\n"); 213 | break; 214 | 215 | case PAR_UPDATE_ALL: 216 | ssds_log(logMESSAGE, "Update all packages was initiated.\n"); 217 | status = ssds_send_repo(params, arch, release, socket, GET_UPDATE_ALL); 218 | if(status != OK) break; 219 | 220 | if(ssds_check_repo(socket, &message) != ANSWER_OK) 221 | { 222 | ssds_log(logWARNING,"%s\n", message); 223 | } 224 | 225 | status = ssds_answer_process(socket, GET_UPDATE); 226 | break; 227 | } 228 | 229 | end: 230 | ssds_log(logSSDS, "End of client.\n\n"); 231 | 232 | ssds_gc_cleanup(); 233 | 234 | return status; 235 | } 236 | -------------------------------------------------------------------------------- /src/common/Makefile: -------------------------------------------------------------------------------- 1 | # all source file should be in one foldder for your own testing with this temporary Makefile 2 | # make server, make client, make clean ("make" ONLY builds server) 3 | 4 | TARGETS = server #name of the program && target file 5 | OBJS = Server.o 6 | CC = g++ 7 | CXXFLAGS = -O2 -g -Wall -Wextra -pedantic -std=c++11 -I/usr/local/include -L/usr/local/lib -lboost_thread -lboost_system -fmessage-length=0 8 | 9 | #basic build function with dependency OBJ 10 | server: $(OBJS) 11 | $(CC) $(CXXFLAGS) $(OBJS) -o $(TARGETS) 12 | 13 | Server.o: Server.cpp 14 | $(CC) $(CXXFLAGS) -c Server.cpp 15 | 16 | TAREGETC = client 17 | OBJC = client.o 18 | 19 | client: $(OBJC) 20 | $(CC) $(CXXFLAGS) $(OBJC) -o client 21 | 22 | client.o: client.cpp 23 | $(CC) $(CXXFLAGS) -c client.cpp 24 | 25 | clean: 26 | rm -f $(OBJS) $(TARGETS) $(OBJC) $(TARGETC) 27 | -------------------------------------------------------------------------------- /src/common/README: -------------------------------------------------------------------------------- 1 | Classes for client and server are stored in common directory 2 | Like XML class and Logging class 3 | -------------------------------------------------------------------------------- /src/common/cfg_parsing.c: -------------------------------------------------------------------------------- 1 | 2 | #include "cfg_parsing.h" 3 | 4 | 5 | int read_cfg(char **ret_client_id, char** ret_address, long int* ret_comm_port) 6 | { 7 | /* 8 | ** reads connection configuration from CFG file 9 | */ 10 | 11 | 12 | char *address, *comm_port, *client_id; 13 | FILE* cfg_file; 14 | cfg_file = fopen(CFG_FILE, "r"); 15 | if (cfg_file == NULL) 16 | { 17 | ssds_log(logDEBUG, "Could not open cfg file, using defaults.\n"); 18 | 19 | *ret_address = (char*)ssds_malloc(10*sizeof(char)); 20 | strncpy(*ret_address, "127.0.0.1\0", 10); 21 | 22 | *ret_comm_port = 2345; 23 | return 1; 24 | } 25 | 26 | ssds_log(logDEBUG, "CFG file opened.\n"); 27 | 28 | char fmstate = 'e'; 29 | char act_c; 30 | 31 | int address_parsed = 0; 32 | int client_id_parsed = 0; 33 | int comm_port_parsed = 0; 34 | 35 | do 36 | { 37 | act_c = fgetc(cfg_file); 38 | switch (fmstate) 39 | { 40 | case 'e': 41 | if ((act_c == '#') || (act_c == '[')) //comment 42 | fmstate = 'c'; 43 | else if (act_c == 'a') //address 44 | fmstate = 'a'; 45 | else if (act_c == 's') //address (alternative) 46 | fmstate = 's'; 47 | else if (act_c == 'p') //port 48 | fmstate = 'p'; 49 | else if (act_c == 'i') //id 50 | fmstate = 'i'; 51 | else fmstate = 'c'; //ignore invalid lines 52 | break; 53 | 54 | case 'c': 55 | if (act_c == '\n') 56 | fmstate = 'e'; 57 | break; 58 | 59 | case 'a': 60 | compare(cfg_file, "address=", 7, &fmstate, &act_c); 61 | if (fmstate == 'a') 62 | { 63 | address = file_read_value(cfg_file, 0); 64 | *ret_address = address; 65 | address_parsed = 1; 66 | fmstate = 'e'; 67 | } 68 | break; 69 | 70 | case 's': 71 | compare(cfg_file, "server=", 6, &fmstate, &act_c); 72 | if (fmstate == 's') 73 | { 74 | address = file_read_value(cfg_file, 0); 75 | *ret_address = address; 76 | address_parsed = 1; 77 | fmstate = 'e'; 78 | } 79 | break; 80 | 81 | case 'p': 82 | compare(cfg_file, "port=", 4, &fmstate, &act_c); 83 | if (fmstate == 'p') 84 | { 85 | comm_port = file_read_value(cfg_file, 5); 86 | *ret_comm_port = strtol(comm_port, NULL, 10); 87 | ssds_free(comm_port); 88 | comm_port_parsed = 1; 89 | fmstate = 'e'; 90 | } 91 | break; 92 | 93 | case 'i': 94 | compare(cfg_file, "id=", 2, &fmstate, &act_c); 95 | if (fmstate == 'i') 96 | { 97 | client_id = file_read_value(cfg_file, 0); 98 | *ret_client_id = client_id; 99 | client_id_parsed = 1; 100 | fmstate = 'e'; 101 | } 102 | break; 103 | 104 | default: 105 | break; 106 | } 107 | } 108 | while (act_c != EOF); 109 | 110 | fclose(cfg_file); 111 | 112 | if (address_parsed == 0) 113 | { 114 | *ret_address = (char*)ssds_malloc(10*sizeof(char)); 115 | strncpy(*ret_address, "127.0.0.1\0", 10); 116 | } 117 | if (client_id_parsed == 0) 118 | { 119 | *ret_client_id = NULL; // client do not have an Id yet 120 | } 121 | if (!comm_port_parsed) 122 | { 123 | *ret_comm_port = 2345; 124 | } 125 | 126 | ssds_log(logDEBUG, "server: %s, comm port: %ld\n", *ret_address, *ret_comm_port); 127 | 128 | return 0; 129 | } 130 | 131 | int read_srv_cfg(long int* ret_comm_port) 132 | { 133 | /* 134 | * reads connection configuration from CFG file 135 | */ 136 | 137 | char *comm_port; 138 | FILE* cfg_file; 139 | cfg_file = fopen(CFG_FILE, "r"); 140 | if (cfg_file == NULL) 141 | { 142 | ssds_log(logDEBUG, "Could not open cfg file, using defaults.\n"); 143 | 144 | *ret_comm_port = 2345; 145 | return 1; 146 | } 147 | 148 | ssds_log(logDEBUG, "CFG file opened.\n"); 149 | 150 | char fmstate = 'e'; 151 | char act_c; 152 | 153 | int comm_port_parsed = 0; 154 | 155 | do 156 | { 157 | act_c = fgetc(cfg_file); 158 | switch (fmstate) 159 | { 160 | case 'e': 161 | if (act_c == '#') //comment 162 | fmstate = 'c'; 163 | else if (act_c == 'p') //port 164 | fmstate = 'p'; 165 | else fmstate = 'c'; //ignore invalid lines 166 | break; 167 | 168 | case 'c': 169 | if (act_c == '\n') 170 | fmstate = 'e'; 171 | break; 172 | 173 | case 'p': 174 | compare(cfg_file, "port=", 4, &fmstate, &act_c); 175 | if (fmstate == 'p') 176 | { 177 | comm_port = file_read_value(cfg_file, 5); 178 | *ret_comm_port = strtol(comm_port, NULL, 10); 179 | ssds_free(comm_port); 180 | comm_port_parsed = 1; 181 | fmstate = 'e'; 182 | } 183 | break; 184 | 185 | default: 186 | break; 187 | } 188 | } 189 | while (act_c != EOF); 190 | 191 | fclose(cfg_file); 192 | 193 | if (!comm_port_parsed) 194 | { 195 | *ret_comm_port = 2345; 196 | } 197 | 198 | ssds_log(logDEBUG, "comm port: %ld\n", *ret_comm_port); 199 | 200 | return 0; 201 | } 202 | 203 | int write_to_cfg(char *name, char *value) 204 | { 205 | FILE* cfg_file; 206 | cfg_file = fopen(CFG_FILE, "r+"); 207 | if (cfg_file == NULL) 208 | { 209 | ssds_log(logDEBUG, "Conf file not found.\n"); 210 | return 1; 211 | } 212 | 213 | ssds_log(logDEBUG, "CFG file opened for write.\n"); 214 | 215 | char fmstate = 'e'; 216 | char *act_val; 217 | int already_exists = 0; 218 | 219 | int len = 0; 220 | while (name[len] != '\0') 221 | { 222 | len++; 223 | } 224 | int val_len = 0; 225 | while (value[val_len] != '\0') 226 | { 227 | val_len++; 228 | } 229 | 230 | char act_c; 231 | int position; 232 | 233 | do 234 | { 235 | act_c = fgetc(cfg_file); 236 | switch (fmstate) 237 | { 238 | case 'e': 239 | if (act_c == name[0]) //desired value 240 | fmstate = 'v'; 241 | else fmstate = 'c'; //ignore invalid lines 242 | break; 243 | 244 | case 'c': 245 | if (act_c == '\n') 246 | fmstate = 'e'; 247 | break; 248 | 249 | 250 | case 'v': 251 | compare(cfg_file, name, len - 1, &fmstate, &act_c); 252 | act_c = fgetc(cfg_file); 253 | if (act_c != '=') 254 | { 255 | fmstate = 'c'; 256 | } 257 | if (fmstate == 'v') 258 | { 259 | already_exists = 1; 260 | fmstate = 'e'; 261 | position = ftell(cfg_file); 262 | } 263 | break; 264 | 265 | 266 | default: 267 | break; 268 | } 269 | } 270 | while (act_c != EOF); 271 | 272 | if (already_exists == 1) 273 | { 274 | //clone file with changed value 275 | fseek(cfg_file, 0, SEEK_SET); 276 | char *tempcfg = (void*)ssds_malloc((position + 1) * sizeof(char)); 277 | fread(tempcfg, sizeof(char), position, cfg_file); 278 | tempcfg[position] = '\0'; 279 | FILE *new_file = fopen("../etc/rds-client.conf.tmp", "w"); 280 | fwrite(tempcfg, sizeof(char), position, new_file); 281 | fwrite(value, sizeof(char), val_len, new_file); 282 | 283 | 284 | do 285 | { 286 | act_c = fgetc(cfg_file); 287 | } 288 | while ((act_c != '\n') && (act_c != EOF)); 289 | while (act_c != EOF) 290 | { 291 | fputc(act_c, new_file); 292 | act_c = fgetc(cfg_file); 293 | } 294 | 295 | fclose(cfg_file); 296 | fclose(new_file); 297 | 298 | if (remove(CFG_FILE) != 0) 299 | { 300 | ssds_log(logERROR, "cannot delete old conf. file\n"); 301 | return 1; 302 | } 303 | 304 | if (rename("../etc/ssds-client.conf.tmp", CFG_FILE) != 0) 305 | { 306 | ssds_log(logERROR, "cannot rename new conf. file\n"); 307 | return 1; 308 | } 309 | 310 | ssds_log(logDEBUG, "there is already [%s] in config file, updating its value\n", name); 311 | return 0; 312 | } 313 | else 314 | { 315 | fseek(cfg_file, 0, SEEK_END); 316 | fwrite(name, sizeof(char), len, cfg_file); 317 | fwrite("=", sizeof(char), 1, cfg_file); 318 | fwrite(value, sizeof(char), val_len, cfg_file); 319 | fwrite("\n", sizeof(char), 1, cfg_file); 320 | 321 | ssds_log(logDEBUG, "[%s = %s] written to configuration file\n", name, value); 322 | 323 | fclose(cfg_file); 324 | } 325 | return 0; 326 | } 327 | 328 | char* file_read_value(FILE* file, int max_length) 329 | { 330 | /* 331 | ** reads value from file until EOL 332 | */ 333 | char *value; 334 | char act_char; 335 | int value_lenght = 0; 336 | int allocated_lenght = 5; 337 | value = (char*)ssds_malloc(6*sizeof(char)); //5 + 1 338 | 339 | act_char = fgetc(file); 340 | while ((act_char != '\n') && (act_char != EOF)) 341 | { 342 | if (value_lenght == allocated_lenght) 343 | { 344 | allocated_lenght += 5; 345 | value = (char*)ssds_realloc(value, (allocated_lenght + 1)*sizeof(char)); 346 | } 347 | value[value_lenght++] = act_char; 348 | act_char = fgetc(file); 349 | } 350 | value[value_lenght] = '\0'; 351 | if ((value_lenght >= max_length) & (max_length != 0)) 352 | { 353 | ssds_log(logDEBUG, "[%s] shortened to:\n", value); 354 | value[max_length - 1] = '\0'; 355 | value = (char*)ssds_realloc(value, (max_length)*sizeof(char)); 356 | ssds_log(logDEBUG, "\t[%s] (max-length = %d)\n", value, max_length); 357 | } 358 | //ssds_log(logDEBUG, "***read \"%s\" of lenght %d\n", value, value_lenght); 359 | return value; 360 | } 361 | 362 | 363 | void compare(FILE* file, char* str, int len, char *state, char *act_c) 364 | { 365 | for (int i1 = 1; i1 <= len; i1++) 366 | { 367 | if (*act_c != str[i1]) 368 | { 369 | *state = 'c'; 370 | } 371 | if (i1 < len) 372 | { 373 | *act_c = fgetc(file); 374 | } 375 | } 376 | } 377 | -------------------------------------------------------------------------------- /src/common/cfg_parsing.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | //#ifndef _CFG_PARSING_H 22 | //#define _CFG_PARSING_H 23 | 24 | #include "includes.h" 25 | #include "log_handler.h" 26 | #include "mem_management.h" 27 | 28 | 29 | #ifdef __CASE_CLIENT 30 | #define CFG_FILE "../etc/rds-client.conf" 31 | #else 32 | #define CFG_FILE "../etc/rds-server.conf" 33 | #endif 34 | 35 | int read_cfg(char **ret_client_id, char **address, long int *comm_port); 36 | int write_to_cfg(char *name, char *value); 37 | int read_srv_cfg(long int* comm_port); 38 | int write_to_cfg(char *name, char *value); 39 | char* file_read_value(FILE* file, int max_length); 40 | void compare(FILE* file, char* str, int len, char *state, char *act_c); 41 | -------------------------------------------------------------------------------- /src/common/detect_missing_repos.c: -------------------------------------------------------------------------------- 1 | #include "detect_missing_repos.h" 2 | 3 | int check_for_missing_repos() 4 | { 5 | char **req_repos; 6 | 7 | FILE* reposFD; 8 | int req_repo_count = 0; 9 | int alloc_for_names = 10; 10 | req_repos = (char**)ssds_malloc(alloc_for_names * sizeof(char*)); 11 | 12 | 13 | /* Load names of required repos from file */ 14 | 15 | reposFD = fopen(REPO_LIST_FILE, "r"); 16 | if (reposFD == NULL) 17 | { 18 | ssds_log(logDEBUG, "Could not open required_repos_list file.\n"); 19 | return -1; 20 | } 21 | while (1) 22 | { 23 | if (alloc_for_names <= req_repo_count) 24 | { 25 | alloc_for_names += 5; 26 | req_repos = (char**)ssds_realloc(req_repos, alloc_for_names * sizeof(char*)); 27 | } 28 | req_repos[req_repo_count] = file_read_value(reposFD, 0); 29 | 30 | if (strlen(req_repos[req_repo_count]) >= REPO_NAME_MIN_LENGTH) 31 | { 32 | req_repo_count++; 33 | } 34 | 35 | char tc = fgetc(reposFD); 36 | if (tc == EOF) 37 | { 38 | break; 39 | } 40 | else 41 | { 42 | fseek(reposFD, SEEK_CUR, -1); 43 | } 44 | } 45 | fclose(reposFD); 46 | 47 | 48 | /* Load list of repos in /etc/yum.repos.d/ */ 49 | 50 | DIR* repo_dir = opendir(LOCAL_REPOS_LOCATION); 51 | struct dirent* dirs; 52 | alloc_for_names = 10; 53 | int local_repo_count = 0; 54 | char **local_repos; 55 | local_repos = (char**)ssds_malloc(alloc_for_names * sizeof(char*)); 56 | 57 | while ((dirs = readdir(repo_dir)) != NULL) 58 | { 59 | if (alloc_for_names <= local_repo_count) 60 | { 61 | alloc_for_names += 5; 62 | local_repos = (char**)ssds_realloc(local_repos, alloc_for_names * sizeof(char*)); 63 | } 64 | local_repos[local_repo_count] = dirs->d_name; 65 | local_repo_count++; 66 | } 67 | 68 | 69 | /* testing if all of required repos are present in local repos */ 70 | 71 | int missing_repos = 0; 72 | int found = 0; 73 | 74 | for (int i1 = 0; i1 < req_repo_count; i1++) 75 | { 76 | for (int i2 = 0; i2 < local_repo_count; i2++) 77 | { 78 | if ((strlen(req_repos[i1]) == strlen(local_repos[i2])) && (strncmp(req_repos[i1], local_repos[i2], strlen(req_repos[i1])) == 0)) 79 | { 80 | found = 1; 81 | break; 82 | } 83 | } 84 | if (found != 1) 85 | { 86 | ssds_log(logMESSAGE, "Missing repository [%s], ssds might not work correctly\n", req_repos[i1]); 87 | missing_repos++; 88 | } 89 | } 90 | 91 | 92 | closedir(repo_dir); 93 | for (int i1 = 0; i1 < req_repo_count; i1++) 94 | { 95 | ssds_free(req_repos[i1]); 96 | } 97 | ssds_free(req_repos); 98 | ssds_free(local_repos); 99 | return missing_repos; 100 | } -------------------------------------------------------------------------------- /src/common/detect_missing_repos.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _DETECT_MISSING_REPOS_H 22 | #define _DETECT_MISSING_REPOS_H 23 | 24 | #include 25 | #include "../common/includes.h" 26 | #include "../common/log_handler.h" 27 | #include "../common/mem_management.h" 28 | #include "../common/cfg_parsing.h" 29 | 30 | #define REPO_LIST_FILE "../required_repos_list.txt" 31 | #define LOCAL_REPOS_LOCATION "/etc/yum.repos.d/" 32 | #define REPO_NAME_MIN_LENGTH 4 33 | 34 | /* 35 | * returns 1 if everything is OK, -1 when error (for ex. missing file) 36 | * and number >=1 if that number of repos is missing 37 | */ 38 | int check_for_missing_repos(void); 39 | 40 | #endif -------------------------------------------------------------------------------- /src/common/errors.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _ERRORS_H_ 22 | #define _ERRORS_H_ 23 | 24 | enum ERRORS 25 | { 26 | OK = 0, 27 | SOCKET_ERROR, 28 | NETWORKING_ERROR, 29 | INTERNAL_ERROR, 30 | FILE_ERROR, 31 | PARAMS_ERROR, 32 | REPO_ERROR, 33 | JSON_ERROR, 34 | DOWNLOAD_ERROR, 35 | MEMORY_ERROR, 36 | ROOT_ERROR, 37 | RPM_ORDER_ERROR, 38 | INSTALL_ERROR, 39 | UPDATE_ERROR, 40 | ERASE_ERROR, 41 | ACTION_ERROR, 42 | EXIT 43 | }; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/common/globvar.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Server side dependency solving 3 | * transfer of dependency solving from local machine to server when installing new packages 4 | * 5 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel, Šimon Matěj 6 | * 7 | * Licensed under the GNU Lesser General Public License Version 2.1 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef _GLOBVAR_H 25 | #define _GLOBVAR_H 26 | 27 | #ifdef __cplusplus 28 | extern "C"{ 29 | #endif 30 | 31 | /**********************************************************/ 32 | /* Message codes used in json communication on both sides */ 33 | /**********************************************************/ 34 | 35 | enum{ 36 | GENERATE_ID = 1, 37 | SEND_SOLV,//2 38 | SEND_YUM_CONF, //3 39 | SOLV_MORE_FRAGMENT,//4 40 | SOLV_NO_MORE_FRAGMENT,//5 41 | GET_DEPENDENCY,//6 42 | GET_INSTALL,//7 43 | GET_UPDATE,//8 44 | GET_ERASE,//9 45 | GET_UPDATE_ALL,//10 46 | ANSWER_OK,//11 47 | ANSWER_WARNING,//12 48 | ANSWER_ERROR,//13 49 | ANSWER_NO_DEP //14 when dependencies are not ok 50 | }; 51 | 52 | typedef enum { 53 | JS_ARR_INSTALL = 0, 54 | JS_ARR_UPGRADE, 55 | JS_ARR_ERASE, 56 | JS_ARR_OBSOLETE, 57 | JS_ARR_UNNEEDED 58 | }SsdsJsArrayName; 59 | 60 | static const char* const SsdsJsArrayStr[] = {"install", "upgrade", "erase", "obsolete", "unneeded"}; 61 | 62 | 63 | #ifdef __cplusplus 64 | } 65 | #endif 66 | #endif 67 | -------------------------------------------------------------------------------- /src/common/includes.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef __INCLUDES_H_ 22 | #define __INCLUDES_H_ 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | //GLIB 29 | #include 30 | #include 31 | #include 32 | #include 33 | 34 | //Standard libraries 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | //Networking 47 | #include 48 | #include 49 | #include 50 | #include 51 | #include 52 | 53 | //Global variables 54 | #include "globvar.h" 55 | 56 | #ifdef __cplusplus 57 | } 58 | #endif //__INCLUDES_H_ 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /src/common/json_read.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "json_handler.h" 22 | 23 | SsdsJsonRead* ssds_js_rd_init() 24 | { 25 | SsdsJsonRead* new = (SsdsJsonRead*)ssds_malloc(sizeof(SsdsJsonRead)); 26 | new->parser = json_parser_new(); 27 | return new; 28 | } 29 | 30 | gboolean ssds_js_rd_parse(char* buffer, SsdsJsonRead* json) 31 | { 32 | GError *error = NULL; 33 | 34 | gboolean ret = json_parser_load_from_data(json->parser, (const gchar*)buffer, -1, &error); 35 | if(!ret) 36 | return EXIT_FAILURE; 37 | 38 | json->rootNode = json_parser_get_root(json->parser); 39 | 40 | JsonObject* obj=json_node_get_object(json->rootNode); 41 | json->dataNode=json_object_get_member(obj, (gchar*)"data"); 42 | json->dataObj=json_node_get_object(json->dataNode); 43 | return ret; 44 | } 45 | 46 | int ssds_rd_get_code(SsdsJsonRead* json) 47 | { 48 | int ret=-1; 49 | JsonObject* obj=json_node_get_object(json->rootNode); 50 | if(json_object_has_member(obj, (gchar*)"code")) 51 | ret=(int)json_object_get_int_member(obj, "code"); 52 | 53 | return ret; 54 | } 55 | 56 | int ssds_js_rd_get_read_bytes(SsdsJsonRead* json) 57 | { 58 | int ret=-1; 59 | JsonObject* obj = json->dataObj; 60 | if(json_object_has_member(obj, (gchar*)"read")) 61 | ret=(int)json_object_get_int_member(obj, "read"); 62 | 63 | return ret; 64 | } 65 | 66 | char* ssds_js_rd_get_message(SsdsJsonRead* json) 67 | { 68 | char *msg = NULL; 69 | JsonObject* obj = json->dataObj; 70 | if(json_object_has_member(obj, (gchar*)"message")) 71 | msg = (char *)json_object_get_string_member(obj, "message"); 72 | 73 | return msg; 74 | } 75 | 76 | GList* ssds_js_rd_find(SsdsJsonRead* json, char* x_path) 77 | { 78 | GList* ret = NULL; 79 | JsonPath* new_path = json_path_new(); 80 | json_path_compile(new_path, x_path, NULL); 81 | 82 | JsonNode* root = json_parser_get_root(json->parser); 83 | JsonNode* result = json_path_match(new_path, root); 84 | JsonArray* result_arr = json_node_get_array(result); 85 | 86 | ret = json_array_get_elements(result_arr); 87 | 88 | return ret; 89 | } 90 | 91 | // ================================================================================= 92 | // original json ˇˇˇ 93 | 94 | int ssds_js_rd_get_code(SsdsJsonRead* json) 95 | { 96 | int ret = -1; 97 | JsonObject* obj = json_node_get_object(json->rootNode); 98 | if(json_object_has_member(obj, (gchar*)"code")) 99 | ret = (int)json_object_get_int_member(obj, "code"); 100 | 101 | return ret; 102 | } 103 | 104 | void ssds_js_rd_get_packages(char** pkgs, SsdsJsonRead* json) 105 | { 106 | JsonArray* array = json_object_get_array_member(json->dataObj, "req_pkgs"); 107 | guint len = json_array_get_length(array); 108 | //pkgs->packages = (char**)ssds_malloc(len*sizeof(char*)); 109 | 110 | guint i; 111 | for(i = 0; i < len; i++) 112 | { 113 | pkgs[i] = (char*)malloc((strlen((char*)json_array_get_string_element(array,i)) + 1)*sizeof(char)); 114 | char* word = (char*)json_array_get_string_element(array, i); 115 | strcpy(pkgs[i], word); 116 | } 117 | 118 | pkgs[++i]=NULL; 119 | } 120 | 121 | 122 | void ssds_js_rd_repo_info(SsdsJsonRead* json, SsdsRepoInfoList* list) 123 | { 124 | JsonArray*array = json_object_get_array_member(json->dataObj, "repolist"); 125 | guint len = json_array_get_length(array); 126 | 127 | guint i; 128 | for(i = 0; i < len; i++) 129 | { 130 | SsdsRepoInfo* repo = ssds_js_rd_repoinfo_init(); 131 | 132 | JsonObject* obj = json_array_get_object_element(array, i); 133 | repo->type = (int)json_object_get_int_member(obj, "type"); 134 | 135 | char* currName = (char*)json_object_get_string_member(obj, "name"); 136 | repo->name = (char*)ssds_malloc((strlen(currName)+1)*sizeof(char)); 137 | strcpy(repo->name, currName); 138 | 139 | JsonArray* url_arr = json_object_get_array_member(obj, (gchar*)"repo_url"); 140 | int arr_len = json_array_get_length(url_arr); 141 | repo->urls = (char**)ssds_malloc(arr_len*(sizeof(char*))); 142 | 143 | int j; 144 | for(j = 0; j < arr_len; j++) 145 | { 146 | char* word = (char*)json_array_get_string_element(url_arr, j); 147 | repo->urls[j] = (char*)ssds_malloc((strlen(word)+1)*sizeof(char)); 148 | strcpy(repo->urls[j], word); 149 | repo->count++; 150 | } 151 | 152 | list->repoInfoList = g_slist_append(list->repoInfoList, repo); 153 | } 154 | } 155 | 156 | 157 | SsdsPkgInfo* ssds_js_rd_pkginfo_init() 158 | { 159 | SsdsPkgInfo* new = (SsdsPkgInfo*)ssds_malloc(sizeof(SsdsPkgInfo)); 160 | new->packages = NULL; 161 | new->length = 0; 162 | return new; 163 | } 164 | 165 | 166 | SsdsRepoInfo* ssds_js_rd_repoinfo_init() 167 | { 168 | SsdsRepoInfo* new = (SsdsRepoInfo*)ssds_malloc(sizeof(SsdsRepoInfo)); 169 | new->count = 0; 170 | new->type = 0; 171 | new->name = NULL; 172 | new->urls = NULL; 173 | return new; 174 | } 175 | 176 | SsdsRepoInfoList* ssds_js_rd_list_init() 177 | { 178 | SsdsRepoInfoList* new = (SsdsRepoInfoList*)ssds_malloc(sizeof(SsdsRepoInfoList)); 179 | new->repoInfoList = NULL; 180 | return new; 181 | } 182 | 183 | /**********************/ 184 | /* mainly client part */ 185 | /**********************/ 186 | SsdsJsonAnswer* ssds_js_rd_answer_init() 187 | { 188 | SsdsJsonAnswer* new = (SsdsJsonAnswer*)ssds_malloc(sizeof(SsdsJsonAnswer)); 189 | new->name = NULL; 190 | new->pkgList = NULL; 191 | return new; 192 | } 193 | 194 | SsdsJsonPkg* ssds_js_rd_pkg_init() 195 | { 196 | SsdsJsonPkg* new = (SsdsJsonPkg*)ssds_malloc(sizeof(SsdsJsonPkg)); 197 | new->pkg_name = NULL; 198 | new->pkg_loc = NULL; 199 | new->base_url = NULL; 200 | new->metalink = NULL; 201 | return new; 202 | } 203 | 204 | int ssds_js_rd_get_count(SsdsJsonRead* json, char* name) 205 | { 206 | const char* default_path="$.data.."; 207 | int length=strlen(default_path)+strlen(name); 208 | char* full_path=(char*)malloc((length+1)*sizeof(char)); 209 | strncpy(full_path, default_path, strlen(default_path)+1); 210 | strncat(full_path, name, strlen(name)); 211 | 212 | JsonPath* new_path = json_path_new(); 213 | json_path_compile(new_path, full_path, NULL); 214 | 215 | JsonNode* result = json_path_match(new_path, json->rootNode); 216 | JsonArray* result_array = json_node_get_array(result); 217 | JsonArray* final = json_array_get_array_element(result_array, 0); 218 | int ret = json_array_get_length(final); 219 | 220 | free(full_path); 221 | return ret; 222 | } 223 | 224 | GSList* ssds_js_rd_parse_answer(const char* name, SsdsJsonRead* json) 225 | { 226 | JsonArray* array = json_object_get_array_member(json->dataObj, name); 227 | int count = ssds_js_rd_get_count(json, name); 228 | GSList* ret = g_slist_alloc(); 229 | 230 | for(int i=0; ipkg_name = (char*)ssds_malloc((strlen(pkg_name)+1)*sizeof(char)); 238 | strncpy(one_pkg->pkg_name, pkg_name,strlen(pkg_name)+1); 239 | }else{ 240 | one_pkg->pkg_name = NULL; 241 | } 242 | 243 | //name of package location on repository 244 | char* pkg_loc = (char*)json_object_get_string_member(obj, "pkg_loc"); 245 | if(pkg_loc != NULL){ 246 | one_pkg->pkg_loc = (char*)ssds_malloc((strlen(pkg_loc)+1)*sizeof(char)); 247 | strncpy(one_pkg->pkg_loc, pkg_loc,strlen(pkg_loc)+1); 248 | }else{ 249 | one_pkg->pkg_loc = NULL; 250 | } 251 | 252 | //baseurl or null 253 | if(json_object_get_null_member(obj, "base_url")) 254 | { 255 | char* meta = (char*)json_object_get_string_member(obj, "metalink"); 256 | if(meta != NULL){ 257 | one_pkg->metalink = (char*)ssds_malloc((strlen(meta)+1)*sizeof(char)); 258 | strncpy(one_pkg->metalink, meta, strlen(meta)+1); 259 | }else{ 260 | one_pkg->metalink = NULL; 261 | } 262 | } 263 | else 264 | { 265 | char* base = (char*)json_object_get_string_member(obj, "base_url"); 266 | if(base != NULL){ 267 | one_pkg->base_url = (char*)ssds_malloc((strlen(base)+1)*sizeof(char)); 268 | strncpy(one_pkg->base_url, base, strlen(base)+1); 269 | }else{ 270 | one_pkg->base_url = NULL; 271 | } 272 | } 273 | 274 | ret = g_slist_append(ret, one_pkg); 275 | } 276 | 277 | return ret; 278 | } 279 | -------------------------------------------------------------------------------- /src/common/log_handler.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "log_handler.h" 22 | 23 | const char* log_lvl_msg[7] = {"INFO", "MESSAGE", "WARNING", "ERROR", "DEBUG", "SSDS", "QUESTION"}; 24 | int __verbose = 0; 25 | int __debug = 0; 26 | 27 | void ssds_log(int log_level, const char *message, ...) 28 | { 29 | FILE *flog = fopen(LOG_FILE, "a"); 30 | time_t current_time = time(NULL); 31 | struct tm *ts = localtime(¤t_time); 32 | 33 | if(flog == NULL) 34 | { 35 | fprintf(stderr, "[%d/%d/%d %02d:%02d:%02d SSDS ERROR]: Unable to open log file.\n", 36 | ts->tm_mday, ts->tm_mon+1, ts->tm_year-100, 37 | ts->tm_hour, ts->tm_min, ts->tm_sec); 38 | exit(EXIT_FAILURE); 39 | } 40 | 41 | if(log_level != logDEBUG) 42 | fprintf(flog, "[%d/%d/%d %02d:%02d:%02d %s]: ", 43 | ts->tm_mday, ts->tm_mon+1, ts->tm_year-100, 44 | ts->tm_hour, ts->tm_min, ts->tm_sec, 45 | log_lvl_msg[log_level]);//beginning of every message 46 | 47 | va_list args; 48 | va_start(args, message); 49 | 50 | switch(log_level){ 51 | case logSSDS: 52 | fprintf(stdout, "\033[92m[%d/%d/%d %02d:%02d:%02d SSDS]\033[0m: ", 53 | ts->tm_mday, ts->tm_mon+1, ts->tm_year-100, 54 | ts->tm_hour, ts->tm_min, ts->tm_sec); 55 | vfprintf(stdout, message, args); 56 | break; 57 | 58 | case logQUESTION: 59 | fprintf(stdout, "\033[1;92m[QUESTION]\033[0m: "); 60 | vfprintf(stdout, message, args); 61 | break; 62 | 63 | case logINFO: 64 | if(__verbose == 1) 65 | { 66 | fprintf(stdout, "\033[96m[%d/%d/%d %02d:%02d:%02d INFO]\033[0m: ", 67 | ts->tm_mday, ts->tm_mon+1, ts->tm_year-100, 68 | ts->tm_hour, ts->tm_min, ts->tm_sec); 69 | vfprintf(stdout, message, args); 70 | } 71 | break; 72 | 73 | case logMESSAGE: 74 | fprintf(stdout, "\033[94m[MESSAGE]\033[0m: "); 75 | vfprintf(stdout, message, args); 76 | break; 77 | 78 | case logWARNING: 79 | fprintf(stderr, "\033[93m[%02d:%02d:%02d WARNING]\033[0m: ", 80 | ts->tm_hour, ts->tm_min, ts->tm_sec); 81 | vfprintf(stderr, message, args); 82 | break; 83 | 84 | case logERROR: 85 | fprintf(stderr, "\033[91m[%02d:%02d:%02d ERROR]\033[0m: ", 86 | ts->tm_hour, ts->tm_min, ts->tm_sec); 87 | vfprintf(stderr, message, args); 88 | break; 89 | case logDEBUG: 90 | if(__debug == 1) 91 | { 92 | fprintf(stderr, "\033[95m[%02d:%02d:%02d DEBUG]\033[0m: ", 93 | ts->tm_hour, ts->tm_min, ts->tm_sec); 94 | vfprintf(stderr, message, args); 95 | } 96 | break; 97 | } 98 | 99 | if(log_level != logDEBUG) 100 | { 101 | va_start(args, message); 102 | vfprintf(flog, message, args); 103 | } 104 | fclose(flog); 105 | va_end(args); 106 | } 107 | 108 | void set_verbose() 109 | { 110 | __verbose = 1; 111 | } 112 | 113 | void unset_verbose() 114 | { 115 | __verbose = 0; 116 | } 117 | 118 | void set_debug() 119 | { 120 | __debug = 1; 121 | } 122 | 123 | void unset_debug() 124 | { 125 | __debug = 0; 126 | } 127 | -------------------------------------------------------------------------------- /src/common/log_handler.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _LOG_HANDLER_H 22 | #define _LOG_HANDLER_H 23 | 24 | #include "includes.h" 25 | #ifdef __cplusplus 26 | extern "C"{ 27 | #endif 28 | 29 | /** Location of logging file */ 30 | #define LOG_FILE "/tmp/ssds.log" 31 | 32 | /** 33 | * Used for logging severence level 34 | */ 35 | enum LogClass{ 36 | logINFO=0, /**< INFO is for general info messages - prints only when __verbose == 1 */ 37 | logMESSAGE, /**< MESSAGE is for messages for user */ 38 | logWARNING, /**< WARNING is for describing unorthodox or undefined behaviour */ 39 | logERROR, /**< ERROR is for fatal situations */ 40 | logDEBUG, /**< DEBUG is only for debugging - prints only when __debug == 1*/ 41 | logSSDS, /**< SSDS is just for first and last message of server and client - printed everytime */ 42 | logQUESTION /**< QUESTION is for messages, which will wait for user interaction */ 43 | }; 44 | 45 | /** Contains severence level message for ssds_log function */ 46 | extern const char* log_lvl_msg[7]; 47 | 48 | /** 49 | * Used on global scope to indicate if verbose option is on. 50 | * If __verbose == 0 - ssds_log prints only WARNING and ERROR to stderr. 51 | * Set to 0 by default. 52 | */ 53 | extern int __verbose; 54 | 55 | /** 56 | * Used on global scope to indicate if debug option is on. 57 | * If __debug==0 - ssds_log doesn't print anything with logDEBUG. 58 | * Set to 0 by default. 59 | */ 60 | extern int __debug; 61 | 62 | /** 63 | * Used for logging. Works the same way as printf() but takes 64 | * severity level as an argument. Prints given message into file 65 | * and to stderr. By default doesn't print INFO, MESSAGE and DEBUG 66 | * to stderr. Use set_verbose to turn on INFO and MESSAGE output to 67 | * stderr and set_debug to turn on DEBUG output to stderr. 68 | * The message supports formatting as printf with %d, %s, \n etc 69 | * @param log_level int 70 | * @param message char* 71 | */ 72 | void ssds_log(int log_level, const char *message, ...); 73 | 74 | 75 | /** 76 | * Sets __verbose to 1. This will allow INFO and MESSAGE to be printed 77 | * to stderr. 78 | */ 79 | void set_verbose(); 80 | 81 | /** 82 | * Sets __verbose to 0. 83 | */ 84 | void unset_verbose(); 85 | 86 | /** 87 | * Sets __debug to 1. This will allow DEBUG messages to be printed 88 | * to stderr and to log file. 89 | */ 90 | void set_debug(); 91 | 92 | /** 93 | * Sets __debug to 0. 94 | */ 95 | void unset_debug(); 96 | 97 | #ifdef __cplusplus 98 | } 99 | #endif 100 | 101 | #endif /* _LOG_HANDLER_H */ 102 | -------------------------------------------------------------------------------- /src/common/mem_management.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "mem_management.h" 22 | 23 | Ssds_gc * global_gc = NULL; 24 | 25 | int allocated = 0; 26 | int num_items = 0; 27 | 28 | void ssds_signal_handler(int signum) 29 | { 30 | ssds_log(logERROR, "End with signal number %d.\n", signum); 31 | ssds_gc_cleanup(); 32 | exit(signum); 33 | } 34 | 35 | void ssds_gc_cleanup() 36 | { 37 | Ssds_gc_item * next = NULL; 38 | Ssds_gc_item * item = global_gc->top; 39 | while(item != NULL) 40 | { 41 | next = item->next; 42 | switch(item->type) 43 | { 44 | case SOCKET: 45 | close(item->data.sock_fd); 46 | break; 47 | case PTR: 48 | if(item->data.ptr != NULL) 49 | { 50 | free(item->data.ptr); 51 | } 52 | break; 53 | default: 54 | break; 55 | } 56 | 57 | free(item); 58 | item = next; 59 | } 60 | free(global_gc); 61 | global_gc = NULL; 62 | ssds_log(logDEBUG,"Number of items: %d Memory allocated: %d \n",num_items, allocated); 63 | allocated = 0; 64 | num_items = 0; 65 | } 66 | 67 | Ssds_gc_item * ssds_gc_search(Alloc_data * data, int type) 68 | { 69 | for (Ssds_gc_item * tmp = global_gc->top; tmp != NULL; tmp = tmp->next) 70 | { 71 | switch(type) 72 | { 73 | case SOCKET: 74 | if(tmp->data.sock_fd == data->sock_fd) 75 | { 76 | return tmp; 77 | } 78 | break; 79 | case PTR: 80 | if(tmp->data.ptr == data->ptr) 81 | { 82 | return tmp; 83 | } 84 | break; 85 | default: 86 | break; 87 | } 88 | } 89 | return NULL; 90 | } 91 | 92 | void ssds_gc_remove(Alloc_data * data, int type) 93 | { 94 | Ssds_gc_item * item = ssds_gc_search(data, type); 95 | if(item != NULL) 96 | { 97 | if(item->next == NULL && item->prev == NULL) //only item in gc 98 | { 99 | global_gc->top = NULL; 100 | } 101 | else if(item->next == NULL && item->prev != NULL) //item on the end of gc 102 | { 103 | item->prev->next = NULL; 104 | } 105 | else if(item->next != NULL && item->prev == NULL) //item on the start of gc 106 | { 107 | item->next->prev = NULL; 108 | global_gc->top = item->next; 109 | } 110 | else if(item->next != NULL && item->prev != NULL) //item in between two other items 111 | { 112 | item->prev->next = item->next; 113 | item->next->prev = item->prev; 114 | } 115 | free(item); 116 | } 117 | } 118 | 119 | void ssds_gc_push(Alloc_data * data, int type) 120 | { 121 | //if(ssds_gc_search(data, type) != NULL) 122 | //{ 123 | // return; 124 | //} 125 | Ssds_gc_item * new_item = (Ssds_gc_item *) malloc(sizeof(Ssds_gc_item)); 126 | if(new_item == NULL) 127 | { 128 | fprintf(stderr, "Failed to allocate new item in ssds_gc_push.\n"); 129 | ssds_gc_cleanup(); 130 | exit(MEMORY_ERROR); 131 | } 132 | new_item->type = type; 133 | new_item->next = NULL; 134 | new_item->prev = NULL; 135 | switch(type) 136 | { 137 | case SOCKET: 138 | new_item->data.sock_fd = data->sock_fd; 139 | break; 140 | case PTR: 141 | new_item->data.ptr = data->ptr; 142 | default: 143 | break; 144 | 145 | } 146 | if(global_gc->top == NULL) 147 | { 148 | global_gc->top = new_item; 149 | } 150 | else 151 | { 152 | global_gc->top->prev = new_item; 153 | new_item->next = global_gc->top; 154 | global_gc->top = new_item; 155 | } 156 | } 157 | 158 | void ssds_gc_push_ptr(void * ptr) 159 | { 160 | Alloc_data data = { .ptr = ptr}; 161 | //data->ptr = ptr; 162 | ssds_gc_push(&data, PTR); 163 | } 164 | 165 | void ssds_gc_push_socket(int socket) 166 | { 167 | Alloc_data data = {.sock_fd = socket}; 168 | //data->sock_fd = socket; 169 | ssds_gc_push(&data,SOCKET); 170 | } 171 | 172 | void ssds_free(void * ptr) 173 | { 174 | num_items -= 1; 175 | ssds_gc_remove_ptr(ptr); 176 | free(ptr); 177 | } 178 | 179 | void ssds_close(int socket) 180 | { 181 | num_items -= 1; 182 | ssds_gc_remove_socket(socket); 183 | close(socket); 184 | } 185 | 186 | void ssds_gc_remove_ptr(void * ptr) 187 | { 188 | Alloc_data data = {.ptr = ptr}; 189 | //data->ptr = ptr; 190 | ssds_gc_remove(&data, PTR); 191 | } 192 | 193 | void ssds_gc_remove_socket(int socket) 194 | { 195 | Alloc_data data = {.sock_fd = socket}; 196 | //data->sock_fd = socket; 197 | ssds_gc_remove(&data,SOCKET); 198 | } 199 | 200 | void * ssds_realloc(void * old_ptr, int size) 201 | { 202 | allocated += size; 203 | void * new_ptr = realloc(old_ptr, size); 204 | if(new_ptr == NULL) 205 | { 206 | ssds_log(logERROR, "Failed to reallocate pointer in ssds_realloc.\n"); 207 | return NULL; 208 | } 209 | if(new_ptr != old_ptr) 210 | { 211 | ssds_gc_remove_ptr(old_ptr); 212 | ssds_gc_push_ptr(new_ptr); 213 | } 214 | return new_ptr; 215 | } 216 | 217 | void * ssds_malloc(int size) 218 | { 219 | num_items += 1; 220 | allocated += size; 221 | void * new_ptr = malloc(size); 222 | if(new_ptr == NULL) 223 | { 224 | ssds_log(logERROR, "Failed to allocate pointer in ssds_malloc.\n"); 225 | return NULL; 226 | } 227 | ssds_gc_push_ptr(new_ptr); 228 | return new_ptr; 229 | } 230 | 231 | void * ssds_calloc(int n_items, int size) 232 | { 233 | num_items += 1; 234 | allocated += n_items * size; 235 | void * new_ptr = calloc(n_items, size); 236 | if(new_ptr == NULL) 237 | { 238 | ssds_log(logERROR, "Failed to allocate pointer in ssds_malloc.\n"); 239 | return NULL; 240 | } 241 | ssds_gc_push_ptr(new_ptr); 242 | return new_ptr; 243 | } 244 | 245 | 246 | void ssds_gc_init() 247 | { 248 | global_gc = (Ssds_gc *) malloc(sizeof(Ssds_gc)); 249 | if(global_gc == NULL) 250 | { 251 | ssds_log(logERROR, "Failed to allocate garbace collector.\n"); 252 | exit(MEMORY_ERROR); 253 | } 254 | global_gc->top = NULL; 255 | } 256 | 257 | int ssds_socket(int domain, int type, int protocol) 258 | { 259 | num_items += 1; 260 | int new_socket = socket(domain, type, protocol); 261 | if(new_socket < 0) 262 | { 263 | ssds_log(logERROR, "Failed to open socket.\n"); 264 | return -1; 265 | } 266 | ssds_gc_push_socket(new_socket); 267 | return new_socket; 268 | } 269 | 270 | int ssds_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len) 271 | { 272 | num_items += 1; 273 | int new_socket = accept(socket, address, address_len); 274 | if(new_socket < 0) 275 | { 276 | ssds_log(logERROR, "Failed to accept socket.\n"); 277 | return -1; 278 | } 279 | ssds_gc_push_socket(new_socket); 280 | return new_socket; 281 | } 282 | 283 | Ssds_gc * ssds_gc_get_header() 284 | { 285 | return global_gc; 286 | } 287 | -------------------------------------------------------------------------------- /src/common/mem_management.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _MEM_MANAGEMENT_H 22 | #define _MEM_MANAGEMENT_H 23 | 24 | #include "includes.h" 25 | #include "log_handler.h" 26 | #include "errors.h" 27 | 28 | 29 | #ifdef __cplusplus 30 | extern "C"{ 31 | #endif 32 | 33 | enum ALLOC_TYPES 34 | { 35 | SOCKET, 36 | PTR 37 | }; 38 | 39 | typedef union al_dat 40 | { 41 | int sock_fd; 42 | void * ptr; 43 | }Alloc_data; 44 | 45 | typedef struct mem_item 46 | { 47 | Alloc_data data; 48 | int type; 49 | struct mem_item * next; 50 | struct mem_item * prev; 51 | }Ssds_gc_item; 52 | 53 | typedef struct s_gc 54 | { 55 | Ssds_gc_item * top; 56 | }Ssds_gc; 57 | 58 | /** 59 | * Function called when termination signals are recieved. 60 | */ 61 | void ssds_signal_handler(int signum); 62 | 63 | /** 64 | * Deletes everything in the garbage collector including garbage collector. 65 | */ 66 | void ssds_gc_cleanup(); 67 | 68 | /** 69 | * Searches for a pointer in the garbage collector 70 | * @param ptr pointer that is searched 71 | * @return 1 if pointer is in garbage collector, 0 if its not 72 | */ 73 | Ssds_gc_item * ssds_gc_search(Alloc_data * data, int type); 74 | 75 | /** 76 | * Removes pointer from garbage collector 77 | * @param ptr pointer that is removed 78 | */ 79 | void ssds_gc_remove(Alloc_data * data, int type); 80 | 81 | /** 82 | * Pushes pointer into garbage collector 83 | * @param ptr pushed pointer 84 | */ 85 | void ssds_gc_push(Alloc_data * data, int type); 86 | 87 | /** 88 | * Realloc function that has the same interface as realloc but works 89 | * with garbage collector 90 | * @param old_ptr old pointer 91 | * @param size new size of pointer 92 | * @return new reallocated pointer 93 | */ 94 | void * ssds_realloc(void * old_ptr, int size); 95 | 96 | /** 97 | * Malloc function that has the same interface as realloc but works 98 | * with garbage collector 99 | * @param size number of bytes to be allocated 100 | * @return allocated pointer 101 | */ 102 | void * ssds_malloc(int size); 103 | 104 | /** 105 | * Malloc function that has the same interface as realloc but works 106 | * with garbage collector 107 | * @param n_items number of chunks 108 | * @param size size of chunks 109 | * @return allocated pointer 110 | */ 111 | void * ssds_calloc(int n_items, int size); 112 | 113 | /** 114 | * Initialization function for garbage collector. Must be called before 115 | * user allocates something. 116 | */ 117 | void ssds_gc_init(); 118 | 119 | /** 120 | * Pushes pointer to garbage collector. 121 | * @param ptr pushed pointer 122 | */ 123 | void ssds_gc_push_ptr(void * ptr); 124 | 125 | /** 126 | * @Pushes socket to garbage collector. 127 | * @param socket pushed socket 128 | */ 129 | void ssds_gc_push_socket(int socket); 130 | 131 | /** 132 | * Removes pointer from garbage collector. 133 | * @param ptr removed pointer 134 | */ 135 | void ssds_gc_remove_ptr(void * ptr); 136 | 137 | /** 138 | * Removes socket from garbage collector. 139 | * @param socket removed socket 140 | */ 141 | void ssds_gc_remove_socket(int socket); 142 | 143 | /** 144 | * Removes pointer from garbage collector and calls free on it. 145 | * @param ptr freed pointer 146 | */ 147 | void ssds_free(void * ptr); 148 | 149 | /** 150 | * Removes socket from garbage collector and closes it. 151 | * @param socket closed socket 152 | */ 153 | void ssds_close(int socket); 154 | 155 | /** 156 | * Creates a socket and pushes it into garbage collector. 157 | * @param domain parameteor of socket 158 | * @param type parameteor of socket 159 | * @param protocol parameteor of socket 160 | * @return new socket 161 | */ 162 | int ssds_socket(int domain, int type, int protocol); 163 | 164 | /** 165 | * Accepts a socket and pushes it into garbage collector 166 | * @param socket parameter of accept 167 | * @param address parameter of accept 168 | * @param address_len parameter of accept 169 | * @return accepted socket 170 | */ 171 | int ssds_accept(int socket, struct sockaddr *restrict address, socklen_t *restrict address_len); 172 | 173 | /** 174 | * Returns pointer to GC, used for testing 175 | * @return pointer to GC 176 | */ 177 | Ssds_gc * ssds_gc_get_header(); 178 | 179 | 180 | #ifdef __cplusplus 181 | } 182 | #endif 183 | 184 | #endif //_MEM_MANAGEMENT_H 185 | -------------------------------------------------------------------------------- /src/common/network_security.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "network_security.h" 22 | 23 | 24 | /* 25 | DO NOT CHANGE FOLLOWING VALUES, 26 | IF YOU WANT TO DISABLE SSL, DO SO BY CHANGING USE_SSL IN THE .h FILE 27 | */ 28 | int _ssl_connected = 0; // connection secured 29 | SSL_CTX *ctx = NULL; // SSL context 30 | SSL *ssl = NULL; // SSL connection 31 | 32 | 33 | ssize_t ssds_read(int fd, void *buf, size_t count) 34 | { 35 | ssds_log(logDEBUG, "Reading max %d bytes of data\n", count); 36 | int res = -1; 37 | if (USE_SSL == 0) // unencrypted communication 38 | { 39 | ssds_log(logDEBUG, "Using unencrypted read\n"); 40 | res = read(fd, buf, count); 41 | } 42 | else // encrypted communication 43 | { 44 | ssds_log(logDEBUG, "Using encrypted read\n"); 45 | if (_ssl_connected == 0) // initialize connection 46 | { 47 | if (initialize_secure_connection(fd) == -1) 48 | { 49 | if (ssl != NULL) SSL_free(ssl); 50 | if (ctx != NULL) SSL_CTX_free(ctx); 51 | return -1; 52 | } 53 | else 54 | { 55 | ssds_log(logMESSAGE, "SSL successfully connected\n"); 56 | _ssl_connected = 1; 57 | } 58 | } 59 | res = SSL_read(ssl, buf, count); 60 | if (res == -1) 61 | { 62 | ssds_log(logERROR, "SSL read failed\n"); 63 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 64 | } 65 | } 66 | ssds_log(logDEBUG, "Read %d bytes\n", res); 67 | return res; 68 | } 69 | 70 | 71 | ssize_t ssds_write(int fd, const void *buf, size_t count) 72 | { 73 | ssds_log(logDEBUG, "Writing %d bytes of data\n", count); 74 | int res = -1; 75 | if (USE_SSL == 0) 76 | { 77 | ssds_log(logDEBUG, "Using unencrypted write\n"); 78 | res = write(fd, buf, count); 79 | } 80 | else 81 | { 82 | ssds_log(logDEBUG, "Using encrypted write\n"); 83 | if (_ssl_connected == 0) // not connected 84 | { 85 | if (initialize_secure_connection(fd) == -1) 86 | { 87 | if (ssl != NULL) SSL_free(ssl); 88 | if (ctx != NULL) SSL_CTX_free(ctx); 89 | return -1; 90 | } 91 | else 92 | { 93 | ssds_log(logMESSAGE, "SSL successfully connected\n"); 94 | _ssl_connected = 1; 95 | } 96 | } 97 | res = SSL_write(ssl, buf, count); 98 | if (res == -1) 99 | { 100 | ssds_log(logERROR, "SSL write failed\n"); 101 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 102 | } 103 | } 104 | ssds_log(logDEBUG, "Written %d bytes\n", res); 105 | return res; 106 | } 107 | 108 | 109 | int initialize_secure_connection(int fd) 110 | { 111 | ssds_log(logDEBUG, "Init SSL\n"); 112 | sleep(5); 113 | ctx = InitCTX(); 114 | if (ctx == NULL) 115 | { 116 | return -1; 117 | } 118 | 119 | //server loads certificate and key 120 | #ifdef __CASE_SERVER 121 | ssds_log(logDEBUG, "Server is loading certificates\n"); 122 | if (LoadCertificates(ctx, MY_CERT, MY_KEY) == -1) 123 | { 124 | ssds_log(logERROR, "SSL fail (server load certs)\n"); 125 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 126 | return -1; 127 | } 128 | else 129 | { 130 | ssds_log(logMESSAGE, "SSL certificates successfully loaded\n"); 131 | } 132 | #endif 133 | 134 | ssl = SSL_new(ctx); 135 | SSL_set_fd(ssl, fd); 136 | 137 | //client connects to server 138 | #ifdef __CASE_CLIENT 139 | if (SSL_connect(ssl) == -1) 140 | { 141 | ssds_log(logERROR, "SSL fail (client connect)\n"); 142 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 143 | return -1; 144 | } 145 | #endif 146 | 147 | //server accepts client 148 | #ifdef __CASE_SERVER 149 | if (SSL_accept(ssl) == -1) 150 | { 151 | ssds_log(logERROR, "SSL fail (server accept)\n"); 152 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 153 | return -1; 154 | } 155 | #endif 156 | 157 | if (ShowCerts(ssl) == -1) 158 | { 159 | ssds_log(logERROR, "SSL fail (no peer certificates avalaible)\n"); 160 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 161 | return -1; 162 | } 163 | return 0; 164 | } 165 | 166 | 167 | SSL_CTX* InitCTX(void) 168 | { 169 | const SSL_METHOD *method; 170 | 171 | SSL_library_init(); 172 | OpenSSL_add_all_algorithms(); 173 | SSL_load_error_strings(); 174 | #ifdef __CASE_CLIENT 175 | method = TLSv1_2_client_method(); 176 | #endif 177 | #ifdef __CASE_SERVER 178 | method = TLSv1_2_server_method(); 179 | #endif 180 | ctx = SSL_CTX_new(method); 181 | if ( ctx == NULL ) 182 | { 183 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 184 | } 185 | if (SSL_CTX_set_cipher_list(ctx, CIPHERS) != 1) 186 | { 187 | ssds_log(logERROR, "Couldnt use any ciphers\n"); 188 | return NULL; 189 | } 190 | return ctx; 191 | } 192 | 193 | 194 | int ShowCerts(SSL* ssl) 195 | { 196 | X509 *cert; 197 | char *line; 198 | cert = SSL_get_peer_certificate(ssl); 199 | if ( cert != NULL ) 200 | { 201 | ssds_log(logDEBUG, "Peer certificate:\n"); 202 | line = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); 203 | ssds_log(logDEBUG, "Subject:\n%s\n", line); 204 | free(line); 205 | line = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); 206 | ssds_log(logDEBUG, "Issuer:\n%s\n", line); 207 | free(line); 208 | X509_free(cert); 209 | return 0; 210 | } 211 | else 212 | ssds_log(logERROR, "No peer certificate avalaible.\n"); 213 | return -1; 214 | } 215 | 216 | 217 | int LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile) 218 | { 219 | if (SSL_CTX_use_certificate_file(ctx, CertFile, CERT_FILETYPE) <= 0) 220 | { 221 | ssds_log(logERROR, "Could not load certificate\n"); 222 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 223 | return -1; 224 | } 225 | if (SSL_CTX_use_PrivateKey_file(ctx, KeyFile, KEY_FILETYPE) <= 0) 226 | { 227 | ssds_log(logERROR, "Could not load private key\n"); 228 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 229 | return -1; 230 | } 231 | if (!SSL_CTX_check_private_key(ctx)) 232 | { 233 | ssds_log(logERROR, "Certificate and key do not match\n"); 234 | if (PRINT_SSL_ERRORS_TO_STDERR) ERR_print_errors_fp(stderr); 235 | return -1; 236 | } 237 | 238 | SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); 239 | SSL_CTX_set_verify_depth(ctx, 4); 240 | return 0; 241 | } 242 | 243 | void crypted_connection_reset() 244 | { 245 | if (ssl != NULL) SSL_free(ssl); 246 | if (ctx != NULL) SSL_CTX_free(ctx); 247 | _ssl_connected = 0; 248 | } -------------------------------------------------------------------------------- /src/common/network_security.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _NETWORK_SECURITY_H 22 | #define _NETWORK_SECURITY_H 23 | 24 | #include "log_handler.h" 25 | #include "mem_management.h" 26 | #include "includes.h" 27 | #include "cfg_parsing.h" 28 | #include "errors.h" 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | 36 | #define USE_SSL 0 // 0 = do not use SSL, 1 = do use SSL 37 | 38 | #define MY_CERT "cert/public.pem" // public cetrificate file 39 | #define MY_KEY "cert/private.pem" // private key file 40 | #define CERT_FILETYPE SSL_FILETYPE_PEM // certificate file format 41 | #define KEY_FILETYPE SSL_FILETYPE_PEM // key file format 42 | /* for information about SSL filetype definitions visit: 43 | * https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_use_certificate.html 44 | */ 45 | 46 | #define PRINT_SSL_ERRORS_TO_STDERR 0 47 | 48 | #define CIPHERS "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:\ 49 | ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:\ 50 | ECDHE-ECDSA-AES128-SHA:AES128-GCM-SHA256:AES128-SHA256:AES128-SHA:\ 51 | DHE-DSS-AES128-GCM-SHA256:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES128-SHA256:\ 52 | DHE-DSS-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:PSK-AES128-CBC-SHA:\ 53 | CAMELLIA128-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:ECDHE-RSA-AES256-GCM-SHA384:\ 54 | ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:\ 55 | ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:AES256-GCM-SHA384:AES256-SHA256:\ 56 | AES256-SHA:DHE-DSS-AES256-GCM-SHA384:DHE-RSA-AES256-GCM-SHA384:\ 57 | DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA256:DHE-RSA-AES256-SHA:\ 58 | DHE-DSS-AES256-SHA:PSK-AES256-CBC-SHA:CAMELLIA256-SHA:DHE-RSA-CAMELLIA256-SHA:\ 59 | DHE-DSS-CAMELLIA256-SHA:ECDHE-RSA-DES-CBC3-SHA:ECDHE-ECDSA-DES-CBC3-SHA:\ 60 | DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:EDH-DSS-DES-CBC3-SHA:PSK-3DES-EDE-CBC-SHA:\ 61 | ECDHE-RSA-RC4-SHA:ECDHE-ECDSA-RC4-SHA:RC4-SHA:PSK-RC4-SHA" 62 | 63 | #ifdef __cplusplus 64 | extern "C"{ 65 | #endif 66 | 67 | 68 | /** 69 | * Function which uses either standard read(), or crypted read. 70 | * @param fd communication socket descriptor 71 | * @param *buf buffer for incoming message 72 | * @param count maximum number of bytes to read 73 | * @return ssize_t bytes read 74 | */ 75 | ssize_t ssds_read(int fd, void *buf, size_t count); 76 | 77 | /** 78 | * Function which uses either standard write(), or crypted write 79 | * @param fd communication socket descriptor 80 | * @param *buf buffer with outcomming message 81 | * @param count maximum number of bytes to send 82 | * @return ssize_t bytes sent 83 | */ 84 | ssize_t ssds_write(int fd, const void *buf, size_t count); 85 | 86 | /** 87 | * Shutdowns current ssl connection 88 | */ 89 | void crypted_connection_reset(); 90 | 91 | /** 92 | * creates SSL connection 93 | * @param fd communication socket descriptor 94 | * @return int 0 = success, -1 = fail 95 | */ 96 | int initialize_secure_connection(int fd); 97 | 98 | /** 99 | * initialize SSL context 100 | * @return SSL_CTX* SSL context 101 | */ 102 | SSL_CTX* InitCTX(void); 103 | 104 | /** 105 | * prints connection certificates 106 | * @param ssl ssl connection 107 | * @return int 0 = success, -1 = fail 108 | */ 109 | int ShowCerts(SSL* ssl); 110 | 111 | /** 112 | * Loads certificate and private key 113 | * @param *ctx ssl context 114 | * @param *CertFile string containing name of certificate file 115 | * @param *KeyFile string containing name of private key file 116 | * @return int 0 = success, -1 = fail 117 | */ 118 | int LoadCertificates(SSL_CTX* ctx, char* CertFile, char* KeyFile); 119 | 120 | 121 | #ifdef __cplusplus 122 | } 123 | #endif 124 | 125 | #endif /* _NETWORK_SECURITY_H */ 126 | 127 | -------------------------------------------------------------------------------- /src/common/network_util.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "network_util.h" 22 | 23 | char* sock_recv(int sock_fd) 24 | { 25 | char* reply = (char*)ssds_malloc(MAX_INPUT_LEN*sizeof(char)); 26 | memset(reply, 0, MAX_INPUT_LEN); 27 | ssize_t ret = ssds_read(sock_fd, reply , MAX_INPUT_LEN); 28 | 29 | if(ret == -1) 30 | { 31 | ssds_log(logERROR, "Unable to read data from socket\n"); 32 | ssds_free(reply); 33 | return NULL; 34 | } 35 | 36 | if(ret == MAX_INPUT_LEN) 37 | { 38 | char* buffer = (char*)ssds_malloc(BUFF_SIZE*sizeof(char)); 39 | memset(buffer, 0, BUFF_SIZE); 40 | 41 | int read_count = 0; 42 | int buff_size = 1; 43 | memcpy(buffer, reply, MAX_INPUT_LEN); 44 | 45 | do 46 | { 47 | read_count++; 48 | memset(reply, 0, MAX_INPUT_LEN); 49 | 50 | if(read_count*MAX_INPUT_LEN >= buff_size*BUFF_SIZE) 51 | buffer = ssds_realloc(buffer, ++buff_size*BUFF_SIZE); 52 | 53 | ret = ssds_read(sock_fd, reply , MAX_INPUT_LEN); 54 | memcpy(buffer+read_count*MAX_INPUT_LEN, reply, MAX_INPUT_LEN); 55 | 56 | 57 | }while(!(ret < MAX_INPUT_LEN)); 58 | 59 | ssds_free(reply); 60 | return buffer; 61 | } 62 | //no buffer is needed for very short messages 63 | return reply; 64 | } 65 | 66 | ssize_t sock_solv_recv(int sock_fd, char **buffer) 67 | { 68 | *buffer = (char*)ssds_malloc(MAX_INPUT_LEN*sizeof(char)); 69 | memset(*buffer, 0, MAX_INPUT_LEN); 70 | ssize_t retVal = ssds_read(sock_fd, *buffer , MAX_INPUT_LEN); 71 | 72 | if(retVal == -1) 73 | { 74 | ssds_log(logERROR, "Unable to read data from socket\n"); 75 | ssds_free(*buffer); 76 | return retVal; 77 | } 78 | 79 | if(retVal == MAX_INPUT_LEN) 80 | { 81 | char* buff = (char*)ssds_malloc(BUFF_SIZE*sizeof(char)); 82 | memset(buff, 0, BUFF_SIZE); 83 | 84 | int read_count = 0; 85 | int buff_size = 1; 86 | ssize_t ret; 87 | memcpy(buff, *buffer, MAX_INPUT_LEN); 88 | 89 | do 90 | { 91 | read_count++; 92 | memset(*buffer, 0, MAX_INPUT_LEN); 93 | 94 | if(read_count*MAX_INPUT_LEN >= buff_size*BUFF_SIZE) 95 | buff = ssds_realloc(buff, ++buff_size*BUFF_SIZE); 96 | 97 | ret = ssds_read(sock_fd, *buffer , MAX_INPUT_LEN); 98 | retVal += ret; 99 | memcpy(buff+read_count*MAX_INPUT_LEN, *buffer, MAX_INPUT_LEN); 100 | 101 | }while(!(ret < MAX_INPUT_LEN)); 102 | 103 | ssds_free(*buffer); 104 | *buffer = buff; 105 | } 106 | //no buffer is needed for very short messages 107 | return retVal; 108 | } 109 | 110 | 111 | void secure_write(int socket, char* message, ssize_t length) 112 | { 113 | 114 | ssds_write(socket, message, length); 115 | } 116 | 117 | int client_connect(int *socket, char *server_address, long int port) 118 | { 119 | 120 | int connection_try = 1; 121 | 122 | *socket = ssds_socket(AF_INET, SOCK_STREAM, 0);//AF_INET = IPv4, SOCK_STREAM = TCP, 0 = IP 123 | ssds_log(logDEBUG, "Set up socket descriptor.\n"); 124 | 125 | ssds_log(logDEBUG, "Setting up connection to server.\n"); 126 | struct sockaddr_in server_comm; 127 | 128 | server_comm.sin_addr.s_addr = inet_addr(server_address); 129 | ssds_log(logDEBUG, "Set server address.\n"); 130 | 131 | server_comm.sin_family = AF_INET; 132 | ssds_log(logDEBUG, "Set comunication protocol.\n"); 133 | 134 | server_comm.sin_port = htons(port); 135 | ssds_log(logDEBUG, "Set server port.\n"); 136 | 137 | ssds_log(logDEBUG, "Socket control.\n"); 138 | if(*socket == -1) 139 | { 140 | ssds_log(logERROR, "Client encountered an error when creating socket for communication.\n"); 141 | return SOCKET_ERROR; 142 | } 143 | 144 | ssds_log(logDEBUG, "Socket control - OK.\n"); 145 | 146 | ssds_log(logMESSAGE, "Trying to connect to server...(1 of 3)\n"); 147 | while((connect(*socket, (struct sockaddr *)&server_comm, sizeof(server_comm)) < 0) && (connection_try < 3)) 148 | { 149 | ssds_log(logMESSAGE, "Unable to connect to comm. socket on server. Another attempt will be executed in 5 seconds.\n"); 150 | sleep(5); 151 | ssds_log(logMESSAGE, "Trying to connect to server...(%d of 3)\n", ++connection_try); 152 | } 153 | 154 | if(connection_try == 3){ 155 | ssds_log(logERROR, "Unable to connect comm. socket on server. Please, check out your network connection and try it again later.\n"); 156 | return NETWORKING_ERROR; 157 | } 158 | 159 | ssds_log(logMESSAGE, "Connection to server is established.\n"); 160 | 161 | return OK; 162 | } 163 | -------------------------------------------------------------------------------- /src/common/network_util.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _NETWORK_UTIL_H 22 | #define _NETWORK_UTIL_H 23 | 24 | #include "log_handler.h" 25 | #include "mem_management.h" 26 | #include "includes.h" 27 | #include "cfg_parsing.h" 28 | #include "errors.h" 29 | 30 | #include "network_security.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C"{ 34 | #endif 35 | 36 | /** Max length of one read call */ 37 | #define MAX_INPUT_LEN 2000 38 | 39 | /** 40 | * Initial length of buffer - buffer is resized 41 | * when additional data is recieved 42 | */ 43 | #define BUFF_SIZE 2000 44 | 45 | /** 46 | * Function to recieve data of previously unknown length from socket. 47 | * There is a buffer that resizes according to the size of recieved data. 48 | * @param sock_fd File descriptor for socket that is recieving data 49 | * @return buffer with recieved data - needs to be freed in the end 50 | */ 51 | char* sock_recv(int sock_fd); 52 | 53 | /** 54 | * Function to recieve data of previously unknown length from socket. 55 | * There is a buffer that resizes according to the size of recieved data. 56 | * @param sock_fd File descriptor for socket that is recieving data 57 | * @param buffer buffer with recieved data - needs to be freed in the end 58 | * @return count of readed bytes 59 | */ 60 | ssize_t sock_solv_recv(int sock_fd, char **buffer); 61 | 62 | /** 63 | * Function for secure transfer data to client/server . 64 | * @param socket communication socket 65 | * @param *message transfered message 66 | * @param length length of message 67 | */ 68 | void secure_write(int socket, char* message, ssize_t length); 69 | 70 | /** 71 | * Function to connect client to server. 72 | * @param *socket communication socket 73 | * @param *server_address IP of server 74 | * @param comm_port communication port 75 | * @return int OK or error code 76 | */ 77 | int client_connect(int *socket, char *server_address, long int comm_port); 78 | 79 | #ifdef __cplusplus 80 | } 81 | #endif 82 | 83 | #endif /* _NETWORK_UTIL_H */ 84 | -------------------------------------------------------------------------------- /src/common/packages.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving 2 | * transfer of dependency solving from local machine to server when installing new packages 3 | * 4 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel, Šimon Matěj 5 | * 6 | * Licensed under the GNU Lesser General Public License Version 2.1 7 | * 8 | * This library is free software; you can redistribute it and/or 9 | * modify it under the terms of the GNU Lesser General Public 10 | * License as published by the Free Software Foundation; either 11 | * version 2.1 of the License, or (at your option) any later version. 12 | * 13 | * This library 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 | * Lesser General Public License for more details. 17 | * 18 | * You should have received a copy of the GNU Lesser General Public 19 | * License along with this library; if not, write to the Free Software 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 | */ 22 | 23 | #include "packages.h" 24 | 25 | int ssds_add_to_transaction(rpmts ts, char *pkg, int action) 26 | { 27 | 28 | FD_t fd; 29 | Header hdr; 30 | int rc = 0; 31 | 32 | /* Read package header */ 33 | fd = Fopen(pkg, "r.ufdio"); 34 | if (fd == NULL) { 35 | ssds_log(logERROR, "Unable to open file %s.\n", pkg); 36 | return 1; 37 | } 38 | ssds_log(logDEBUG, "File %s is opened.\n", pkg); 39 | 40 | rc = rpmReadPackageFile(ts, fd, pkg, &hdr); 41 | 42 | if (rc != RPMRC_OK) { 43 | ssds_log(logERROR,"Unable to read package %s.\n", pkg); 44 | return rc; 45 | } 46 | 47 | ssds_log(logDEBUG, "Package is ok.\n"); 48 | 49 | /* Add it to the transaction set */ 50 | rc = rpmtsAddInstallElement(ts, hdr, (fnpyKey) pkg, action, 0); 51 | 52 | if (rc) { 53 | ssds_log(logERROR ,"Error adding %s to transaction.\n", pkg); 54 | } 55 | 56 | ssds_log(logDEBUG, "Package added to transaction with code %d.\n", rc); 57 | 58 | headerFree(hdr); 59 | Fclose(fd); 60 | return rc; 61 | } 62 | 63 | int ssds_add_to_erase(rpmts ts, char *pkg){ 64 | 65 | Header hdr; 66 | rpmdbMatchIterator mi; 67 | int rc = OK; 68 | 69 | /* Locate the package and add for erasure */ 70 | mi = rpmtsInitIterator(ts, (rpmTag)RPMDBI_LABEL, pkg, 0); 71 | while ((hdr = rpmdbNextIterator(mi)) != NULL) { 72 | int recOffset = rpmdbGetIteratorOffset(mi); 73 | if (recOffset) { 74 | rc = rpmtsAddEraseElement(ts, hdr, recOffset); 75 | if (rc) 76 | ssds_log(logERROR, "Error adding %s to transaction.\n", pkg); 77 | 78 | } 79 | } 80 | mi = rpmdbFreeIterator(mi); 81 | return rc; 82 | } 83 | -------------------------------------------------------------------------------- /src/common/packages.h: -------------------------------------------------------------------------------- 1 | /** 2 | * Server side dependency solving 3 | * transfer of dependency solving from local machine to server when installing new packages 4 | * 5 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel, Šimon Matěj 6 | * 7 | * Licensed under the GNU Lesser General Public License Version 2.1 8 | * 9 | * This library is free software; you can redistribute it and/or 10 | * modify it under the terms of the GNU Lesser General Public 11 | * License as published by the Free Software Foundation; either 12 | * version 2.1 of the License, or (at your option) any later version. 13 | * 14 | * This library is distributed in the hope that it will be useful, 15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 | * Lesser General Public License for more details. 18 | * 19 | * You should have received a copy of the GNU Lesser General Public 20 | * License along with this library; if not, write to the Free Software 21 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 | */ 23 | 24 | #ifndef _PACKAGES_H 25 | #define _PACKAGES_H 26 | 27 | #ifdef __cplusplus 28 | extern "C"{ 29 | #endif 30 | 31 | #include "includes.h" 32 | #include "log_handler.h" 33 | #include "errors.h" 34 | 35 | #include 36 | #include 37 | #include 38 | #include 39 | 40 | // Paths to download folders 41 | static const char *DOWNLOAD_TARGET = "/var/cache/ssds/packages/"; 42 | 43 | // Types of supported operation 44 | enum{ 45 | SSDS_INSTALL = 0, 46 | SSDS_UPDATE 47 | }; 48 | 49 | /** 50 | * Add package to RPM transaction with requested operation. 51 | * @param ts rpmts RPM transaction 52 | * @param pkg char* path to package 53 | * @param action int type of operation 54 | * @return RPM transaction set return value 55 | */ 56 | int ssds_add_to_transaction (rpmts ts, char *pkg, int action); 57 | 58 | /** 59 | * Add package to RPM transaction for erase. 60 | * @param ts rpmts RPM transaction 61 | * @param pkg char* name of package to erase 62 | * @return RPM transaction set return value 63 | */ 64 | int ssds_add_to_erase (rpmts ts, char *pkg); 65 | 66 | #ifdef __cplusplus 67 | } 68 | #endif 69 | 70 | #endif 71 | 72 | -------------------------------------------------------------------------------- /src/common/params.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "params.h" 22 | 23 | int parse_params_cl(int argc, char* argv[], ParamOptsCl* params) 24 | { 25 | if(argc==1) 26 | { 27 | ssds_log(logERROR, "No command provided. The program will terminate now.\n"); 28 | return 2; 29 | } 30 | 31 | static int param_opt; //needs to be static or else make fails 32 | static struct option long_options[] = 33 | { 34 | {"install", no_argument, ¶m_opt, PAR_INSTALL}, 35 | {"chkdep", no_argument, ¶m_opt, PAR_CHK_DEP}, 36 | {"update", no_argument, ¶m_opt, PAR_UPDATE}, 37 | {"erase", no_argument, ¶m_opt, PAR_ERASE}, 38 | {"help", no_argument, 0, 'h'} 39 | }; 40 | 41 | int c; 42 | int opt_index = 0; 43 | int seen = 0; 44 | extern int optind; 45 | opterr = 0; 46 | 47 | while(1) 48 | { 49 | c = getopt_long(argc, argv, "vhd", long_options, &opt_index); 50 | switch(c) 51 | { 52 | case 0: 53 | params->command = long_options[opt_index].val; 54 | seen++; 55 | break; 56 | 57 | case 'h': 58 | print_help_cl(); 59 | exit(EXIT_SUCCESS); 60 | break; 61 | 62 | case 'v': 63 | set_verbose(); 64 | break; 65 | 66 | case 'd': 67 | set_debug(); 68 | break; 69 | 70 | case '?': 71 | print_help_cl(); 72 | return -1; 73 | break; 74 | } 75 | 76 | if(c == -1) 77 | break; 78 | } 79 | 80 | if(seen > 1) 81 | { 82 | ssds_log(logMESSAGE, "Choose either install, update, erase or chkdep. The program will terminate now.\n"); 83 | ssds_log(logERROR, "Wrong parameter combination. Terminating.\n"); 84 | return -1; 85 | } 86 | 87 | if(seen == 0) 88 | { 89 | ssds_log(logERROR, "No command provided. The program will terminate now.\n"); 90 | return 3; 91 | } 92 | 93 | if(optind < argc) 94 | { 95 | while(optind < argc) 96 | { 97 | params->pkgs = g_slist_append(params->pkgs, argv[optind++]); 98 | params->pkg_count++; 99 | } 100 | } 101 | return 0; 102 | } 103 | 104 | ParamOptsCl* init_params_cl() 105 | { 106 | ParamOptsCl* new = (ParamOptsCl*)ssds_malloc(sizeof(ParamOptsCl)); 107 | new->pkg_count = 0; 108 | new->command = -1; 109 | new->pkgs = NULL; 110 | return new; 111 | } 112 | 113 | 114 | void free_params_cl(ParamOptsCl* params) 115 | { 116 | g_slist_free_full(params->pkgs, (GDestroyNotify) free); //only *char in the list so free will suffice 117 | ssds_free(params); 118 | } 119 | 120 | 121 | void parse_params_srv(int argc, char* argv[]) 122 | { 123 | int opt; 124 | while ((opt = getopt(argc, argv, "vhd")) != -1) { 125 | switch (opt) { 126 | case 'v': 127 | set_verbose(); 128 | break; 129 | case 'h': 130 | print_help_srv(); 131 | exit(EXIT_SUCCESS); 132 | break; 133 | case 'd': 134 | set_debug(); 135 | break; 136 | default: /* '?' */ 137 | print_help_srv(); 138 | exit(PARAMS_ERROR); 139 | } 140 | } 141 | } 142 | 143 | 144 | void print_help_cl() 145 | { 146 | printf("Usage: ./rds-client [ ...]\n\n" 147 | "List of Commands\n\n" 148 | "--install\t\tResolve dependencies and install packages\n" 149 | "--update\t\tResolve dependencies and update packages\n" 150 | "--erase\t\t\tErase packages\n" 151 | "--chkdep\t\tOnly show required packages - do not install yet\n" 152 | "--help, -h\t\tDisplays help\n" 153 | "-v\t\t\tVerbose - turned off by default\n" 154 | "-d\t\t\tDebug - turned off by default\n" 155 | ); 156 | } 157 | 158 | void print_help_srv() 159 | { 160 | printf("Usage: ./rds-server \n\n" 161 | "List of Commands\n\n" 162 | "-h\tDisplays help\n" 163 | "-v\tVerbose - turned off by default\n" 164 | "-d\tDebug - turned off by default\n" 165 | ); 166 | } 167 | -------------------------------------------------------------------------------- /src/common/params.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _PARAMS_H 22 | #define _PARAMS_H 23 | 24 | #include "includes.h" 25 | #include "log_handler.h" 26 | #include "mem_management.h" 27 | #include "errors.h" 28 | 29 | #ifdef __cplusplus 30 | extern "C"{ 31 | #endif 32 | 33 | /** 34 | * Integer option for command in ParamOptsCl 35 | */ 36 | enum ParamsOptions{ 37 | PAR_NO_OPT = 0, /**< 0 No option was provided */ 38 | PAR_INSTALL, /**< 1 Install option chosen */ 39 | PAR_CHK_DEP, /**< 2 Only check if dependencies are fulfilled */ 40 | PAR_UPDATE, /**< 3 Update option choosen */ 41 | PAR_ERASE, /**< 4 Erase option choosen */ 42 | PAR_UPDATE_ALL /**< 5 Update all packages */ 43 | }ParOpt; 44 | 45 | /********************************/ 46 | /* This part is used by client */ 47 | /********************************/ 48 | 49 | /** 50 | * Structure hold information parsed from parameters provided by user */ 51 | typedef struct ParamOptsCl ParamOptsCl; 52 | 53 | struct ParamOptsCl{ 54 | int command; /**< ParOpt number of command */ 55 | int pkg_count; /**< Number of packages required by user */ 56 | GSList* pkgs; /**< Names of packages from command line */ 57 | }; 58 | 59 | /** 60 | * Parses command line on client side. 61 | * @param argc int 62 | * @param argv char** 63 | * @param params ParamOptsCl* 64 | * @return EXIT_SUCCES when all parameters are in order, EXIT_FAILURE otherwise 65 | */ 66 | int parse_params_cl(int argc, char* argv[], ParamOptsCl* params); 67 | 68 | /** 69 | * Returns newly allocated ParamOptsCl 70 | * @return ParamOptsCl* 71 | */ 72 | ParamOptsCl* init_params_cl(); 73 | 74 | void free_params_cl(ParamOptsCl* params); 75 | 76 | /** 77 | * Prints help for client users 78 | */ 79 | void print_help_cl(); 80 | 81 | /********************************/ 82 | /* This part is used by server */ 83 | /********************************/ 84 | 85 | void parse_params_srv(int argc,char* argv[]); 86 | 87 | /** 88 | * Prints help for server usage 89 | */ 90 | void print_help_srv(); 91 | 92 | #ifdef __cplusplus 93 | } 94 | #endif 95 | 96 | #endif /* _PARAMS_H */ 97 | -------------------------------------------------------------------------------- /src/common/repo_handler.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "repo_handler.h" 22 | 23 | SsdsLocalRepoInfo* ssds_repo_parse_init() 24 | { //this part uses librepo library to parse .repo files - repoconf module was created by TMlcoch 25 | SsdsLocalRepoInfo* new = (SsdsLocalRepoInfo*)ssds_malloc(sizeof(SsdsLocalRepoInfo)); 26 | new->repoHandler = lr_yum_repoconfs_init(); 27 | 28 | return new; 29 | } 30 | 31 | 32 | int ssds_parse_default_repo(SsdsLocalRepoInfo* repo) 33 | { 34 | GError *err = NULL; 35 | gboolean ret = lr_yum_repoconfs_load_dir(repo->repoHandler, "/etc/yum.repos.d/", &err); 36 | if(!ret){ 37 | ssds_log(logERROR, "Unable to load default repo\n"); 38 | return 0; 39 | } 40 | return 1; 41 | } 42 | 43 | void ssds_get_repo_urls(SsdsLocalRepoInfo* repo, SsdsJsonCreate* json, char* arch, char* release) 44 | { 45 | GError* err = NULL; 46 | 47 | ssds_log(logDEBUG,"Getting repoconfs list.\n"); 48 | GSList* list = lr_yum_repoconfs_get_list(repo->repoHandler, &err); 49 | 50 | ssds_log(logDEBUG, "Loop over repoconf list.\n"); 51 | for(unsigned int i = 0; i < g_slist_length(list); i++){ 52 | char** url = (char **)ssds_malloc(1*sizeof(char*)); 53 | char* name = NULL; 54 | short type = 0; 55 | void * val; 56 | int k = 0; 57 | 58 | ssds_log(logDEBUG,"Getting repo configuration.\n"); 59 | LrYumRepoConf * conf = (LrYumRepoConf*)g_slist_nth_data(list, i); 60 | 61 | ssds_log(logDEBUG,"Getting repo info.\n"); 62 | lr_yum_repoconf_getinfo(conf, &err, LR_YRC_ENABLED, &val); 63 | 64 | if((long int)val){ 65 | err = NULL; 66 | if(lr_yum_repoconf_getinfo(conf, &err, LR_YRC_ID, &val) != 0){ 67 | ssds_log(logDEBUG,"Getting repo name.\n"); 68 | name = (char*)val; 69 | ssds_log(logDEBUG,"Name: %s.\n",name); 70 | } 71 | 72 | err = NULL; 73 | if(lr_yum_repoconf_getinfo(conf, &err, LR_YRC_MIRRORLIST, &val) != 0){ 74 | ssds_log(logDEBUG,"Getting mirrorlist url.\n"); 75 | url[0] = (char*)val; 76 | k = 1; 77 | ssds_log(logDEBUG,"URL: %s.\n", url[0]); 78 | type = SSDS_MIRRORLIST; 79 | } 80 | 81 | err = NULL; 82 | if(lr_yum_repoconf_getinfo(conf, &err, LR_YRC_METALINK, &val) != 0){ 83 | ssds_log(logDEBUG,"Getting metalink url.\n"); 84 | url[0] = (char*)val; 85 | k = 1; 86 | ssds_log(logDEBUG,"URL: %s.\n", url[0]); 87 | type = SSDS_METALINK; 88 | } 89 | 90 | err = NULL; 91 | //void ** val2; 92 | if(lr_yum_repoconf_getinfo(conf, &err, LR_YRC_BASEURL, &val) != 0){ 93 | ssds_log(logDEBUG,"Getting base urls.\n"); 94 | ssds_free(url); 95 | url = (char**)val; 96 | while(url[k]) 97 | k++; 98 | type = SSDS_BASEURL; 99 | } 100 | 101 | ssds_log(logDEBUG,"Setting url var - releaseserver.\n"); 102 | LrUrlVars *list = lr_urlvars_set(NULL, "releasever", release); //"3.18.6-200.fc21" 103 | ssds_log(logDEBUG,"Setting url var - basearch.\n"); 104 | list = lr_urlvars_set(list, "basearch", arch); 105 | 106 | ssds_log(logDEBUG,"Getting URL size.\n"); 107 | ssds_log(logDEBUG,"Size: %d.\n",k); 108 | 109 | char **url_subst_list = (char**)ssds_malloc((k+1)*sizeof(char*)); 110 | char* url_copy; 111 | char* url_subst; 112 | 113 | ssds_log(logDEBUG,"Setting urls into json.\n"); 114 | for(int j = 0; j < k; j++) 115 | { 116 | url_copy = strdup(url[j]); 117 | url_subst = lr_url_substitute(url_copy, list); 118 | url_subst_list[j] = strdup(url_subst); 119 | free(url_copy); //created by strdup - not in GC, needs to be freed manually 120 | free(url_subst); //created by strdup - not in GC, needs to be freed manually 121 | } 122 | url_subst_list[k] = NULL; 123 | 124 | ssds_js_cr_add_repo(json,url_subst_list, name, type, k); 125 | ssds_free(url); 126 | for(int j = 0; j <= k; j++) 127 | free(url_subst_list[j]); //created by strdup - not in GC, needs to be freed manually 128 | 129 | ssds_free(url_subst_list); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /src/common/repo_handler.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _REPO_HANDLER_H 22 | #define _REPO_HANDLER_H 23 | 24 | #include "includes.h" 25 | 26 | //LIBREPO 27 | #include 28 | #include 29 | 30 | //SSDS 31 | #include "json_handler.h" 32 | #include "log_handler.h" 33 | 34 | //SOLVING 35 | #include 36 | #include 37 | #include 38 | #include 39 | #include 40 | #include 41 | 42 | #include "mem_management.h" 43 | 44 | #ifdef __cplusplus 45 | extern "C"{ 46 | #endif 47 | 48 | /************************************************************/ 49 | /* Parse repo - getting information from local .repo files */ 50 | /************************************************************/ 51 | 52 | /** 53 | * Structure for information about local repositories on client machine 54 | */ 55 | typedef struct SsdsLocalRepoInfo SsdsLocalRepoInfo; 56 | 57 | struct SsdsLocalRepoInfo{ 58 | LrYumRepoConfs* repoHandler; /**< List of repo structures */ 59 | }; 60 | 61 | /** 62 | * Returns newly allocated SsdsLocalRepoInfo 63 | * @return SsdsLocalRepoInfo* 64 | */ 65 | SsdsLocalRepoInfo* ssds_repo_parse_init(); 66 | 67 | /** 68 | * Parses local .repo files. Function uses librepo class repoconf.h. 69 | * Information about repos are saved to SsdsLocalRepoInfo 70 | * @param repo SsdsLocalRepoInfo 71 | * @return int 72 | */ 73 | int ssds_parse_default_repo(SsdsLocalRepoInfo* repo); 74 | 75 | /** 76 | * Gets urls of local repos from SsdsLocalRepoInfo and inserts them 77 | * into SsdsJsonCreate structure so that they can be sent to server 78 | * @param repo SsdsLocalRepoInfo* 79 | * @param json SsdsJsonCreate* 80 | * @param arch char* 81 | * @param release char* 82 | */ 83 | void ssds_get_repo_urls(SsdsLocalRepoInfo* repo, SsdsJsonCreate* json, char* arch, char* release); 84 | 85 | /*****************************************************************/ 86 | /* Repo metadata - information about metadata location on server */ 87 | /*****************************************************************/ 88 | 89 | /** 90 | * GSList of SsdsMetadataFilesLoc 91 | */ 92 | typedef struct SsdsRepoMetadataList SsdsRepoMetadataList; 93 | 94 | /** 95 | * Structure is used by server to hold information about downloaded metadata 96 | */ 97 | typedef struct SsdsMetadataFilesLoc SsdsMetadataFilesLoc; 98 | 99 | struct SsdsRepoMetadataList{ 100 | GSList *files_locations; /**< GSList of SsdsMetadataFilesLoc */ 101 | }; 102 | 103 | struct SsdsMetadataFilesLoc{ 104 | char* repomd; /**< path to repomod.xml file */ 105 | char* filelists; /**< path to filelists.xml */ 106 | char* primary; /**< path to primary.xml */ 107 | char* repo_name; /**< name of repo for later use */ 108 | }; 109 | 110 | /** 111 | * Returns newly allocated SsdsRepoMetadataList 112 | * @return SsdsRepoMetadataList* 113 | */ 114 | SsdsRepoMetadataList* ssds_repo_metadata_init();// 115 | 116 | /** 117 | * Function tries to locate metadata about repos provided by json. 118 | * If such metadata are not found on server, they are downloaded. 119 | * Find local copy by using local_repo_metadata and download them by 120 | * using download_repo_metadata_by_url. 121 | * @param json SsdsJsonRead* 122 | * @param info_list SsdsRepoInfoList* 123 | * @param meta_list SsdsRepoMetadataList* 124 | * @return 125 | */ 126 | int ssds_locate_repo_metadata(/*SsdsJsonRead* json, */SsdsRepoInfoList* info_list, SsdsRepoMetadataList* meta_list);// 127 | 128 | /** 129 | * Function tries to locate metadata for one repo provided in repo. 130 | * This works only for one repo - needs to be called in loop to find all. 131 | * @param repo SsdsRepoInfo* 132 | * @param list SsdsRepoMetadataList* 133 | * @return 1 if metadata were found locally, otherwise returns 0 134 | */ 135 | int local_repo_metadata(SsdsRepoInfo* repo, SsdsRepoMetadataList* list);// 136 | 137 | /** 138 | * Function appends name of repo to full path to dir containing metadata on server 139 | * @param repo_name char* 140 | * @return full path to repo as char* 141 | */ 142 | char* full_path_to_metadata(char* repo_name);// 143 | 144 | /** 145 | * Callback function for downloading metadata 146 | * @param data void* 147 | * @param total double 148 | * @param now double 149 | * @return 0 150 | */ 151 | int metadata_progress(G_GNUC_UNUSED void *data, double total, double now); 152 | 153 | /** 154 | * Function tries to download metadata for repo by using full url of repository 155 | * @param repo SsdsRepoInfo* 156 | * @param list SsdsRepoMetadataList* 157 | */ 158 | void download_repo_metadata_by_url(SsdsRepoInfo* repo, SsdsRepoMetadataList* list); 159 | 160 | /** 161 | * Redeclaration of function strdup 162 | * @param s const char* 163 | * @return char * 164 | */ 165 | char *strdup(const char *s); 166 | #ifdef __cplusplus 167 | } 168 | #endif 169 | 170 | #endif /* _REPO_HANDLER_H */ 171 | -------------------------------------------------------------------------------- /src/common/repo_metadata.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "repo_handler.h" 22 | 23 | 24 | SsdsRepoMetadataList* ssds_repo_metadata_init() 25 | { 26 | SsdsRepoMetadataList* new = (SsdsRepoMetadataList*)ssds_malloc(sizeof(SsdsRepoMetadataList)); 27 | new->files_locations = NULL; 28 | return new; 29 | } 30 | 31 | 32 | int ssds_locate_repo_metadata(/*SsdsJsonRead* json, */SsdsRepoInfoList* info_list, SsdsRepoMetadataList* meta_list) 33 | { 34 | guint len = g_slist_length(info_list->repoInfoList); 35 | for(guint i = 0; i < len; i++){ 36 | // ssds_log(logDEBUG, "ssds_locate_repo_metadata inside for before getting repo from list\n"); 37 | SsdsRepoInfo* repo = (SsdsRepoInfo*)g_slist_nth_data(info_list->repoInfoList, i); 38 | 39 | if(!local_repo_metadata(repo, meta_list)) 40 | { 41 | // ssds_log(logDEBUG, "ssds_locate_repo_metadata inside if\n"); 42 | download_repo_metadata_by_url(repo, meta_list); 43 | ssds_log(logDEBUG, "ssds_locate_repo_metadata inside if after download\n"); 44 | } 45 | 46 | } 47 | 48 | //TODO - update return value 49 | return 1; 50 | } 51 | 52 | 53 | int local_repo_metadata(SsdsRepoInfo* repos, SsdsRepoMetadataList* list) 54 | { 55 | char* local_path=full_path_to_metadata(repos->name); 56 | GError *tmp_err = NULL; 57 | LrHandle *h = lr_handle_init(); 58 | LrResult *r = lr_result_init(); 59 | 60 | ssds_log(logDEBUG, "%s\n", local_path); 61 | 62 | char** handle_urls = (char**)ssds_malloc(2*sizeof(char*)); 63 | handle_urls[0] = local_path; 64 | handle_urls[1] = NULL; 65 | lr_handle_setopt(h, NULL, LRO_URLS, handle_urls);//look for repo locally 66 | lr_handle_setopt(h, NULL, LRO_LOCAL, (long)1); 67 | lr_handle_setopt(h, NULL, LRO_REPOTYPE, LR_YUMREPO); 68 | 69 | gboolean ret = lr_handle_perform(h, r, &tmp_err); 70 | 71 | if(ret) 72 | { 73 | // ssds_log(logINFO,"Local metadata for %s found at %s. Using local copy.\n", repo->name, local_path); 74 | LrYumRepo* local_repo = lr_yum_repo_init(); 75 | lr_result_getinfo(r, &tmp_err, LRR_YUM_REPO, &local_repo); 76 | 77 | SsdsMetadataFilesLoc* loc = (SsdsMetadataFilesLoc*)ssds_malloc(sizeof(SsdsMetadataFilesLoc)); 78 | loc->repomd = local_path; 79 | loc->filelists = strdup(lr_yum_repo_path(local_repo,"filelists")); 80 | loc->primary = strdup(lr_yum_repo_path(local_repo,"primary")); 81 | loc->repo_name = strdup(repos->urls[0]); 82 | 83 | list->files_locations = g_slist_append(list->files_locations, loc); 84 | lr_yum_repo_free(local_repo); 85 | return 1; 86 | } 87 | 88 | // ssds_log(logINFO, "Local metadata for %s repo were not found at %s. Metadata will be downloaded.\n", repo->name, local_path); 89 | return 0; 90 | } 91 | 92 | 93 | char* full_path_to_metadata(char* repo_name) 94 | { 95 | const char* dest = "/tmp/ssds/"; 96 | int length = strlen(dest) + strlen(repo_name); 97 | char* full_path = (char*)ssds_malloc((length+1)*sizeof(char)); 98 | 99 | strncpy(full_path, dest, strlen(dest)+1); 100 | strncat(full_path, repo_name, strlen(repo_name)); 101 | 102 | mkdir(dest, 0777); 103 | mkdir(full_path, 0777); 104 | 105 | return full_path; 106 | } 107 | 108 | int metadata_progress(G_GNUC_UNUSED void *data, double total, double now){ 109 | if(total > 0){ 110 | printf("\rDownloading repo: %s\t - %.0f%%", (char *) data, (now/total)*100); 111 | fflush(stdout); 112 | } 113 | return 0; 114 | } 115 | 116 | void download_repo_metadata_by_url(SsdsRepoInfo* repo, SsdsRepoMetadataList* list) 117 | { 118 | LrHandleOption type; 119 | GError *tmp_err = NULL; 120 | 121 | // Download only this metadata 122 | //char *download_list[] = { "primary", "filelists", NULL}; 123 | LrHandle *h = lr_handle_init(); 124 | LrResult *r = lr_result_init(); 125 | repo->urls[repo->count] = NULL; 126 | 127 | //find type of url in vector 128 | switch(repo->type) 129 | { 130 | case 1: 131 | type = LRO_URLS; 132 | lr_handle_setopt(h, NULL, type, repo->urls); 133 | break; 134 | case 2: 135 | type = LRO_MIRRORLISTURL; 136 | lr_handle_setopt(h, NULL, type, repo->urls[0]); 137 | break; 138 | case 3: 139 | type = LRO_METALINKURL; 140 | lr_handle_setopt(h, NULL, type, repo->urls[0]); 141 | break; 142 | } 143 | 144 | char* full_path = full_path_to_metadata(repo->name); 145 | 146 | //lr_handle_setopt(h, NULL, LRO_YUMDLIST, download_list); 147 | lr_handle_setopt(h, NULL, LRO_REPOTYPE, LR_YUMREPO); 148 | lr_handle_setopt(h, NULL, LRO_CONNECTTIMEOUT, (long)10); 149 | lr_handle_setopt(h, NULL, LRO_DESTDIR, full_path); 150 | lr_handle_setopt(h, NULL, LRO_PROGRESSCB, metadata_progress); 151 | lr_handle_setopt(h, NULL, LRO_PROGRESSDATA, repo->name); 152 | // printf("Performing handle on repo name: %s, repo type: %d\n", repo->name, repo->type); 153 | gboolean ret = lr_handle_perform(h, r, &tmp_err); 154 | printf("\n"); 155 | char *destdir; 156 | lr_handle_getinfo(h, NULL, LRI_DESTDIR, &destdir); 157 | 158 | 159 | if (ret) { 160 | ssds_log(logMESSAGE, "Metadata for %s - download successfull (Destination dir: %s).\n", repo->name, destdir); 161 | 162 | LrYumRepo* lrRepo = lr_yum_repo_init(); 163 | lr_result_getinfo(r, &tmp_err, LRR_YUM_REPO, &lrRepo); 164 | //std::cout << lr_yum_repo_path(repo, "filelists") << std::endl; 165 | 166 | // ssds_log(logDEBUG, "Lr_result contains all the info now\n"); 167 | 168 | SsdsMetadataFilesLoc* loc = (SsdsMetadataFilesLoc*)ssds_malloc(sizeof(SsdsMetadataFilesLoc)); 169 | 170 | loc->repomd = destdir; 171 | 172 | loc->filelists = strdup(lr_yum_repo_path(lrRepo,"filelists")); 173 | loc->primary = strdup(lr_yum_repo_path(lrRepo,"primary")); 174 | loc->repo_name = strdup(repo->urls[0]); 175 | // 176 | // printf("download_repo_metadata_by_url:\nrepomd: %s\nfilelists: %s\nprimary: %s\n", loc->repomd, loc->filelists, loc->primary); 177 | 178 | // ssds_log(logDEBUG, "Locations of downloaded files are ready\n"); 179 | 180 | list->files_locations = g_slist_append(list->files_locations, loc); 181 | // ssds_log(logDEBUG, "Locations of files are in the list\n"); 182 | lr_yum_repo_free(lrRepo); 183 | // ssds_log(logDEBUG, "download_repo_metadata_by_url after repo free\n"); 184 | } else { 185 | fprintf(stderr, "Error encountered: %s.\n", tmp_err->message); 186 | g_error_free(tmp_err); 187 | } 188 | 189 | // ssds_log(logDEBUG, "download_repo_metadata_by_url beffore free\n"); 190 | // lr_result_free(r); 191 | // lr_handle_free(h); 192 | // ssds_log(logDEBUG, "download_repo_metadata_by_url after free\n"); 193 | } 194 | -------------------------------------------------------------------------------- /src/common/solving.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "solving.h" 22 | 23 | // HySack* ssds_solve_init() 24 | // { 25 | // HySack sack = hy_sack_create(NULL, NULL, NULL,HY_MAKE_CACHE_DIR); 26 | // 27 | // if(hy_sack_load_system_repo(sack, NULL, HY_BUILD_CACHE)) 28 | // return NULL; 29 | // 30 | // HySack* ret; 31 | // ret = &sack; 32 | // return ret; 33 | // } 34 | 35 | void ssds_fill_sack(HySack* sack, SsdsRepoMetadataList* list)//TODO - sem dostat spravny sack asi pomoci pool_set_installed 36 | { 37 | // for(ssds_repo::metadata_files_location* loc : metadata.files_locations) 38 | guint i; 39 | for(i = 0; i < g_slist_length(list->files_locations); i++) 40 | { 41 | SsdsMetadataFilesLoc* file = (SsdsMetadataFilesLoc*)g_slist_nth_data(list->files_locations, i); 42 | HyRepo repo = hy_repo_create(file->repo_name); 43 | // ssds_log(logDEBUG, "repomd: %s\n filelists: %s\nprimary: %s\n", file->repomd, file->filelists, file->primary); 44 | 45 | int path_len = strlen(file->repomd)+strlen("/repodata/repomd.xml"); 46 | char* repomd_path = (char*)ssds_malloc((path_len+1)*sizeof(char)); 47 | memset(repomd_path, '\0', path_len+1); 48 | strcpy(repomd_path, file->repomd); 49 | strcat(repomd_path, "/repodata/repomd.xml"); 50 | 51 | hy_repo_set_string(repo, HY_REPO_MD_FN, repomd_path); 52 | hy_repo_set_string(repo, HY_REPO_PRIMARY_FN, file->primary); 53 | hy_repo_set_string(repo, HY_REPO_FILELISTS_FN, file->filelists); 54 | hy_repo_set_string(repo, HY_REPO_NAME, file->repo_name); 55 | 56 | hy_sack_load_yum_repo(*sack, repo, 0); 57 | ssds_log(logDEBUG, "%s repo loaded to sack.\n", file->repo_name); 58 | } 59 | } 60 | 61 | int ssds_dep_query(const char** request, SsdsJsonCreate* answer, HySack* sack, int operation, int pkg_count) 62 | { 63 | HyGoal goal = hy_goal_create(*sack); 64 | 65 | if(operation == GET_UPDATE_ALL) 66 | { 67 | hy_goal_upgrade_all(goal); 68 | hy_goal_run(goal); 69 | } 70 | else 71 | { 72 | HyPackageList plist = hy_packagelist_create(); 73 | HyPackage pkg; 74 | HyQuery query = hy_query_create(*sack); 75 | 76 | 77 | 78 | //try exact match 79 | if(pkg_count >1) 80 | hy_query_filter_in(query, HY_PKG_NAME, HY_EQ, request); 81 | else 82 | hy_query_filter(query, HY_PKG_NAME, HY_EQ, request[0]); 83 | 84 | 85 | plist = hy_query_run(query); 86 | if(hy_packagelist_count(plist)==0) 87 | {//exact match didn't work - I need to try 88 | hy_query_free(query); 89 | query = hy_query_create(*sack); 90 | 91 | if(pkg_count >1) 92 | hy_query_filter_in(query, HY_PKG_NAME, HY_GLOB, request); 93 | else 94 | hy_query_filter(query, HY_PKG_NAME, HY_GLOB, request[0]); 95 | } 96 | hy_query_filter_latest_per_arch(query, 1); 97 | plist = hy_query_run(query); 98 | 99 | for(int i = 0; i < hy_packagelist_count(plist); i++) 100 | { 101 | pkg = hy_packagelist_get(plist, i); 102 | // printf("pkg v query: %s\n", hy_package_get_name(pkg)); 103 | switch(operation) 104 | { 105 | case GET_INSTALL: 106 | hy_goal_install(goal, pkg); 107 | break; 108 | case GET_UPDATE: 109 | hy_goal_upgrade_to(goal, pkg); 110 | break; 111 | case GET_ERASE: 112 | hy_goal_erase(goal, pkg); 113 | break; 114 | } 115 | if(hy_goal_run(goal) == 0) 116 | ssds_log(logMESSAGE, "Dependencies for %s are ok.\n", hy_package_get_name(pkg)); 117 | else 118 | { 119 | ssds_log(logMESSAGE, "Dependencies for %s are not ok. Package cannot be installed.\n", hy_package_get_name(pkg)); 120 | return -1; 121 | } 122 | } 123 | } 124 | /*printf*/("pred insert\n"); 125 | ssds_js_cr_pkgs_insert(answer, &goal); 126 | } 127 | 128 | 129 | void adjust_glob(char** pkgs, int pkg_count) 130 | { 131 | if(pkgs==NULL) 132 | return; 133 | 134 | for(int i=0; ilength; i++) 153 | // { 154 | // ssds_log(logDEBUG,"Answer in for loop.\n"); 155 | // ssds_dep_query(pkgs->packages[i], answer, sack); 156 | // // query(pkgs->packages[i], answer); 157 | // } 158 | // } 159 | -------------------------------------------------------------------------------- /src/common/solving.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _SOLVING_H 22 | #define _SOLVING_H 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | //SSDS 29 | #include "repo_handler.h" 30 | #include "json_handler.h" 31 | #include "log_handler.h" 32 | #include "mem_management.h" 33 | 34 | //GLIB 35 | #include "includes.h" 36 | 37 | //SOLVING 38 | #include 39 | #include 40 | #include 41 | #include 42 | #include 43 | #include 44 | #include 45 | 46 | //LIBREPO 47 | #include 48 | #include 49 | 50 | 51 | // HySack* ssds_solve_init(); 52 | 53 | /** 54 | * Fills sack object with information from all repositories provided by client 55 | * @param sack HySack* 56 | * @param list SsdsRepoMetadataList* 57 | */ 58 | void ssds_fill_sack(HySack* sack, SsdsRepoMetadataList* list); 59 | 60 | /** 61 | * Function connects input with output and dependency solving. 62 | * Takes information from client and passes them for dependency solving to 63 | * ssds_dep_query. Ssds_dep_query adds each result to SsdsJsonCreate. 64 | * @param client_data SsdsJsonRead* 65 | * @param answer SsdsJsonCreate* 66 | * @param sack HySack* 67 | */ 68 | //void ssds_dep_answer(SsdsJsonRead *client_data, SsdsJsonCreate* answer, HySack* sack); 69 | 70 | /** 71 | * Solves dependency for one package. Needs to be called in loop for all packages. 72 | * Used by ssds_dep_answer. 73 | * @param request const char* 74 | * @param answer SsdsJsonCreate* 75 | * @param sack HySack* 76 | */ 77 | int ssds_dep_query(const char** request, SsdsJsonCreate* answer, HySack* sack, int operation, int pkg_count); 78 | 79 | 80 | /** 81 | * Puts * into every string in array of package names (["vim", "emacs", NULL] becomes ["vim*", "emacs*", NULL]) 82 | * @param pkgs** char** 83 | * @param pkg_count int 84 | */ 85 | void adjust_glob(char** pkgs, int pkg_count); 86 | 87 | #ifdef __cplusplus 88 | } 89 | #endif 90 | 91 | #endif /* _SOLVING_H */ 92 | -------------------------------------------------------------------------------- /src/common/ssds.dtd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/common/util.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "util.h" 22 | 23 | void ssds_resolve_dependency_file_path(char * ret_val, char** arch, char** release) 24 | { 25 | *release = NULL; 26 | struct utsname *machine = (struct utsname *)ssds_malloc(sizeof(struct utsname)); 27 | 28 | ssds_log(logDEBUG, "Getted info about machine.\n"); 29 | 30 | if(machine == NULL){ 31 | ssds_log(logERROR, "Not enough memory on heap.\n"); 32 | return; 33 | } 34 | 35 | ssds_log(logDEBUG, "Getting info about release and arch.\n"); 36 | 37 | if(uname(machine) < 0){ 38 | ssds_log(logERROR, "Unable to found system type and computer architecture.\n"); 39 | ssds_free(machine); 40 | return; 41 | } 42 | 43 | ssds_log(logDEBUG, "Getting last dot in release string.\n"); 44 | char *end = strrchr(machine->release, '.'); 45 | 46 | if(end == NULL){ 47 | ssds_log(logERROR, "Internal error - unable to find dot in release string.\n"); 48 | ssds_free(machine); 49 | return; 50 | } 51 | 52 | char *i = end-1; 53 | ssds_log(logDEBUG, "Search release number.\n"); 54 | 55 | while(i > machine->release && isdigit(i[0])) 56 | { 57 | i--; 58 | } 59 | ssds_log(logDEBUG, "Getting release string length.\n"); 60 | 61 | int length = end - i; 62 | ssds_log(logDEBUG, "Allocating memory for release string.\n"); 63 | char *fedora_release = (char *)ssds_malloc(length*sizeof(char)); 64 | 65 | if(fedora_release == NULL){ 66 | ssds_log(logERROR, "Not enough memory on heap.\n"); 67 | ssds_free(machine); 68 | return; 69 | } 70 | 71 | ssds_log(logDEBUG, "Memory allocated.\n"); 72 | 73 | i++; length--; 74 | 75 | ssds_log(logDEBUG, "Copying release number into new string.\n"); 76 | strncpy(fedora_release, i, length); //22 or 21 or any other 77 | fedora_release[length] = '\0'; 78 | 79 | ssds_log(logDEBUG, "Getting path string.\n"); 80 | //composing path to @System.solv file 81 | snprintf(ret_val, 100, "/var/cache/dnf/%s/%s/@System.solv",machine->machine,fedora_release); 82 | //snprintf(ret_val, 100, "/var/cache/dnf/@System.solv"); 83 | ssds_log(logDEBUG, "Getting arch string.\n"); 84 | *arch = machine->machine; 85 | *release = fedora_release; 86 | } 87 | 88 | int progress_callback(void *data, double total, double downloaded){ 89 | if(total > 0){ 90 | printf("\r%.40s\t%.0f%%",(char *)data, (downloaded/total)*100); 91 | fflush(stdout); 92 | } 93 | return 0; 94 | } 95 | 96 | int end_callback(void *data, LrTransferStatus status, const char *msg){ 97 | if(status == LR_TRANSFER_SUCCESSFUL){ 98 | printf("\r%.40s\t%s\n",(char *)data,"100% - Downloaded."); 99 | }else{ 100 | printf("\r%.40s\t%s\n",(char *)data,msg); 101 | } 102 | return status; 103 | } 104 | 105 | -------------------------------------------------------------------------------- /src/common/util.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký, Walter Scherfel 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #ifndef _UTIL_H 22 | #define _UTIL_H 23 | 24 | #ifdef __cplusplus 25 | extern "C"{ 26 | #endif 27 | 28 | #include "includes.h" 29 | #include "log_handler.h" 30 | #include 31 | #include "mem_management.h" 32 | 33 | /** 34 | * Resolves path for @System.solv file depending on system version 35 | * @brief ssds_resolve_dependency_file_path 36 | * @param ret_val return value of function 37 | * @param arch return value of function 38 | * @param release return value of function 39 | */ 40 | void ssds_resolve_dependency_file_path(char* ret_val, char** arch, char** release); 41 | 42 | /** 43 | * Callback function for downloading packages 44 | * @param data void* 45 | * @param total double 46 | * @param downloaded double 47 | * @return 0 48 | */ 49 | int progress_callback(void *data, double total, double downloaded); 50 | 51 | /** 52 | * Callback function called after package download 53 | * @param data void* 54 | * @param status LrTransferStatus 55 | * @param msg const char* 56 | * @return status 57 | */ 58 | int end_callback(void *data, LrTransferStatus status, const char *msg); 59 | 60 | 61 | #ifdef __cplusplus 62 | } 63 | #endif 64 | 65 | #endif 66 | -------------------------------------------------------------------------------- /src/examples/Makefile_log: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | CFLAGS=-std=c11 3 | INCLUDE=-I/usr/include/glib-2.0/ -I/usr/lib64/glib-2.0/include/ 4 | LINKS=-lglib-2.0 5 | 6 | 7 | all: handler example 8 | $(CC) $(CFLAGS) $(INCLUDE) $(LINKS) log_example.o log_handler.o -o log 9 | example: 10 | $(CC) $(CFLAGS) $(INCLUDE) $(LINKS) -c log_example.c -o log_example.o 11 | handler: 12 | $(CC) $(CFLAGS) $(INCLUDE) $(LINKS) -c log_handler.c -o log_handler.o 13 | clean: 14 | rm -rf log *.o 15 | -------------------------------------------------------------------------------- /src/examples/Makefile_params: -------------------------------------------------------------------------------- 1 | #soubor: Makefile 2 | # Michal Ruprich, xrupri00, RedHat, SSDS - hawkey example 3 | 4 | CC=gcc 5 | CFLAGS= -std=c11 6 | 7 | all: param_ex 8 | param_ex: params log 9 | $(CC) $(CFLAGS) param_ex.c params.o log_handler.o -o param_ex 10 | params: 11 | $(CC) $(CFLAGS) ../common/params.c -c 12 | log: ../common/log_handler.c 13 | $(CC) $(CFLAGS) ../common/log_handler.c -c 14 | clean: 15 | rm -rf param_ex *.o 16 | -------------------------------------------------------------------------------- /src/examples/client.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | 10 | #define MAX_INPUT_LEN 10 11 | #define BUFF_SIZE 50 12 | 13 | int main() 14 | { 15 | int socket_desc; 16 | const char * message = "Hello from client\n"; 17 | socket_desc=socket(AF_INET, SOCK_STREAM, 0);//AF_INET = IPv4, SOCK_STREAM = TCP, 0 = IP 18 | 19 | struct sockaddr_in server; 20 | server.sin_addr.s_addr=inet_addr("127.0.0.1"); 21 | server.sin_family=AF_INET; 22 | server.sin_port=htons(2345); 23 | 24 | if(socket_desc==-1) 25 | { 26 | printf("Client encountered an error when creating socket for communication\n"); 27 | return 1; 28 | } 29 | 30 | if(connect(socket_desc, (struct sockaddr *)&server, sizeof(server))<0) 31 | { 32 | printf("Connection error\n"); 33 | return 1; 34 | } 35 | 36 | printf("Connection successful\n"); 37 | FILE* fd = fopen("/var/cache/dnf/x86_64/21/@System.solv", "r"); 38 | 39 | long int len = fseek(fd, 0, SEEK_END); 40 | printf("length of file: %d\n", ftell(fd)); 41 | 42 | long int send_num = htonl(len); 43 | 44 | 45 | write(socket_desc, &send_num, sizeof(send_num)); 46 | // write(socket_desc, message, strlen(message)); 47 | 48 | 49 | 50 | 51 | // printf("%s", buf); 52 | 53 | // free(buf); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /src/examples/hawkey_ex.c: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C"{ 3 | #endif 4 | 5 | #include 6 | #include 7 | #include "hawkey_ex.h" 8 | #include 9 | 10 | void example_func(){ 11 | HySack sack = hy_sack_create(NULL, NULL, NULL,HY_MAKE_CACHE_DIR); 12 | 13 | 14 | } 15 | 16 | #ifdef __cplusplus 17 | } 18 | #endif -------------------------------------------------------------------------------- /src/examples/hawkey_ex.h: -------------------------------------------------------------------------------- 1 | //#include 2 | //#include 4 | 5 | void example_func(); -------------------------------------------------------------------------------- /src/examples/json_improved.h: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | //GLIB 22 | #include 23 | #include 24 | 25 | //JSON-GLIB 26 | #include 27 | #include 28 | 29 | #include 30 | #include 31 | #include 32 | 33 | /** 34 | *Type of url from .repo file located in /etc/yum.repos.d/ 35 | */ 36 | typedef enum { 37 | SSDS_BASEURL = 1, /**< #baseurl in .repo file */ 38 | SSDS_MIRRORLIST, /**< #mirrorlist in .repo file */ 39 | SSDS_METALINK /**< #metalink in .repo file*/ 40 | } SsdsJsonUrlType; 41 | 42 | /********************************************************************************************** 43 | * Json create - this part describes functions used when creating json structure from scratch * 44 | **********************************************************************************************/ 45 | 46 | /** 47 | * Structure used for creating message in json to be sent over the network 48 | */ 49 | typedef struct SsdsJsonCreate SsdsJsonCreate; 50 | 51 | struct SsdsJsonCreate{ 52 | JsonGenerator * generator; /**< Holds structure for generatig json from scraps */ 53 | JsonNode* rootNode; /**< Points to root of json */ 54 | JsonNode* codeNode; /**< Points to node holding control code */ 55 | JsonNode* dataNode; /**< Points to node holding data part of json */ 56 | JsonNode* currNode; /**< Currently used node */ 57 | JsonObject* rootObj; /**< Root object - used for adding new objects */ 58 | JsonObject* dataObj; /**< Data object - used for adding objects under data */ 59 | JsonObject* currObj; /**< Currently used object */ 60 | JsonArray* currArray; /**< Currently used array */ 61 | }; 62 | 63 | /** 64 | * Type of data that is inserted into objects or arrays 65 | */ 66 | typedef enum { 67 | JS_STRING = 0, 68 | JS_INT, 69 | JS_BOOL, 70 | JS_ARRAY, 71 | JS_OBJ 72 | }SsdsJsInsType; 73 | 74 | /** 75 | * Returns new SsdsJsonCreate structure - this structure is needed during the whole process of json creation 76 | * @return newly allocated SsdsJsonCreate structure 77 | */ 78 | SsdsJsonCreate* ssds_js_cr_init(int code); 79 | 80 | /** 81 | * Adds a new element into currArray from SsdsJsonCreate structure 82 | * Array that is created last is set to be currArray. For inserting elements to defferent array use ssds_js_cr_switch_array 83 | * @param json SsdsJsonCreate structure holding the json structure in memory 84 | * @param type SsdsJsInsType - integer identifying type of data inserted as a new element 85 | * @param data data to be inserted - string, int, or bool - for object and array use NULL 86 | */ 87 | void ssds_js_cr_add_array_member(SsdsJsonCreate* json, int type, void* data); 88 | 89 | /** 90 | * Adds a new element into currObj from SsdsJsonCreate structure. 91 | * Works the same way as ssds_js_cr_add_array_member. 92 | * @param json SsdsJsonCreate structure holding the json structure in memory 93 | * @param type SsdsJsInsType - integer identifying type of data inserted as a new element 94 | * @param data data to be inserted - string, int, or bool - for object and array use NULL 95 | * @param name string to be used as a name for new element 96 | */ 97 | void ssds_js_cr_add_obj_member(SsdsJsonCreate* json, int type, void* data, const char* name); 98 | 99 | /** 100 | * Adds new element into top level data object. It can be array, object, string, bool or int. 101 | * @param json SsdsJsonCreate structure holding the json structure in memory 102 | * @param type SsdsJsInsType - integer identifying type of data inserted as a new element 103 | * @param data data to be inserted - string, int, or bool - for object and array use NULL 104 | * @param name string to be used as a name for new element 105 | */ 106 | void ssds_js_cr_new_data(SsdsJsonCreate* json, int type, const char* name, void* data); 107 | 108 | /** 109 | * Finds an array anywhere in the json structure and sets json->currArray as the currently active array. 110 | * @param json SsdsJsonCreate structure holding the json structure in memory 111 | * @param name String used as the array identifier 112 | * @return TRUE if array with given name is found and set, otherwise FALSE 113 | */ 114 | gboolean ssds_js_cr_switch_array(SsdsJsonCreate* json, const char* name); 115 | 116 | /** 117 | * Sets array one level above the current array as the current array. 118 | * @param json SsdsJsonCreate structure holding the json structure in memory 119 | */ 120 | void ssds_js_cr_upper_array(SsdsJsonCreate* json); 121 | 122 | /** 123 | * Sets object one level above current object as current object 124 | * @param json SsdsJsonCreate structure holding the json structure in memory 125 | */ 126 | void ssds_js_cr_upper_obj(SsdsJsonCreate* json); 127 | 128 | /** 129 | * Converts data in memory represented by SsdsJsonCreate to string. 130 | * @param json SsdsJsonCreate structure holding the json structure in memory 131 | */ 132 | char* ssds_js_cr_to_string(SsdsJsonCreate* json); 133 | 134 | /** 135 | * Function used for debugging - use it to dump the created json to stdout. 136 | * @param json SsdsJsonCreate structure holding the json structure in memory 137 | */ 138 | void ssds_js_cr_dump(SsdsJsonCreate* json); 139 | 140 | /********************************************************************************************** 141 | * Json read - this part describes functions used when parsing recieved json structure * 142 | **********************************************************************************************/ 143 | /** 144 | * Structure used for parsing message recieved through socket and converting it to json structure 145 | */ 146 | typedef struct SsdsJsonRead SsdsJsonRead; 147 | 148 | struct SsdsJsonRead{ 149 | JsonParser* parser; /** < parser holds SsdsJsonRead structure */ 150 | JsonNode* rootNode; /** < root of json - used to find objects */ 151 | JsonNode* currNode; /** < currently used node */ 152 | JsonNode* dataNode; /** < data node - often used */ 153 | JsonObject* currObj; /** < currently used object */ 154 | JsonObject* dataObj; /** < data object - often used for adding new objects */ 155 | }; 156 | 157 | /** 158 | * Returns new SsdsJsonRead structure - this structure is needed during the whole process of json parsing 159 | * @return newly allocated SsdsJsonCreate structure 160 | */ 161 | SsdsJsonRead* ssds_json_rd_init(); 162 | 163 | /** 164 | * Parses string representing json structure into SsdsJsonRead structure. 165 | * @param buffer Json structure in a string 166 | * @param json SsdsJsonRead structure holding parsed json in memory 167 | * @return Returns TRUE if the recieved json is valid, FALSE otherwise - TODO 168 | */ 169 | gboolean ssds_rd_parse(char* buffer, SsdsJsonRead* json); 170 | 171 | /** 172 | * Extracts status code from json. 173 | * @param json SsdsJsonRead structure holding parsed json in memory 174 | * @return status code from recieved json 175 | */ 176 | int ssds_rd_get_code(SsdsJsonRead* json); 177 | 178 | /** 179 | * Finds all elements from recieved json. x_path is a string describing path to the elements. 180 | * All elements found are placed in a GList. 181 | * @param json SsdsJsonRead structure holding parsed json in memory 182 | * @param x_path JsonPath format as a string - TODO 183 | * @return GList of all elements found - this needs to be freed afterwards 184 | */ 185 | GList* ssds_js_rd_find(SsdsJsonRead* json, char* x_path); -------------------------------------------------------------------------------- /src/examples/log_example.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "log_handler.h" 5 | 6 | // #define g_message(message) g_print("SSDS: MESSAGE: %s\n", message) 7 | // #define g_info(message) g_print("SSDS: INFO: %s\n", message) 8 | // #define g_warning(message) g_print("SSDS: WARNING: %s\n", message) 9 | // #define g_error(message) g_print("SSDS: ERROR: %s\n", message) 10 | // #define g_debug(message) g_print("SSDS: DEBUG: %s\n", message) 11 | // #define g_critical(message) g_print("SSDS: CRITICAL: %s\n", message) 12 | 13 | 14 | 15 | void main() 16 | { 17 | printf("%s\n", log_lvl_msg[0]); 18 | ssds_log("Pokusna zprava", logINFO); 19 | ssds_log("Pokusny error", logERROR); 20 | 21 | set_verbose(); 22 | ssds_log("Pokusna zprava", logINFO); 23 | } -------------------------------------------------------------------------------- /src/examples/param_ex.c: -------------------------------------------------------------------------------- 1 | #include "../common/params.h" 2 | 3 | int main(int argc, char* argv[]) 4 | { 5 | if(parse_params(argc, argv)==-1) 6 | return 1; 7 | 8 | 9 | 10 | return 0; 11 | } -------------------------------------------------------------------------------- /src/examples/server.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int main() 8 | { 9 | int listen_sock, connect_sock; 10 | char* client_ip; 11 | char client_msg[1000]; 12 | listen_sock=socket(AF_INET, SOCK_STREAM, 0);//AF_INET = IPv4, SOCK_STREAM = TCP, 0 = IP 13 | 14 | if(listen_sock==-1) 15 | { 16 | printf("Server encountered an error when creating socket for communication\n"); 17 | return 1; 18 | } 19 | 20 | struct sockaddr_in server, client; 21 | server.sin_family=AF_INET; 22 | server.sin_addr.s_addr=INADDR_ANY; 23 | server.sin_port=htons(2345); 24 | 25 | if(bind(listen_sock, (struct sockaddr*)&server, sizeof(server)) <0) 26 | { 27 | printf("Server wasn't able to bind with socket\n"); 28 | return 1; 29 | } 30 | 31 | printf("Server ready. Waiting for incoming connections.\n"); 32 | 33 | if(listen(listen_sock, 5)!=0) 34 | { 35 | printf("Listen failed on server\n"); 36 | return 1; 37 | } 38 | 39 | const char* message = "Look, just because I don't be givin' no man a foot massage don't make it right for Marsellus to throw Antwone into a glass motherfuckin' house, fuckin' up the way the nigger talks. Motherfucker do that shit to me, he better paralyze my ass, 'cause I'll kill the motherfucker, know what I'm sayin'?\n"; 40 | printf("msg len: %d\n", strlen(message)); 41 | int addr_len = sizeof(server); 42 | while(1) 43 | { 44 | if((connect_sock=accept(listen_sock, (struct sockaddr *) &client, (socklen_t*)&addr_len))<0) 45 | { 46 | printf("Accept connection has failed\n"); 47 | return 1; 48 | } 49 | 50 | int recv_nmr = 0; 51 | 52 | if( recv(connect_sock, &recv_nmr , sizeof(recv_nmr) , 0) < 0) 53 | { 54 | printf("Recieving of data has failed\n"); 55 | return 1; 56 | } 57 | 58 | client_ip=inet_ntoa(client.sin_addr); 59 | printf("Connection accepted from ip address %s\n", client_ip); 60 | 61 | printf("%d\n", ntohl(recv_nmr)); 62 | 63 | // write(connect_sock, message, strlen(message)); 64 | } 65 | 66 | return 0; 67 | } -------------------------------------------------------------------------------- /src/server/Makefile: -------------------------------------------------------------------------------- 1 | # all source file should be in one foldder for your own testing with this temporary Makefile 2 | # make server, make client, make clean ("make" ONLY builds server) 3 | 4 | TARGETS = server #name of the program && target file 5 | OBJS = Server.o 6 | CC = g++ 7 | CXXFLAGS = -O2 -g -Wall -Wextra -pedantic -std=c++11 -I/usr/local/include -L/usr/local/lib -lboost_thread -lboost_system -fmessage-length=0 8 | 9 | #basic build function with dependency OBJ 10 | server: $(OBJS) 11 | $(CC) $(CXXFLAGS) $(OBJS) -o $(TARGETS) 12 | 13 | Server.o: Server.cpp 14 | $(CC) $(CXXFLAGS) -c Server.cpp 15 | 16 | TAREGETC = client 17 | OBJC = client.o 18 | 19 | client: $(OBJC) 20 | $(CC) $(CXXFLAGS) $(OBJC) -o client 21 | 22 | client.o: client.cpp 23 | $(CC) $(CXXFLAGS) -c client.cpp 24 | 25 | clean: 26 | rm -f $(OBJS) $(TARGETS) $(OBJC) $(TARGETC) 27 | -------------------------------------------------------------------------------- /src/server/README: -------------------------------------------------------------------------------- 1 | This part of code is used for server side 2 | 3 | Implemented up until now: 4 | 1. 5 | >> start of synchronous connection based on boost.asio library 6 | >> server class (&methods) 7 | >>first preparation of handling errors and exceptions: demonstration of exception for future development 8 | -------------------------------------------------------------------------------- /src/server/server.c: -------------------------------------------------------------------------------- 1 | #include "server.h" 2 | 3 | int ssds_server_init(int *comm_desc, int *comm_addr_len) 4 | { 5 | 6 | /*************************************************************************/ 7 | /* Initialization of server */ 8 | /*************************************************************************/ 9 | 10 | int enable = 1, status = OK; 11 | struct sockaddr_in server_comm; 12 | 13 | *comm_desc = ssds_socket(AF_INET, SOCK_STREAM, 0);//AF_INET = IPv4, SOCK_STREAM = TCP, 0 = IP 14 | 15 | setsockopt(*comm_desc, SOL_SOCKET, SO_REUSEADDR, &enable, sizeof(enable)); 16 | 17 | if(*comm_desc == -1) 18 | { 19 | ssds_log(logERROR, "Server encountered an error when creating socket for communication.\n"); 20 | status = SOCKET_ERROR; 21 | goto initEnd; 22 | } 23 | 24 | ssds_log(logDEBUG, "Socket ready.\n"); 25 | 26 | long int comm_port; 27 | read_srv_cfg(&comm_port); 28 | 29 | server_comm.sin_family = AF_INET; 30 | server_comm.sin_addr.s_addr = INADDR_ANY; 31 | server_comm.sin_port = htons(comm_port); 32 | 33 | if(bind(*comm_desc, (struct sockaddr*)&server_comm, sizeof(server_comm)) < 0) 34 | { 35 | ssds_log(logERROR, "Server wasn't able to bind with communication socket.\n"); 36 | status = SOCKET_ERROR; 37 | goto initEnd; 38 | } 39 | 40 | if(setsockopt(*comm_desc, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(enable)) < 0){ 41 | ssds_log(logERROR, "Server wasn't able to set communication socket option.\n"); 42 | status = SOCKET_ERROR; 43 | goto initEnd; 44 | } 45 | 46 | ssds_log(logINFO, "Server set up. Waiting for incoming connections.\n"); 47 | 48 | if(listen(*comm_desc, 5) != 0) 49 | { 50 | ssds_log(logERROR, "Listen failed on communication socket on server.\n"); 51 | status = SOCKET_ERROR; 52 | goto initEnd; 53 | } 54 | 55 | *comm_addr_len = sizeof(server_comm); 56 | 57 | initEnd: 58 | return status; 59 | } 60 | 61 | int ssds_server_accept_connection(int comm_desc, int comm_addr_len) 62 | { 63 | int socket, status = OK, client_end = 0; 64 | struct sockaddr_in client_comm; 65 | 66 | if((socket = ssds_accept(comm_desc, (struct sockaddr *) &client_comm, (socklen_t*)&comm_addr_len)) < 0) 67 | { 68 | ssds_log(logERROR, "Accept connection has failed.\n"); 69 | status = SOCKET_ERROR; 70 | goto acceptEnd; 71 | } 72 | 73 | char *client_ip = inet_ntoa(client_comm.sin_addr); 74 | ssds_log(logMESSAGE, "Connection accepted from ip address %s\n", client_ip); 75 | 76 | // FORK HERE ? 77 | 78 | while(!client_end){ 79 | status = ssds_server_process(socket, client_ip, &client_end); 80 | if(status != OK) goto acceptEnd; 81 | } 82 | 83 | acceptEnd: 84 | ssds_close(socket); 85 | ssds_log(logDEBUG, "End of communication with client.\n"); 86 | 87 | return status; 88 | } 89 | 90 | int ssds_server_process(int socket, char *client_ip, int *client_end) 91 | { 92 | int status = OK, bytes_to_write, bytes_written = 0, bytes_read; 93 | FILE * f; 94 | char *buf = sock_recv(socket), *msg, *comm_buffer; 95 | SsdsJsonCreate *json_send = ssds_js_cr_init(ANSWER_OK); 96 | SsdsJsonRead *json_read = ssds_js_rd_init(); 97 | 98 | if(buf == NULL) 99 | { 100 | ssds_log(logERROR, "Recieving of message has failed.\n"); 101 | status = NETWORKING_ERROR; 102 | goto processEnd; 103 | } 104 | 105 | if(!ssds_js_rd_parse(buf, json_read))//parse incoming message 106 | { 107 | ssds_log(logERROR, "False data recieved from %s. Client rejected.\n", client_ip); 108 | goto processEnd; 109 | } 110 | 111 | ssds_log(logDEBUG, "%s\n\n", buf); 112 | 113 | switch(ssds_js_rd_get_code(json_read)) 114 | { 115 | case SEND_SOLV: 116 | ssds_log(logDEBUG, "Got message with code %d (client is going to send @System.solv file).\n", SEND_SOLV); 117 | 118 | bytes_to_write = ssds_js_rd_get_read_bytes(json_read); 119 | 120 | f = fopen("@System.solv","wb"); //for now the file is in the same directory as server; 121 | if(f == NULL) 122 | { 123 | ssds_log(logERROR,"Error while creating @System.solv file.\n"); 124 | ssds_js_cr_insert_code(json_send, ANSWER_ERROR); 125 | ssds_js_cr_set_message(json_send, "Error while creating @System.solv file on server side."); 126 | msg = ssds_js_cr_to_string(json_send); 127 | secure_write(socket, msg, strlen(msg)); 128 | status = FILE_ERROR; 129 | goto processEnd; 130 | } 131 | 132 | bytes_written = 0; 133 | 134 | while(1) 135 | { 136 | bytes_read = sock_solv_recv(socket, &comm_buffer); 137 | if(fwrite(comm_buffer ,1 ,bytes_read ,f) != bytes_read){ 138 | ssds_log(logERROR, "Error while writing to @System.solv file.\n"); 139 | ssds_js_cr_insert_code(json_send, ANSWER_ERROR); 140 | ssds_js_cr_set_message(json_send, "Error while writing to @System.solv file on server side.\n"); 141 | *client_end = 1; 142 | break; 143 | } 144 | 145 | ssds_free(comm_buffer); 146 | bytes_written += bytes_read; 147 | 148 | if(bytes_read < 0){ 149 | ssds_js_cr_set_message(json_send, "Error while reading data from client."); 150 | *client_end = 1; 151 | break; 152 | } 153 | if(bytes_written == bytes_to_write) 154 | { 155 | break; 156 | } 157 | 158 | ssds_log(logDEBUG, "%.0f %% of @System.solv file is written.\n", 159 | (((double)bytes_written/(double)bytes_to_write)*100)); 160 | } 161 | msg = ssds_js_cr_to_string(json_send); 162 | secure_write(socket, msg, strlen(msg)); 163 | fclose(f); 164 | ssds_log(logDEBUG, "Finished writing @System.solv file.\n"); 165 | break; 166 | 167 | case SEND_YUM_CONF: 168 | ssds_log(logDEBUG, "Got message with code %d (client is going to send yum.conf file).\n", SEND_YUM_CONF); 169 | 170 | bytes_to_write = ssds_js_rd_get_read_bytes(json_read); 171 | 172 | f = fopen("yum.conf","wb"); //for now the file is in the same directory as server; 173 | if(f == NULL) 174 | { 175 | ssds_log(logERROR,"Error while creating yum.conf file.\n"); 176 | ssds_js_cr_insert_code(json_send, ANSWER_ERROR); 177 | ssds_js_cr_set_message(json_send, "Error while creating yum.conf file on server side."); 178 | msg = ssds_js_cr_to_string(json_send); 179 | secure_write(socket, msg, strlen(msg)); 180 | status = FILE_ERROR; 181 | goto processEnd; 182 | } 183 | 184 | bytes_written = 0; 185 | 186 | while(1) 187 | { 188 | bytes_read = sock_solv_recv(socket, &comm_buffer); 189 | if(fwrite(comm_buffer ,1 ,bytes_read ,f) != bytes_read){ 190 | ssds_log(logERROR, "Error while writing to yum.conf file.\n"); 191 | ssds_js_cr_insert_code(json_send, ANSWER_ERROR); 192 | ssds_js_cr_set_message(json_send, "Error while writing to yum.conf file on server side.\n"); 193 | *client_end = 1; 194 | break; 195 | } 196 | ssds_free(comm_buffer); 197 | bytes_written += bytes_read; 198 | 199 | if(bytes_read < 0){ 200 | ssds_js_cr_set_message(json_send, "Error while reading data fom client."); 201 | *client_end = 1; 202 | break; 203 | } 204 | if(bytes_written == bytes_to_write) 205 | { 206 | break; 207 | } 208 | 209 | ssds_log(logDEBUG, "%.0f %% of yum.conf file is written.\n", 210 | (((double)bytes_written/(double)bytes_to_write)*100)); 211 | } 212 | msg = ssds_js_cr_to_string(json_send); 213 | secure_write(socket, msg, strlen(msg)); 214 | fclose(f); 215 | ssds_log(logDEBUG, "Finished writing yum.conf file.\n"); 216 | break; 217 | 218 | case GET_INSTALL: 219 | case GET_UPDATE: 220 | case GET_UPDATE_ALL: 221 | case GET_ERASE: 222 | // ssds_js_rd_get_count(json_read, "pokus"); 223 | /* Checking repo files */ 224 | /* TODO here should be checking of cached repo files !!! */ 225 | ssds_log(logDEBUG, "Repo files checking.\n"); 226 | 227 | msg = ssds_js_cr_to_string(json_send); 228 | secure_write(socket, msg, strlen(msg)); 229 | 230 | /* Dependency solving part */ 231 | ssds_log(logMESSAGE, "\n\nDEPENDENCY SOLVING.\n\n"); 232 | 233 | char** pkgs = NULL; 234 | int pkg_count = 0; 235 | //SsdsPkgInfo* pkgs = ssds_js_rd_pkginfo_init(); 236 | if(ssds_js_rd_get_code(json_read) != GET_UPDATE_ALL) 237 | { 238 | pkg_count = ssds_js_rd_get_count(json_read, "req_pkgs"); 239 | pkgs = (char**)malloc((pkg_count+1)*sizeof(char*)); 240 | ssds_js_rd_get_packages(pkgs, json_read); 241 | 242 | ssds_log(logDEBUG, "Packages parsed. Packages from client:\n"); 243 | for(int i = 0; i < pkg_count; i++) 244 | { 245 | ssds_log(logDEBUG, "\t%s\n", pkgs[i]); 246 | } 247 | } 248 | ssds_log(logDEBUG, "Getting repo info from client.\n"); 249 | 250 | SsdsRepoInfoList* list = ssds_js_rd_list_init(); 251 | ssds_js_rd_repo_info(json_read, list); 252 | 253 | guint len = g_slist_length(list->repoInfoList); 254 | 255 | ssds_log(logDEBUG, "Repositories, count: %d: \n", len); 256 | for(unsigned int i = 0; i < len; i++) 257 | { 258 | SsdsRepoInfo* info = (SsdsRepoInfo*)g_slist_nth_data(list->repoInfoList, i); 259 | ssds_log(logDEBUG, "\t%d: %s\n", i, info->name); 260 | } 261 | 262 | SsdsRepoMetadataList* meta_list = ssds_repo_metadata_init(); 263 | ssds_locate_repo_metadata(/*json, */list, meta_list); 264 | 265 | HySack sack; 266 | #if VERSION_HAWKEY 267 | sack = hy_sack_create(NULL, NULL, NULL, NULL, HY_MAKE_CACHE_DIR); 268 | #else 269 | sack = hy_sack_create(NULL, NULL, NULL, HY_MAKE_CACHE_DIR); 270 | #endif 271 | 272 | hy_sack_load_system_repo(sack, NULL, HY_BUILD_CACHE); 273 | HySack* sack_p = &sack; 274 | ssds_fill_sack(sack_p, meta_list); 275 | 276 | if(ssds_dep_query(pkgs, json_send, sack_p, ssds_js_rd_get_code(json_read), pkg_count) == -1) 277 | { 278 | ssds_js_cr_insert_code(json_send, ANSWER_NO_DEP); 279 | ssds_js_cr_set_message(json_send, "Dependencies for requested package were not resolved. Package cannot be installed\n"); 280 | } 281 | else 282 | ssds_js_cr_insert_code(json_send, ANSWER_OK); 283 | // ssds_dep_answer(json_read, json_send, sack_p); 284 | 285 | ssds_js_cr_dump(json_send); 286 | msg = ssds_js_cr_to_string(json_send); 287 | // printf("%s\n\n", msg); 288 | secure_write(socket, msg, strlen(msg)); 289 | *client_end = 1; 290 | break; 291 | 292 | 293 | case GET_DEPENDENCY: 294 | /* Checking repo files */ 295 | /* TODO here should be checking of cached repo files !!! */ 296 | ssds_log(logDEBUG, "Repo files checking.\n"); 297 | 298 | msg = ssds_js_cr_to_string(json_send); 299 | secure_write(socket, msg, strlen(msg)); 300 | *client_end = 1; 301 | break; 302 | 303 | default: //client_end = 1; 304 | break; 305 | }//switch 306 | // 307 | processEnd: 308 | ssds_free(json_read); 309 | ssds_free(json_send); 310 | return status; 311 | } 312 | -------------------------------------------------------------------------------- /src/server/server.h: -------------------------------------------------------------------------------- 1 | #ifndef _SERVER_2_H 2 | #define _SERVER_2_H 3 | 4 | #ifdef __cplusplus 5 | extern "C"{ 6 | #endif 7 | 8 | //Standard libraries 9 | #include "../common/includes.h" 10 | 11 | //SSDS 12 | #include "../common/log_handler.h" 13 | #include "../common/network_util.h" 14 | #include "../common/repo_handler.h" 15 | #include "../common/json_handler.h" 16 | #include "../common/solving.h" 17 | #include "../common/params.h" 18 | #include "../common/mem_management.h" 19 | #include "../../cmake/Config/version_conf.h" 20 | #include "../common/cfg_parsing.h" 21 | #include "../common/errors.h" 22 | 23 | int ssds_server_init(int *comm_desc, int *comm_addr_len); 24 | 25 | int ssds_server_accept_connection(int comm_desc, int comm_addr_len); 26 | 27 | int ssds_server_process(int comm_port, char *clietn_ip, int *client_end); 28 | 29 | #ifdef __cplusplus 30 | } 31 | #endif 32 | #endif 33 | -------------------------------------------------------------------------------- /src/server/server_main.c: -------------------------------------------------------------------------------- 1 | /* Server side dependency solving - transfer of dependency solving from local machine to server when installing new packages 2 | * Copyright (C) 2015 Michal Ruprich, Josef Řídký 3 | * 4 | * Licensed under the GNU Lesser General Public License Version 2.1 5 | * 6 | * This library is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 2.1 of the License, or (at your option) any later version. 10 | * 11 | * This library 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 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public 17 | * License along with this library; if not, write to the Free Software 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 | */ 20 | 21 | #include "server.h" 22 | 23 | 24 | int main(int argc, char* argv[]) { 25 | /*******************************************************************/ 26 | /* Setting up garbage collector and setting callback functions */ 27 | /*******************************************************************/ 28 | ssds_gc_init(); 29 | signal(SIGINT, ssds_signal_handler); 30 | signal(SIGBUS, ssds_signal_handler); 31 | signal(SIGSEGV, ssds_signal_handler); 32 | signal(SIGTERM, ssds_signal_handler); 33 | 34 | int status = OK, comm_desc, comm_addr_len; 35 | 36 | parse_params_srv(argc, argv); 37 | 38 | ssds_log(logSSDS, "Server started.\n"); 39 | ssds_log(logDEBUG, "Params parsed.\n"); 40 | 41 | status = ssds_server_init(&comm_desc, &comm_addr_len); 42 | if(status != OK) goto end; 43 | 44 | while(1){ 45 | status = ssds_server_accept_connection(comm_desc, comm_addr_len); 46 | if(status == EXIT) goto end; 47 | } 48 | end: 49 | ssds_gc_cleanup(); 50 | return status; 51 | } 52 | -------------------------------------------------------------------------------- /tests/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set (RDS_TEST_FILES 2 | test_main.c 3 | test_dummy.c 4 | test_template.c 5 | test_cfg_parsing.c 6 | test_params.c 7 | test_gc.c 8 | test_missing_repos.c 9 | ) 10 | 11 | add_executable(test_main ${RDS_TEST_FILES}) 12 | 13 | find_package(Check REQUIRED) 14 | #set(LIBS ${LIBS} ${CHECK_LIBRARIES}) 15 | #include_directories(${CHECK_INCLUDE_DIRS}) 16 | #target_link_libraries(${CHECK_LDFLAGS}) 17 | include_directories(. ../src ${CHECK_INCLUDE_DIRS}) 18 | 19 | target_link_libraries(test_main 20 | lib_rds_client 21 | lib_rds_server 22 | lib_rds_common 23 | ${CHECK_LDFLAGS}) 24 | 25 | add_test(test_main ${CMAKE_CURRENT_BINARY_DIR}/../tests/test_main) 26 | -------------------------------------------------------------------------------- /tests/test_cfg_parsing.c: -------------------------------------------------------------------------------- 1 | //test_template.c - simple test suite template 2 | 3 | #include "test_cfg_parsing.h" 4 | 5 | START_TEST(test_cfg_parsing) 6 | { 7 | ssds_gc_init(); 8 | 9 | number_read(); 10 | invalid_file(); 11 | param_too_long(); 12 | complex_read(); 13 | 14 | ssds_gc_cleanup(); 15 | } 16 | END_TEST 17 | 18 | Suite* cfg_parsing_suite(void) 19 | { 20 | Suite* s = suite_create("cfg_parsing"); 21 | TCase* tc = tcase_create("Main"); 22 | tcase_add_test(tc, test_cfg_parsing); 23 | suite_add_tcase(s, tc); 24 | return s; 25 | } 26 | 27 | int complex_read() 28 | { 29 | FILE *tempfile; 30 | tempfile = fopen("../connection.cfg", "w+"); 31 | if (tempfile == NULL) 32 | { 33 | printf("unable to test, cannot create new file\n"); 34 | return 1; 35 | } 36 | char *tst_str = "address=127.0.0.2\nport=951\n"; 37 | 38 | fwrite(tst_str, sizeof(char), strlen(tst_str), tempfile); 39 | fseek(tempfile, 0, SEEK_SET); 40 | 41 | char *address, *id; 42 | long int p1; 43 | read_cfg(&id, &address, &p1); 44 | 45 | fail_if(strcmp(address, "127.0.0.2") != 0); 46 | fail_if(p1 != 951); 47 | fail_if(id != NULL); 48 | 49 | ssds_free(address); 50 | fclose(tempfile); 51 | remove("../connection.cfg"); 52 | 53 | return 0; 54 | } 55 | 56 | int invalid_file() 57 | { 58 | FILE *tempfile; 59 | tempfile = fopen("../connection.cfg", "w+"); 60 | if (tempfile == NULL) 61 | { 62 | printf("unable to test, cannot create new file\n"); 63 | return 1; 64 | } 65 | 66 | char *tst_str = "so-much=127.0.0.2\ninvalid=951\nvalues=789\n#here\n#address=void"; 67 | 68 | fwrite(tst_str, sizeof(char), strlen(tst_str), tempfile); 69 | fseek(tempfile, 0, SEEK_SET); 70 | 71 | char *address, *id; 72 | long int p1; 73 | read_cfg(&id, &address, &p1); 74 | 75 | fail_if(strcmp(address, "127.0.0.1") != 0); 76 | fail_if(p1 != 2345); 77 | fail_if(id != NULL); 78 | 79 | ssds_free(address); 80 | fclose(tempfile); 81 | remove("../connection.cfg"); 82 | 83 | return 0; 84 | } 85 | 86 | int param_too_long() 87 | { 88 | FILE *tempfile; 89 | tempfile = fopen("../connection.cfg", "w+"); 90 | if (tempfile == NULL) 91 | { 92 | printf("unable to test, cannot create new file\n"); 93 | return 1; 94 | } 95 | 96 | char *tst_str = "port=4815162342"; 97 | 98 | fwrite(tst_str, sizeof(char), strlen(tst_str), tempfile); 99 | fseek(tempfile, 0, SEEK_SET); 100 | 101 | char *address, *id; 102 | long int p1; 103 | read_cfg(&id, &address, &p1); 104 | 105 | fail_if(p1 != 4815); 106 | 107 | ssds_free(address); 108 | fclose(tempfile); 109 | remove("../connection.cfg"); 110 | 111 | return 0; 112 | } 113 | 114 | int number_read() 115 | { 116 | FILE *tempfile; 117 | tempfile = fopen("../connection.cfg", "w+"); 118 | if (tempfile == NULL) 119 | { 120 | printf("unable to test, cannot create new file\n"); 121 | return 1; 122 | } 123 | 124 | char *tst_str = "4815162342\nxxx"; 125 | 126 | fwrite(tst_str, sizeof(char), strlen(tst_str), tempfile); 127 | 128 | fseek(tempfile, 0, SEEK_SET); 129 | char *res = file_read_value(tempfile, 0); 130 | fail_if(strcmp(res, "4815162342") != 0); 131 | 132 | ssds_free(res); 133 | 134 | fseek(tempfile, 0, SEEK_SET); 135 | file_read_value(tempfile, 4); 136 | fail_if(strcmp(res, "481") != 0); 137 | 138 | ssds_free(res); 139 | fclose(tempfile); 140 | remove("../connection.cfg"); 141 | 142 | return 0; 143 | } 144 | 145 | -------------------------------------------------------------------------------- /tests/test_cfg_parsing.h: -------------------------------------------------------------------------------- 1 | //test_template.h - simple test suite template 2 | 3 | #ifndef _TEST_CFG_PARSING_H 4 | #define _TEST_CFG_PARSING_H 5 | 6 | #include 7 | #include 8 | #include 9 | //#include 10 | 11 | #include "../src/common/cfg_parsing.h" 12 | 13 | Suite* cfg_parsing_suite(void); 14 | 15 | int number_read(); 16 | int invalid_file(); 17 | int param_too_long(); 18 | int complex_read(); 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /tests/test_dummy.c: -------------------------------------------------------------------------------- 1 | #include "test_dummy.h" 2 | 3 | START_TEST(test_dummy) 4 | { 5 | char* attempt = ret_null(); 6 | ck_assert_str_eq(attempt, NULL); 7 | // printf("Test dummy\n"); 8 | } 9 | END_TEST 10 | 11 | Suite* dummy_suite(void) 12 | { 13 | Suite* s = suite_create("dummy"); 14 | TCase* tc = tcase_create("Main"); 15 | tcase_add_test(tc, test_dummy); 16 | suite_add_tcase(s, tc); 17 | return s; 18 | } 19 | 20 | char* ret_null(void) 21 | { 22 | return NULL; 23 | } 24 | -------------------------------------------------------------------------------- /tests/test_dummy.h: -------------------------------------------------------------------------------- 1 | #ifndef _TEST_DUMMY_H 2 | #define _TEST_DUMMY_H 3 | 4 | #include 5 | #include 6 | #include 7 | // #include 8 | 9 | Suite* dummy_suite(void); 10 | char* ret_null(void); 11 | 12 | #endif -------------------------------------------------------------------------------- /tests/test_gc.c: -------------------------------------------------------------------------------- 1 | //test_params.h - suite for testing parameters parsing 2 | 3 | #include "test_gc.h" 4 | 5 | START_TEST(test_gc) 6 | { 7 | /*CLIENT FUNCTIONS TESTING*/ 8 | /*test 1*/mem_test(); 9 | /*test 2*/socket_test(); 10 | } 11 | END_TEST 12 | 13 | Suite* gc_suite(void) 14 | { 15 | Suite* s = suite_create("gc"); 16 | TCase* tc = tcase_create("Main"); 17 | tcase_add_test(tc, test_gc); 18 | suite_add_tcase(s, tc); 19 | return s; 20 | } 21 | 22 | void mem_test() 23 | { 24 | Ssds_gc * gc = ssds_gc_get_header(); 25 | fail_if(gc != NULL); 26 | 27 | ssds_gc_init(); 28 | 29 | gc = ssds_gc_get_header(); 30 | fail_if(gc == NULL); 31 | 32 | void * a = ssds_malloc(500); 33 | void * b = ssds_realloc(a,800); 34 | 35 | ssds_gc_cleanup(); 36 | gc = ssds_gc_get_header(); 37 | fail_if(gc != NULL); 38 | } 39 | 40 | void socket_test() 41 | { 42 | Ssds_gc * gc = ssds_gc_get_header(); 43 | fail_if(gc != NULL); 44 | 45 | ssds_gc_init(); 46 | int socket; 47 | 48 | socket = ssds_socket(AF_INET, SOCK_STREAM, 0); 49 | fail_if(socket < 0); 50 | 51 | gc = ssds_gc_get_header(); 52 | fail_if(gc == NULL); 53 | 54 | ssds_gc_cleanup(); 55 | 56 | gc = ssds_gc_get_header(); 57 | fail_if(gc != NULL); 58 | } -------------------------------------------------------------------------------- /tests/test_gc.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _TEST_GC_H 3 | #define _TEST_GC_H 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include "../src/common/mem_management.h" 10 | 11 | Suite* gc_suite(void); 12 | 13 | void mem_test(); 14 | void socket_test(); 15 | 16 | #endif -------------------------------------------------------------------------------- /tests/test_main.c: -------------------------------------------------------------------------------- 1 | /* 2 | test_main.c - runs all created (and added) suites 3 | */ 4 | 5 | #include 6 | 7 | /* INCLUDE TEST SUITES: 8 | */ 9 | #include "test_dummy.h" 10 | #include "test_template.h" 11 | #include "test_cfg_parsing.h" 12 | #include "test_params.h" 13 | #include "test_gc.h" 14 | #include "test_missing_repos.h" 15 | 16 | int main() 17 | { 18 | int number_failed; 19 | //create and add test suites to run 20 | SRunner* sr = srunner_create(dummy_suite()); 21 | 22 | /* ADD TEST SUITES TO RUN: 23 | */ 24 | srunner_add_suite(sr, template_suite()); 25 | srunner_add_suite(sr, cfg_parsing_suite()); 26 | //srunner_add_suite(sr, params_suite()); 27 | srunner_add_suite(sr, gc_suite()); 28 | srunner_add_suite(sr, missing_repos_suite()); 29 | 30 | 31 | //runs all added tests 32 | srunner_run_all(sr, CK_NORMAL); 33 | number_failed = srunner_ntests_failed(sr); 34 | srunner_free(sr); 35 | 36 | return (number_failed == 0) ? 0 : 1; 37 | } -------------------------------------------------------------------------------- /tests/test_missing_repos.c: -------------------------------------------------------------------------------- 1 | //test_missing_repos.c - test suite for testing missing repos at clients device 2 | 3 | #include "test_missing_repos.h" 4 | 5 | START_TEST(test_missing_repos) 6 | { 7 | ssds_gc_init(); 8 | 9 | clean_run(); //if this test keeps failing, maybe you have problems with required repositaries 10 | one_repo_missing(); 11 | missing_file(); 12 | 13 | ssds_gc_cleanup(); 14 | } 15 | END_TEST 16 | 17 | Suite* missing_repos_suite(void) 18 | { 19 | Suite* s = suite_create("missing_repos"); 20 | TCase* tc = tcase_create("Main"); 21 | tcase_add_test(tc, test_missing_repos); 22 | suite_add_tcase(s, tc); 23 | return s; 24 | } 25 | 26 | void clean_run() 27 | { 28 | FILE *tempfile; 29 | tempfile = fopen("../required_repos_list.txt", "w+"); 30 | if (tempfile == NULL) 31 | { 32 | printf("unable to test, cannot create new file\n"); 33 | return ; 34 | } 35 | char *tst_str = "fedora.repo\n\ 36 | fedora-updates.repo\n\ 37 | fedora-updates-testing.repo\n\ 38 | google-chrome.repo\n\ 39 | ozonos.repo\n\ 40 | rpmfusion-free-rawhide.repo\n\ 41 | rpmfusion-free.repo\n\ 42 | rpmfusion-free-updates.repo\n\ 43 | rpmfusion-free-updates-testing.repo\n\ 44 | rpmfusion-nonfree-rawhide.repo\n\ 45 | rpmfusion-nonfree.repo\n\ 46 | rpmfusion-nonfree-updates.repo\n\ 47 | rpmfusion-nonfree-updates-testing.repo\n"; 48 | 49 | fwrite(tst_str, sizeof(char), strlen(tst_str), tempfile); 50 | fseek(tempfile, 0, SEEK_SET); 51 | 52 | int t = check_for_missing_repos(); 53 | fail_if(t != 0); 54 | 55 | fclose(tempfile); 56 | remove("../required_repos_list.txt"); 57 | } 58 | 59 | void one_repo_missing() 60 | { 61 | FILE *tempfile; 62 | tempfile = fopen("../required_repos_list.txt", "w+"); 63 | if (tempfile == NULL) 64 | { 65 | printf("unable to test, cannot create new file\n"); 66 | return; 67 | } 68 | char *tst_str = "repo_name_i_just_made_up\n"; 69 | 70 | fwrite(tst_str, sizeof(char), strlen(tst_str), tempfile); 71 | fseek(tempfile, 0, SEEK_SET); 72 | 73 | int t = check_for_missing_repos(); 74 | fail_if(t != 1); 75 | 76 | fclose(tempfile); 77 | remove("../required_repos_list.txt"); 78 | } 79 | 80 | void missing_file() 81 | { 82 | int t = check_for_missing_repos(); 83 | fail_if(t != -1); 84 | } -------------------------------------------------------------------------------- /tests/test_missing_repos.h: -------------------------------------------------------------------------------- 1 | //test_missing_repos.h - test suite for testing missing repos at clients device 2 | 3 | #ifndef _TEST_MISSING_REPOS_H //name of suite in caps with "_TEST_" prefix and "_H" postfix 4 | #define _TEST_MISSING_REPOS_H // 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../src/common/detect_missing_repos.h" 11 | 12 | Suite* missing_repos_suite(void); 13 | 14 | void clean_run(); 15 | void one_repo_missing(); 16 | void missing_file(); 17 | 18 | #endif -------------------------------------------------------------------------------- /tests/test_params.c: -------------------------------------------------------------------------------- 1 | //test_params.h - suite for testing parameters parsing 2 | 3 | #include "test_params.h" 4 | 5 | START_TEST(test_params) 6 | { 7 | ssds_gc_init(); 8 | 9 | /*CLIENT FUNCTIONS TESTING*/ 10 | /*test 1*/no_parameters(); 11 | /*test 2*/install(); 12 | /*test 3*/both_install_and_chkdep(); 13 | //failing: says no command provided [line 85], 14 | // while it should be both commands [line 88] 15 | /*test 4*/no_command_provided(); 16 | 17 | ssds_gc_cleanup(); 18 | } 19 | END_TEST 20 | 21 | Suite* params_suite(void) 22 | { 23 | Suite* s = suite_create("params"); 24 | TCase* tc = tcase_create("Main"); 25 | tcase_add_test(tc, test_params); 26 | suite_add_tcase(s, tc); 27 | return s; 28 | } 29 | 30 | void no_parameters() 31 | { 32 | ParamOptsCl* params = init_params_cl(); 33 | char *argv_tst[1] = {"./rds-client"}; 34 | 35 | int ret = parse_params_cl(1, argv_tst, params); 36 | fail_if(ret != 2); 37 | 38 | free_params_cl(params); 39 | return; 40 | } 41 | 42 | void install() 43 | { 44 | ParamOptsCl* params = init_params_cl(); 45 | char *argv_tst[3] = {"./rds-client", "--install", "emacs"}; 46 | 47 | int ret = parse_params_cl(3, argv_tst, params); 48 | //printf("ret is %d, command is %d\n", ret, params->command); 49 | fail_if(params->command != -1); 50 | fail_if(ret != 0); 51 | 52 | //free_params_cl(params); 53 | return; 54 | } 55 | 56 | void both_install_and_chkdep() 57 | { 58 | ParamOptsCl* params = init_params_cl(); 59 | char *argv_tst[5] = {"./rds-client", "--install", "emacs", "--chkdep", "qwe"}; 60 | 61 | int ret = parse_params_cl(5, argv_tst, params); 62 | //printf("ret is %d, command is %d, pkg_count is %d\n", ret, params->command, params->pkg_count); 63 | fail_if(ret != -1); 64 | 65 | free_params_cl(params); 66 | return; 67 | } 68 | 69 | void no_command_provided() 70 | { 71 | ParamOptsCl* params = init_params_cl(); 72 | char *argv_tst[3] = {"./rds-client", "emacs", "qwe"}; 73 | 74 | int ret = parse_params_cl(3, argv_tst, params); 75 | //printf("ret is %d, command is %d, pkg_count is %d\n", ret, params->command, params->pkg_count); 76 | fail_if(ret != 3); 77 | 78 | free_params_cl(params); 79 | return; 80 | } 81 | 82 | -------------------------------------------------------------------------------- /tests/test_params.h: -------------------------------------------------------------------------------- 1 | //test_params.h - suite for testing parameters parsing 2 | 3 | #ifndef _TEST_PARAMS_H 4 | #define _TEST_PARAMS_H 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | #include "../src/common/params.h" 11 | #include "../src/common/mem_management.h" 12 | 13 | Suite* params_suite(void); 14 | 15 | void no_parameters(); 16 | void install(); 17 | void both_install_and_chkdep(); 18 | void no_command_provided(); 19 | 20 | #endif -------------------------------------------------------------------------------- /tests/test_template.c: -------------------------------------------------------------------------------- 1 | //test_template.c - simple test suite template 2 | 3 | #include "test_template.h" 4 | 5 | START_TEST(test_template) //name of suite with "test_" prefix 6 | { 7 | fail_if(1 == 2); //your testing code 8 | } 9 | END_TEST 10 | 11 | Suite* template_suite(void) //name of suite with "_suite" postfix 12 | { 13 | Suite* s = suite_create("template"); //name of suite 14 | TCase* tc = tcase_create("Main"); 15 | tcase_add_test(tc, test_template); //name of suite with "test_" prefix 16 | suite_add_tcase(s, tc); 17 | return s; 18 | } 19 | 20 | //don't forget to add name of your .c test file to tests/CMakeLists.txt (line 6) -------------------------------------------------------------------------------- /tests/test_template.h: -------------------------------------------------------------------------------- 1 | //test_template.h - simple test suite template 2 | 3 | #ifndef _TEST_TEMPLATE_H //name of suite in caps with "_TEST_" prefix and "_H" postfix 4 | #define _TEST_TEMPLATE_H // 5 | 6 | #include 7 | #include 8 | #include 9 | 10 | Suite* template_suite(void); //name of suite with "_suite" postfix 11 | 12 | #endif --------------------------------------------------------------------------------