kiss.c (6307B)
1 #define _BSD_SOURCE 2 3 #include <dirent.h> 4 #include <fnmatch.h> 5 #include <stdlib.h> 6 #include <stdio.h> 7 #include <string.h> 8 9 #include "common.h" 10 #include "pkg.h" 11 #include "alt.h" 12 #include "util.h" 13 14 #include <stdint.h> 15 #include "sha256.h" 16 17 char *argv0; 18 19 void 20 kiss_alt() 21 { 22 struct alt_t alts[ALT_MAX]; 23 memset(alts, 0, sizeof(alts)); 24 alt_load(alts); 25 26 for (int i = 0; alts[i].name[0] != '\0'; i++) 27 printf("%s %s\n", alts[i].name, alts[i].path); 28 } 29 30 void 31 kiss_alt_swap(char *name, char *path) 32 { 33 struct alt_t alt; 34 memset(&alt, 0, sizeof(alt)); 35 36 if (strlen(name) >= PKG_NAME_MAX) 37 die("%s: %s is too long of a name", __func__, name); 38 39 if (strlen(path) >= PATH_LEN) 40 die("%s: %s is too long of a path", __func__, path); 41 42 strcpy(alt.name, name); 43 strcpy(alt.path, path); 44 45 if (alt_exists(&alt) != 0) 46 die("%s: %s does not have alternative %s", __func__, name, path); 47 48 alt_swap(&alt); 49 } 50 51 void 52 kiss_download_names(char *kiss_path, char *names[], int len) 53 { 54 struct source_t sources[PKG_SOURCES_MAX]; 55 memset(sources, 0, sizeof(sources)); 56 char *repo, kp[KISS_PATH_MAX], path[PATH_LEN]; 57 58 if (strlen(kiss_path) >= KISS_PATH_MAX) 59 die("%s: KISS_PATH too long", __func__); 60 61 /* TODO put names in linked list to make O(n) instead of O(n^2) */ 62 for (int i = 0; i < len; i++) { 63 /* iterate through KISS_PATH */ 64 memccpy(kp, kiss_path, '\0', strlen(kiss_path)); 65 66 if ((repo = strtok(kp, ":")) == NULL) 67 die("Invalid KISS_PATH."); 68 69 do { 70 if (pkg_exists(repo, names[i], path)) { 71 pkg_sources(repo, names[i], sources); 72 pkg_retrieve(sources); 73 break; 74 } 75 } while ((repo = strtok(NULL, ":")) != NULL); 76 } 77 } 78 79 void 80 kiss_install_names(char *kiss_path, char *names[], int len) 81 { 82 char *repo, kp[KISS_PATH_MAX], path[PATH_LEN], binpath[PATH_LEN]; 83 84 if (strlen(kiss_path) >= KISS_PATH_MAX) 85 die("%s: KISS_PATH too long", __func__); 86 87 pkg_install(names[0]); 88 } 89 90 void 91 kiss_checksum_names(char *kiss_path, char *names[], int len) 92 { 93 char *repo, kp[KISS_PATH_MAX], path[PATH_LEN]; 94 struct source_t sources[64]; 95 96 if (strlen(kiss_path) >= KISS_PATH_MAX) 97 die("%s: KISS_PATH too long", __func__); 98 99 for (int i = 0; i < len; i++) { 100 /* iterate through KISS_PATH */ 101 memccpy(kp, kiss_path, '\0', strlen(kiss_path)); 102 103 if ((repo = strtok(kp, ":")) == NULL) 104 die("Invalid KISS_PATH."); 105 106 do { 107 if (pkg_exists(repo, names[i], path)) { 108 memset(sources, 0, sizeof(sources)); 109 pkg_sources(repo, names[i], sources); 110 pkg_retrieve(sources); 111 pkg_checksums_gen(repo, names[i], sources); 112 break; 113 } 114 } while ((repo = strtok(NULL, ":")) != NULL); 115 } 116 } 117 118 void 119 kiss_list_all() 120 { 121 DIR *db; 122 char pkgs[PKG_COUNT_MAX][PKG_NAME_MAX]; 123 char ver[PKG_VERSION_MAX]; 124 125 if ((db = opendir(KISS_INSTALLED)) == NULL) 126 die("couldn't open package database:"); 127 128 int pkgcount = 0; 129 for (struct dirent *pkg = readdir(db); pkg != NULL; pkg = readdir(db)) { 130 if (pkg->d_type != DT_DIR || pkg->d_name[0] == '.') 131 continue; 132 133 if (strlen(pkg->d_name) >= PKG_NAME_MAX) { 134 closedir(db); 135 die("kiss_list: '%s' is too long of a package name", pkg->d_name); 136 } 137 138 strcpy(pkgs[pkgcount], pkg->d_name); 139 140 pkgcount++; 141 if (pkgcount > PKG_COUNT_MAX) { 142 closedir(db); 143 die("kiss_list: too many packages to list!"); 144 } 145 } 146 closedir(db); 147 qsort(pkgs, pkgcount, LEN(pkgs[0]), strcmpcb); 148 149 for (int i = 0; i < pkgcount; i++) { 150 pkg_version(KISS_INSTALLED, pkgs[i], ver); 151 printf("%s %s", pkgs[i], ver); 152 } 153 } 154 155 void 156 kiss_list_names(char *names[], int len) 157 { 158 char ver[PKG_VERSION_MAX]; 159 160 for (; len > 0; names++, len--) { 161 pkg_version(KISS_INSTALLED, *names, ver); 162 printf("%s %s", *names, ver); 163 } 164 } 165 166 void 167 kiss_remove_names(char *names[], int len) 168 { 169 for (int i = 0; i < len; i++) 170 pkg_remove(names[i]); 171 } 172 173 void 174 kiss_search(const char *kiss_path, char *pattern) 175 { 176 char *repo, path[KISS_PATH_MAX], pkgs[PKG_COUNT_MAX][PKG_NAME_MAX]; 177 int pkgcount; 178 179 if (strlen(kiss_path) >= KISS_PATH_MAX) 180 die("%s: KISS_PATH too long", __func__); 181 182 memccpy(path, kiss_path, '\0', strlen(kiss_path)); 183 184 if ((repo = strtok(path, ":")) == NULL) 185 die("Invalid KISS_PATH."); 186 187 /* iterate through KISS_PATH */ 188 do { 189 /* clear pkgs array */ 190 for (int i = 0; i < PKG_COUNT_MAX; i++) 191 pkgs[i][0] = '\0'; 192 193 pkgcount = pkg_match(repo, pkgs, pattern); 194 195 for (int i = 0; i < pkgcount; i++) { 196 printf("%s/%s\n", repo, pkgs[i]); 197 } 198 } while ((repo = strtok(NULL, ":")) != NULL); 199 200 repo = KISS_INSTALLED; 201 for (int i = 0; i < PKG_COUNT_MAX; i++) 202 pkgs[i][0] = '\0'; 203 204 pkgcount = pkg_match(repo, pkgs, pattern); 205 206 for (int i = 0; i < pkgcount; i++) { 207 printf("%s/%s\n", repo, pkgs[i]); 208 } 209 } 210 211 int 212 main(int argc, char *argv[]) 213 { 214 char *kiss_path; 215 216 argv0 = argv[0]; 217 if ((kiss_path = getenv("KISS_PATH")) == NULL) 218 die("KISS_PATH unset."); 219 puts(kiss_path); 220 221 if (argc < 2) 222 return 1; 223 224 if (strcmp(argv[1], "list") == 0) { 225 if (argv[2]) 226 kiss_list_names(&argv[2], argc-2); 227 else 228 kiss_list_all(); 229 } else if (strcmp(argv[1], "search") == 0 && argc > 2) { 230 kiss_search(kiss_path, argv[2]); 231 } else if (strcmp(argv[1], "download") == 0 && argc > 2) { 232 kiss_download_names(kiss_path, &argv[2], argc-2); 233 } else if (strcmp(argv[1], "checksum") == 0 && argc > 2) { 234 kiss_checksum_names(kiss_path, &argv[2], argc-2); 235 } else if (strcmp(argv[1], "remove") == 0 && argc > 2) { 236 kiss_remove_names(&argv[2], argc-2); 237 } else if (strcmp(argv[1], "install") == 0 && argc > 2) { 238 kiss_install_names(kiss_path, &argv[2], argc-2); 239 } else if (strcmp(argv[1], "alt") == 0) { 240 if (argc == 2) 241 kiss_alt(); 242 else if (argc == 4) 243 kiss_alt_swap(argv[2], argv[3]); 244 } 245 return 0; 246 }