nkiss

WIP
git clone git://git.nihaljere.xyz/nkiss
Log | Files | Refs

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 }