cfg.c - rohrpost - A commandline mail client to change the world as we see it.
 (HTM) git clone git://r-36.net/rohrpost
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
       cfg.c (5892B)
       ---
            1 /*
            2  * Copy me if you can.
            3  * by 20h
            4  */
            5 
            6 #include <unistd.h>
            7 #include <stdio.h>
            8 #include <stdlib.h>
            9 #include <stdarg.h>
           10 #include <string.h>
           11 #include <strings.h>
           12 #include <errno.h>
           13 #include <libgen.h>
           14 #include <sys/stat.h>
           15 #include <sys/types.h>
           16 #include <dirent.h>
           17 #include <ctype.h>
           18 
           19 #include "ind.h"
           20 #include "arg.h"
           21 #include "llist.h"
           22 #include "path.h"
           23 #include "cfg.h"
           24 
           25 config_t *
           26 config_init(char *cfgn)
           27 {
           28         char *path;
           29         config_t *cfg;
           30 
           31         if (cfgn == NULL)
           32                 cfgn = "default";
           33 
           34         path = path_mkcfgfile(cfgn);
           35         cfg = config_read(path);
           36         if (cfg == NULL)
           37                 cfg = config_new();
           38         cfg->path = memdups(path);
           39         free(path);
           40 
           41         if (cfg->name == NULL) {
           42                 cfg->name = memdups("default");
           43         } else {
           44                 cfg->name = memdups(cfgn);
           45         }
           46 
           47         return cfg;
           48 }
           49 
           50 void
           51 config_default(char *cfgn)
           52 {
           53         char *path, *cwd;
           54         struct stat sbuf;
           55 
           56         cwd = getcwd(NULL, 0);
           57         if (cwd == NULL)
           58                 edie("getcwd");
           59 
           60         path = path_mkrppath(NULL);
           61         if (chdir(path) < 0)
           62                 edie("chdir");
           63         if (lstat("default", &sbuf) >= 0) {
           64                 if (remove("default") < 0)
           65                         edie("remove");
           66         }
           67         if (symlink(cfgn, "default") < 0)
           68                 edie("symlink");
           69 
           70         if (chdir(cwd) < 0)
           71                 edie("chdir");
           72 
           73         free(cwd);
           74         free(path);
           75 }
           76 
           77 void
           78 config_list(void)
           79 {
           80         char *path;
           81         struct dirent **dirlist;
           82         int ndir;
           83 
           84         path = path_mkrppath(NULL);
           85 
           86         ndir = scandir(path, &dirlist, NULL, alphasort);
           87         free(path);
           88         if (ndir < 0)
           89                 edie("scandir");
           90         for (--ndir; ndir >= 0; ndir--) {
           91                 if (!strcmp(dirlist[ndir]->d_name, "."))
           92                         continue;
           93                 if (!strcmp(dirlist[ndir]->d_name, ".."))
           94                         continue;
           95                 if (!strcmp(dirlist[ndir]->d_name, "default"))
           96                         continue;
           97                 printf("%s\n", dirlist[ndir]->d_name);
           98         }
           99         free(dirlist);
          100 }
          101 
          102 void
          103 config_stop(config_t *cfg)
          104 {
          105         char *path;
          106 
          107         if (cfg->changed) {
          108                 path = path_mkcfgfile(cfg->name);
          109                 if (config_write(cfg, NULL) == NULL)
          110                         edie("config_write");
          111                 free(path);
          112         }
          113 
          114         config_free(cfg);
          115 }
          116 
          117 llistelem_t *
          118 config_checkget(config_t *cfg, char *key)
          119 {
          120         llistelem_t *result;
          121 
          122         result = config_get(cfg, key);
          123         if (result == NULL)
          124                 die("config_checkget: %s not found in config.\n", key);
          125 
          126         return result;
          127 }
          128 
          129 char *
          130 config_getstr(config_t *cfg, char *key)
          131 {
          132         llistelem_t *selitem;
          133         char *rstr, *envval, *ukey;
          134         int i;
          135 
          136         /*
          137          * The environment is:
          138          *        RP${KEY}
          139          */
          140         ukey = smprintf("RP%s", key);
          141         for (i = 2; i < strlen(ukey); i++)
          142                 ukey[i] = (char)toupper(ukey[i]);
          143 
          144         envval = getenv(ukey);
          145         free(ukey);
          146         if (envval != NULL)
          147                 return memdups(envval);
          148 
          149         if (cfg == NULL)
          150                 return NULL;
          151 
          152         selitem = config_get(cfg, key);
          153         if (selitem != NULL && selitem->data != NULL) {
          154                 rstr = memdup(selitem->data, selitem->datalen+1);
          155         } else {
          156                 rstr = NULL;
          157         }
          158 
          159         return rstr;
          160 }
          161 
          162 char *
          163 config_checkgetstr(config_t *cfg, char *key)
          164 {
          165         char *rstr;
          166 
          167         rstr = config_getstr(cfg, key);
          168         if (rstr == NULL)
          169                 die("config_checkgetstr: %s not found in config.\n", key);
          170 
          171         return rstr;
          172 }
          173 
          174 void
          175 configprintelem(llistelem_t *elem, int onlydata)
          176 {
          177         if (onlydata) {
          178                 llistelem_printdata(elem);
          179         } else {
          180                 llistelem_print(elem);
          181         }
          182 }
          183 
          184 void
          185 configusage(char *argv0)
          186 {
          187         die("usage: %s [-hiqv] [-c cfg] [-e cfg|-l|key"
          188                         " [value]]|-d key|-s regex|-n]\n", argv0);
          189 }
          190 
          191 int
          192 configmain(int argc, char *argv[])
          193 {
          194         int status;
          195         char *key, *value, *cfgn, *def, *argv0;
          196         config_t *cfg;
          197         llist_t *results;
          198         llistelem_t *result, *elem;
          199 
          200         enum {
          201                 BEQUIET = 0x01,
          202                 ONLYDATA = 0x02,
          203                 DOLIST = 0x04,
          204                 DODELETE = 0x08,
          205                 DOSEARCH = 0x10,
          206                 DOINIT = 0x20,
          207                 DODEFAULT = 0x40,
          208                 DONAMECFG = 0x80
          209         };
          210 
          211         status = 0;
          212         key = NULL;
          213         value = NULL;
          214         cfgn = NULL;
          215         def = NULL;
          216 
          217         ARGBEGIN(argv0) {
          218         case 'c':
          219                 cfgn = EARGF(configusage(argv0));
          220                 break;
          221         case 'd':
          222                 status |= DODELETE;
          223                 break;
          224         case 'e':
          225                 def = ARGF();
          226                 status |= DODEFAULT;
          227                 break;
          228         case 'i':
          229                 status |= DOINIT;
          230                 break;
          231         case 'n':
          232                 status |= DONAMECFG;
          233                 break;
          234         case 'q':
          235                 status |= BEQUIET;
          236                 break;
          237         case 'v':
          238                 status |= ONLYDATA;
          239                 break;
          240         case 'l':
          241                 status |= DOLIST;
          242                 break;
          243         case 's':
          244                 status |= DOSEARCH;
          245                 break;
          246         default:
          247                 configusage(argv0);
          248         } ARGEND;
          249 
          250         if (status & DODEFAULT) {
          251                 if (def) {
          252                         config_default(def);
          253                         if (!(status & BEQUIET)) {
          254                                 printf("Default configuration set to '%s'.\n",
          255                                                 def);
          256                         }
          257                         return 0;
          258                 } else {
          259                         config_list();
          260                         return 0;
          261                 }
          262         }
          263 
          264         cfg = config_init(cfgn);
          265 
          266         if (status & DONAMECFG) {
          267                 if (cfg->name != NULL)
          268                         printf("%s\n", cfg->name);
          269                 return 0;
          270         }
          271 
          272         if (status & DOLIST) {
          273                 if (config_len(cfg) > 0) {
          274                         llist_sort(cfg->values);
          275                         forllist(cfg->values, elem)
          276                                 configprintelem(elem, status & ONLYDATA);
          277                 }
          278                 return 0;
          279         }
          280 
          281         if (argc > 0) {
          282                 key = argv[0];
          283                 if (argc > 1)
          284                         value = argv[1];
          285         } else {
          286                 configusage(argv0);
          287         }
          288 
          289         if (value != NULL) {
          290                 result = config_set(cfg, key, value);
          291                 if (!(status & BEQUIET))
          292                         configprintelem(result, status & ONLYDATA);
          293                 config_stop(cfg);
          294                 return 0;
          295         }
          296 
          297         if ((status & DOSEARCH) && !(status & DODELETE)) {
          298                 results = config_find(cfg, key);
          299                 if (results == NULL) {
          300                         if (!(status & BEQUIET))
          301                                 printf("No matching key found.\n");
          302                         return 1;
          303                 }
          304                 forllist(results, elem)
          305                         configprintelem(elem, status & ONLYDATA);
          306                 return 0;
          307         }
          308         if (status & DODELETE) {
          309                 if (status & DOSEARCH) {
          310                         results = config_find(cfg, key);
          311                         if (results == NULL) {
          312                                 if (!(status & BEQUIET))
          313                                         printf("No such key in config.\n");
          314                                 return 1;
          315                         }
          316 
          317                         forllist(results, elem)
          318                                 config_del(cfg, elem->key);
          319                         if (!(status & BEQUIET))
          320                                 printf("%d keys removed from config\n",
          321                                                 results->len);
          322                         config_stop(cfg);
          323                 } else {
          324                         result = config_del(cfg, key);
          325                         if (result == NULL) {
          326                                 if (!(status & BEQUIET))
          327                                         printf("Nothing deleted.\n");
          328                                 return 1;
          329                         } else {
          330                                 if (!(status & BEQUIET))
          331                                         printf("One key removed from "
          332                                                         "config.\n");
          333                                 config_stop(cfg);
          334                         }
          335                 }
          336                 return 0;
          337         }
          338 
          339         result = config_get(cfg, key);
          340         if (result == NULL) {
          341                 if (!(status & BEQUIET))
          342                         printf("No such key in config.\n");
          343                 return 1;
          344         }
          345         configprintelem(result, status & ONLYDATA);
          346 
          347         return 0;
          348 }
          349