<html lang='en'>
<head>
<meta content='text/html; charset=utf-8' http-equiv='Content-Type'>
<title>
GitLab
</title>
</meta>
</head>
<style>
  img {
    max-width: 100%;
    height: auto;
  }
  p.details {
    font-style:italic;
    color:#777
  }
  .footer p {
    font-size:small;
    color:#777
  }
  pre.commit-message {
    white-space: pre-wrap;
  }
  .file-stats a {
    text-decoration: none;
  }
  .file-stats .new-file {
    color: #090;
  }
  .file-stats .deleted-file {
    color: #B00;
  }
</style>
<body>
<div class='content'>
<h3>Andrew Price pushed to branch master at <a href="https://projects.sucs.org/arthur/mw">Justin Mitchell / mw</a></h3>
<h4>
Commits:
</h4>
<ul>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/f9b15ca6bdde0489bfed09fcf03d16d4e40f3f0e">f9b15ca6</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:54:05Z</i>
</div>
<pre class='commit-message'>Consolidate update_user functions

Move it from src/{web,}client/user.[ch] into src/user.c and simplify
with pwrite(2).</pre>
</li>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/665110bd5c80a88a39bf0ba6e17e569c6d17147d">665110bd</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:54:32Z</i>
</div>
<pre class='commit-message'>Consolidate is_old functions

Dedupe it into src/user.c where it fits and rewrite it in terms of a new
user_find_name function which will be used more later.</pre>
</li>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/e40b5341a1f18a45ab67fa93dc4d63ae01810383">e40b5341</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:54:49Z</i>
</div>
<pre class='commit-message'>Don't use FOLDERFILE outside of folders.c</pre>
</li>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/f57942bac6cbdaf5b3988b25440b75c18b7fed7c">f57942ba</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:55:02Z</i>
</div>
<pre class='commit-message'>Don't use USERFILE outside of user.c</pre>
</li>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/62d5bc948726c2a1009386483a320747840976c9">62d5bc94</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:55:12Z</i>
</div>
<pre class='commit-message'>Make the config system completely generic

Move the bits which specified the default server options and config file
paths out of the config system. Add some bits to simplify constructing an
array of default config options.</pre>
</li>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/79e884d58d39fcf270e568032928e09d25a1c6ca">79e884d5</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:55:24Z</i>
</div>
<pre class='commit-message'>Move the config system to src/

Now the client can use it too if necessary.</pre>
</li>
<li>
<strong><a href="https://projects.sucs.org/arthur/mw/commit/bfb79d904743ef25cefa37ca59687eca790c9a2d">bfb79d90</a></strong>
<div>
<span>by Andrew Price</span>
<i>at 2015-10-21T12:55:35Z</i>
</div>
<pre class='commit-message'>Add the built files in src/utils/ to .gitignore</pre>
</li>
</ul>
<h4>18 changed files:</h4>
<ul>
<li class='file-stats'>
<a href='#diff-0'>
.gitignore
</a>
</li>
<li class='file-stats'>
<a href='#diff-1'>
src/client/mod.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-2'>
src/client/user.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-3'>
src/client/user.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-4'>
src/folders.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-5'>
src/folders.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-6'>
src/server/servercfg.c

src/mwcfg.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-7'>
<span class='new-file'>
+
src/mwcfg.h
</span>
</a>
</li>
<li class='file-stats'>
<a href='#diff-8'>
src/server/mwserv.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-9'>
<span class='deleted-file'>

src/server/servercfg.h
</span>
</a>
</li>
<li class='file-stats'>
<a href='#diff-10'>
src/user.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-11'>
src/user.h
</a>
</li>
<li class='file-stats'>
<a href='#diff-12'>
src/utils/clean_users.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-13'>
src/utils/del_user.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-14'>
src/utils/fixuser.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-15'>
src/utils/listuser.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-16'>
src/webclient/import.c
</a>
</li>
<li class='file-stats'>
<a href='#diff-17'>
src/webclient/import.h
</a>
</li>
</ul>
<h4>Changes:</h4>
<li id='diff-0'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-0'>
<strong>
.gitignore
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/.gitignore
</span><span style="color: #000000;background-color: #ddffdd">+++ b/.gitignore
</span><span style="color: #aaaaaa">@@ -15,6 +15,10 @@ src/mwserv
</span> src/mwtest
 src/nonce.h
 src/server/mwserv
<span style="color: #000000;background-color: #ddffdd">+src/utils/del_user
+src/utils/fixuser
+src/utils/listuser
+src/utils/sizes
</span> src/webclient/mwpoll
 mozjs/build
 mozjs/installroot
</code></pre>

<br>
</li>
<li id='diff-1'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-1'>
<strong>
src/client/mod.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/mod.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/mod.c
</span><span style="color: #aaaaaa">@@ -98,13 +98,16 @@ void moderate(void)
</span>   int f_file;
        int tmpindex,tmptext;
 
-       if ((f_file=open(FOLDERFILE,O_RDWR))<0)
-               {perror(FOLDERFILE);exit(-1);}
<span style="color: #000000;background-color: #ddffdd">+        f_file=openfolderfile(O_RDWR);
+       if (f_file < 0)
+               exit(-1);
+
</span>   while (get_folder_entry(f_file,&fold))
        {
-       sprintf(oldpath,"%s/%s%s%s",STATEDIR,fold.name,INDEX_END,MOD_END);
-       if (!access(oldpath,00))
-       {
<span style="color: #000000;background-color: #ddffdd">+                sprintf(oldpath,"%s/%s%s%s",STATEDIR,fold.name,INDEX_END,MOD_END);
+               if (access(oldpath,00))
+                       continue;
+
</span>           printf(_("Changing to folder %s\n"),fold.name);
                /* move the unmoderated messages to a temporary file */
                sprintf(fullpath,"%s/%s%s%s",STATEDIR,fold.name,INDEX_END,".tmp");
<span style="color: #aaaaaa">@@ -165,7 +168,6 @@ void moderate(void)
</span>           sprintf(fullpath,"%s/%s%s%s",STATEDIR,fold.name,TEXT_END,".tmp");
                if (unlink(fullpath)) {perror(fullpath);exit(-1);}
        }
-       }
        close(f_file);
 }
 
</code></pre>

<br>
</li>
<li id='diff-2'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-2'>
<strong>
src/client/user.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/user.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/user.c
</span><span style="color: #aaaaaa">@@ -47,18 +47,6 @@ char *getmylogin(void)
</span>           return(pw->pw_name);
 }
 
-void update_user(struct person *record, int32_t userposn)
-{
-       int outfile;
-
-       outfile=userdb_open(O_RDWR|O_CREAT);
-       /*Lock_File(outfile); */
-       lseek(outfile,userposn,0);
-       write(outfile,record,sizeof(*record));
-       /*Unlock_File(outfile); */
-       close(outfile);
-}
-
 static int old_usr(struct person *usr)
 {
        char salt[3],passwd[PASSWDSIZE];
<span style="color: #aaaaaa">@@ -335,21 +323,6 @@ static int new_usr(struct person *usr, char *name, int32_t *userposn)
</span>   else return(false);
 }
 
-int is_old(struct person *usr, const char *name, int32_t *userposn)
-{
-       int file,found=false;
-
-       if (access(USERFILE,00)) return(false);
-       file=userdb_open(O_RDONLY);
-       while (!found && get_person(file,usr))
-               if (stringcmp(usr->name,name,-1) && !u_del(usr->status))
-                       found=true;
-       if (found)
-               *userposn=lseek(file,0,1)-sizeof(struct person);
-       close(file);
-       return(found);
-}
-
 void login_ok(struct person *usr, int32_t *userposn, int *autochat)
 {
        /* main function */
</code></pre>

<br>
</li>
<li id='diff-3'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-3'>
<strong>
src/client/user.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/client/user.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/client/user.h
</span><span style="color: #aaaaaa">@@ -8,13 +8,11 @@ struct person * user_get(const char * name);
</span> char *getmylogin(void);
 void get_login(char *name, int autochat);
 int get_person(int file, struct person *tmp);
-void update_user(struct person *record, int32_t userposn);
 void list_users(int newonly);
 void list_users_since(long date);
 void login_ok(struct person *usr, int32_t *userposn, int *autochat);
 void strip_name(char *string);
 void pick_salt(char *salt);
 void search(const char *args, const char *ptr);
-int is_old(struct person *usr, const char *name, int32_t *userposn);
 
 #endif
</code></pre>

<br>
</li>
<li id='diff-4'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-4'>
<strong>
src/folders.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/folders.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/folders.c
</span><span style="color: #aaaaaa">@@ -8,6 +8,8 @@
</span> #include "folders.h"
 #include "files.h"
 
<span style="color: #000000;background-color: #ddffdd">+#define FOLDERFILE  STATEDIR"/folders.bb"
+
</span> int openfolderfile(int mode)
 {
        int x;
</code></pre>

<br>
</li>
<li id='diff-5'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-5'>
<strong>
src/folders.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/folders.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/folders.h
</span><span style="color: #aaaaaa">@@ -3,7 +3,6 @@
</span> 
 #include <stdint.h>
 
-#define FOLDERFILE  STATEDIR"/folders.bb"
 #define FOLNAMESIZE    10      /* length of folder names */
 #define TOPICSIZE      30      /* length of the topic of the folder */
 
</code></pre>

<br>
</li>
<li id='diff-6'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-6'>
<strong>
src/server/servercfg.c
</strong>

<strong>
src/mwcfg.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/servercfg.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/mwcfg.c
</span><span style="color: #aaaaaa">@@ -9,13 +9,39 @@
</span> #include <unistd.h>
 #include <jansson.h>
 
-#include <util.h>
-#include "servercfg.h"
<span style="color: #000000;background-color: #ddffdd">+#include "mwcfg.h"
</span> 
 json_t *cfg;
 
-int cfg_init_defaults(void)
<span style="color: #000000;background-color: #ddffdd">+static int cfg_new_opt_int(const struct cfg_default_opt *o)
</span> {
<span style="color: #000000;background-color: #ddffdd">+        json_t *val = json_integer(o->o_val.integer);
+       return json_object_set_new(cfg, o->o_name, val);
+}
+
+static int cfg_new_opt_bool(const struct cfg_default_opt *o)
+{
+       json_t *val = o->o_val.boolean ? json_true() : json_false();
+       return json_object_set_new(cfg, o->o_name, val);
+}
+
+static int cfg_new_opt_str(const struct cfg_default_opt *o)
+{
+       json_t *val = json_string(o->o_val.string);
+       return json_object_set_new(cfg, o->o_name, val);
+}
+
+typedef int (*cfg_new_opt_fn)(const struct cfg_default_opt *);
+
+static const cfg_new_opt_fn cfg_new_opt_fns[] = {
+       [CFG_OPT_INT] = cfg_new_opt_int,
+       [CFG_OPT_BOOL] = cfg_new_opt_bool,
+       [CFG_OPT_STR] = cfg_new_opt_str
+};
+
+int cfg_init_defaults(const struct cfg_default_opt *dft_opts)
+{
+       const struct cfg_default_opt *dopt;
</span>   int ret;
 
        cfg = json_object();
<span style="color: #aaaaaa">@@ -23,18 +49,24 @@ int cfg_init_defaults(void)
</span>           perror("Failed to create default config object");
                return 1;
        }
-       /* README: Config options must be set here so that they will be treated
-          as valid config options on later changes by config files, command
-          line options, etc. */
-       ret = json_object_set_new(cfg, "foreground", json_false())
-       ||    json_object_set_new(cfg, "port", json_integer(9999));
<span style="color: #000000;background-color: #ddffdd">+        for (dopt = dft_opts; dopt && dopt->o_type != CFG_OPT_NULL; dopt++) {
+               cfg_new_opt_fn fn;
</span> 
-       if (ret != 0) {
-               fprintf(stderr, "Failed to build default config items\n");
-               json_decref(cfg);
-               return 1;
<span style="color: #000000;background-color: #ddffdd">+                fn = cfg_new_opt_fns[dopt->o_type];
+               if (fn == NULL) {
+                       fprintf(stderr, "Invalid config option type: %d\n", dopt->o_type);
+                       goto err_decref;
+               }
+               ret = fn(dopt);
+               if (ret != 0) {
+                       fprintf(stderr, "Failed to build default config items\n");
+                       goto err_decref;
+               }
</span>   }
        return 0;
<span style="color: #000000;background-color: #ddffdd">+err_decref:
+       json_decref(cfg);
+       return 1;
</span> }
 
 static const char *jsontype_to_str[] = {
<span style="color: #aaaaaa">@@ -99,7 +131,13 @@ static int cfg_obj_merge(json_t *obj)
</span>   return ret;
 }
 
-static int cfg_load_file(const char *path, int skip_if_missing)
<span style="color: #000000;background-color: #ddffdd">+/**
+ * Returns:
+ * >0 if the path is not found or is not accessible
+ * <0 if another error occurs
+ *  0 if the path was successfully loaded
+ **/
+int cfg_load(const char *path)
</span> {
        json_error_t err;
        json_t *obj;
<span style="color: #aaaaaa">@@ -109,7 +147,7 @@ static int cfg_load_file(const char *path, int skip_if_missing)
</span> 
        fd = open(path, O_RDONLY);
        if (fd < 0) {
-               if ((errno == EACCES || errno == ENOENT) && skip_if_missing)
<span style="color: #000000;background-color: #ddffdd">+                if ((errno == EACCES || errno == ENOENT))
</span>                   return 1;
                fprintf(stderr, "Failed to open config file '%s': %s\n", path, strerror(errno));
                return -1;
<span style="color: #aaaaaa">@@ -130,7 +168,7 @@ static int cfg_load_file(const char *path, int skip_if_missing)
</span>   ret = cfg_obj_validate(obj);
        if (ret != 0)
                return -1;
-
<span style="color: #000000;background-color: #ddffdd">+        printf("Loading configuration from '%s'\n", path);
</span>   ret = cfg_obj_merge(obj);
        json_decref(obj);
        if (ret != 0)
<span style="color: #aaaaaa">@@ -138,37 +176,6 @@ static int cfg_load_file(const char *path, int skip_if_missing)
</span>   return 0;
 }
 
-static int cfg_load_default_path(void)
-{
-       AUTOFREE_BUFFER homeconf = NULL;
-       const char *homedir;
-       const char *etcconf;
-       int ret;
-
-       homedir = getenv("HOME");
-       if (homedir) {
-               ret = asprintf(&homeconf, "%s/.mwserv.conf", homedir);
-               if (ret > 0) {
-                       ret = cfg_load_file(homeconf, 1);
-                       if (ret <= 0)
-                               return ret;
-               }
-       }
-       etcconf = "/etc/mwserv.conf";
-       ret = cfg_load_file(etcconf, 1);
-       if (ret <= 0)
-               return ret;
-       return 0;
-}
-
-int cfg_load(const char *cfg_file)
-{
-       if (cfg_file == NULL)
-               return cfg_load_default_path();
-
-       return cfg_load_file(cfg_file, 0);
-}
-
 void cfg_dump(FILE *f)
 {
        if (json_dumpf(cfg, f, JSON_PRESERVE_ORDER|JSON_INDENT(1)))
</code></pre>

<br>
</li>
<li id='diff-7'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-7'>
<strong>
src/mwcfg.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- /dev/null
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/mwcfg.h
</span><span style="color: #aaaaaa">@@ -0,0 +1,40 @@
</span><span style="color: #000000;background-color: #ddffdd">+#ifndef MWCFG_H
+#define MWCFG_H
+
+struct cfg_default_opt {
+#define CFG_OPT_NULL (0)
+#define CFG_OPT_INT  (1)
+#define CFG_OPT_BOOL (2)
+#define CFG_OPT_STR  (3)
+       int o_type;
+       const char *o_name;
+       union {
+#define _OPTTYP_INT integer
+               long integer;
+#define _OPTTYP_BOOL boolean
+               int boolean;
+#define _OPTTYP_STR string
+               const char *string;
+       } o_val;
+};
+
+#define _OPTTYP(t) _OPTTYP_##t
+
+#define CFG_OPT(type, name, value) { \
+       .o_type = CFG_OPT_##type, \
+       .o_name = name, \
+       .o_val._OPTTYP(type) = value }
+#define CFG_END { NULL, NULL, {0} }
+
+extern int cfg_init_defaults(const struct cfg_default_opt *dft_opts);
+extern int cfg_load(const char *cfg_file);
+extern void cfg_dump(FILE *f);
+
+extern int cfg_set_int(const char *keyname, long int_val);
+extern int cfg_set_bool(const char *keyname, int bool_val);
+extern int cfg_set_string(const char *keyname, const char *str_val);
+
+extern int cfg_get_bool(const char *keyname);
+extern long cfg_get_int(const char *keyname);
+extern const char *cfg_get_string(const char *keyname);
+#endif /* MWCFG_H */
</span></code></pre>

<br>
</li>
<li id='diff-8'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-8'>
<strong>
src/server/mwserv.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/mwserv.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/server/mwserv.c
</span><span style="color: #aaaaaa">@@ -9,8 +9,10 @@
</span> #include <string.h>
 #include <time.h>
 #include <socket.h>
<span style="color: #000000;background-color: #ddffdd">+
+#include <util.h>
+#include <mwcfg.h>
</span> #include "servsock.h"
-#include "servercfg.h"
 
 /* unused, but necessary to link other util functions */
 int idle = 0;
<span style="color: #aaaaaa">@@ -18,6 +20,7 @@ int internet = 0;
</span> int userposn = 0;
 
 #define MWUSER "mw"
<span style="color: #000000;background-color: #ddffdd">+#define MWSERVCONF "mwserv.conf"
</span> 
 time_t uptime = 0;
 
<span style="color: #aaaaaa">@@ -32,13 +35,50 @@ static void usage(char *name)
</span>          "\n", name);
 }
 
<span style="color: #000000;background-color: #ddffdd">+/**
+ * Config options must be set here so that the config system will recognise
+ * them. It also uses them to validate the types of the overrides specified in
+ * config files. Any options found in config files that are not listed here
+ * will be ignored (non-fatally).
+ **/
+static const struct cfg_default_opt defcfgs[] = {
+       CFG_OPT(BOOL, "foreground", 0),
+       CFG_OPT(INT, "port", 9999),
+       CFG_END
+};
+
+static int config_init(void)
+{
+       AUTOFREE_BUFFER homeconf = NULL;
+       const char *homedir;
+       int ret;
+
+       ret = cfg_init_defaults(defcfgs);
+       if (ret)
+               return ret;
+
+       homedir = getenv("HOME");
+       if (homedir) {
+               ret = asprintf(&homeconf, "%s/."MWSERVCONF, homedir);
+               if (ret > 0) {
+                       ret = cfg_load(homeconf);
+                       if (ret <= 0)
+                               return ret;
+               }
+       }
+       ret = cfg_load("/etc/"MWSERVCONF);
+       if (ret <= 0)
+               return ret;
+       return 0;
+}
+
</span> static int getconfig(int argc, char **argv)
 {
        int c;
        int ret;
<span style="color: #000000;background-color: #ddffdd">+        long num;
</span>   int optidx = 0;
        int printcfg = 0;
-       long num;
        static struct option loptspec[] = {
                {"config",       required_argument, 0, 'c'},
                {"foreground",   no_argument,       0, 'f'},
<span style="color: #aaaaaa">@@ -48,13 +88,9 @@ static int getconfig(int argc, char **argv)
</span>           {0, 0, 0, 0}
        };
 
-       ret = cfg_init_defaults();
-       if (ret)
-               return ret;
-
-       ret = cfg_load(NULL);
<span style="color: #000000;background-color: #ddffdd">+        ret = config_init();
</span>   if (ret != 0)
-               return 1;
<span style="color: #000000;background-color: #ddffdd">+                return ret;
</span> 
        while (1) {
                c = getopt_long(argc, argv, "c:fhPp:", loptspec, &optidx);
</code></pre>

<br>
</li>
<li id='diff-9'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-9'>
<strong>
src/server/servercfg.h
</strong>
deleted
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/server/servercfg.h
</span><span style="color: #000000;background-color: #ddffdd">+++ /dev/null
</span><span style="color: #aaaaaa">@@ -1,16 +0,0 @@
</span>-#ifndef SERVERCFG_H
-#define SERVERCFG_H
-
-extern int cfg_load(const char *cfg_file);
-extern int cfg_init_defaults(void);
-extern void cfg_dump(FILE *f);
-
-extern int cfg_set_int(const char *keyname, long int_val);
-extern int cfg_set_bool(const char *keyname, int bool_val);
-extern int cfg_set_string(const char *keyname, const char *str_val);
-
-extern int cfg_get_bool(const char *keyname);
-extern long cfg_get_int(const char *keyname);
-extern const char *cfg_get_string(const char *keyname);
-
-#endif /* SERVERCFG_H */
</code></pre>

<br>
</li>
<li id='diff-10'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-10'>
<strong>
src/user.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/user.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/user.c
</span><span style="color: #aaaaaa">@@ -2,9 +2,13 @@
</span> #include <stdio.h>
 #include <stdlib.h>
 #include <unistd.h>
<span style="color: #000000;background-color: #ddffdd">+#include <strings.h>
</span> 
 #include "user.h"
 #include "files.h"
<span style="color: #000000;background-color: #ddffdd">+#include "perms.h"
+
+#define USERFILE STATEDIR"/users.bb"
</span> 
 int userdb_open(int flags)
 {
<span style="color: #aaaaaa">@@ -28,6 +32,15 @@ void userdb_write(struct person *record, int32_t *userposn)
</span>   close(outfile);
 }
 
<span style="color: #000000;background-color: #ddffdd">+void update_user(struct person *record, int32_t userposn)
+{
+       int outfile;
+
+       outfile = userdb_open(O_WRONLY|O_CREAT);
+       pwrite(outfile, record, sizeof(*record), userposn);
+       close(outfile);
+}
+
</span> void fetch_user(struct person *record, int32_t userposn)
 {
         int outfile;
<span style="color: #aaaaaa">@@ -38,3 +51,35 @@ void fetch_user(struct person *record, int32_t userposn)
</span>         close(outfile);
 }
 
<span style="color: #000000;background-color: #ddffdd">+static int user_find_name(const char *name, struct person *user, int32_t *userposn, int *found)
+{
+       ssize_t bytes;
+       int fd = open(USERFILE, O_RDONLY);
+
+       if (fd < 0)
+               return 1;
+
+       *found = 0;
+       *userposn = 0;
+       while((bytes = read(fd, user, sizeof(*user)))) {
+               if (bytes != sizeof(*user)) {
+                       perror(USERFILE);
+                       close(fd);
+                       return 1;
+               }
+               *userposn += sizeof(*user);
+               if (!strcasecmp(user->name, name) && !u_del(user->status)) {
+                       *found = 1;
+                       break;
+               }
+       }
+       close(fd);
+       return 0;
+}
+
+int is_old(struct person *usr, const char *name, int32_t *userposn)
+{
+        int found;
+
+       return !user_find_name(name, usr, userposn, &found) && found;
+}
</span></code></pre>

<br>
</li>
<li id='diff-11'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-11'>
<strong>
src/user.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/user.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/user.h
</span><span style="color: #aaaaaa">@@ -3,8 +3,6 @@
</span> 
 #include <stdint.h>
 
-#define USERFILE STATEDIR"/users.bb"
-
 #define NAMESIZE       16      /* username */
 #define PASSWDSIZE     20      /* password (after encryption) */
 #define REALNAMESIZE   30      /* real name */
<span style="color: #aaaaaa">@@ -53,6 +51,7 @@ struct person
</span> extern int userdb_open(int flags);
 extern void userdb_write(struct person *record, int32_t *userposn);
 extern void fetch_user(struct person *record, int32_t userposn);
-
<span style="color: #000000;background-color: #ddffdd">+extern void update_user(struct person *record, int32_t userposn);
+extern int is_old(struct person *usr, const char *name, int32_t *userposn);
</span> 
 #endif
</code></pre>

<br>
</li>
<li id='diff-12'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-12'>
<strong>
src/utils/clean_users.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/utils/clean_users.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/utils/clean_users.c
</span><span style="color: #aaaaaa">@@ -4,26 +4,30 @@
</span> int internet=0;
 struct person user;
 
-main()
<span style="color: #000000;background-color: #ddffdd">+int main(int argc, char **argv)
</span> {
-       char oldpath[1024];
-       char newpath[1024];
<span style="color: #000000;background-color: #ddffdd">+        const char *oldpath;
+       char *newpath;
</span>   int newfile,oldfile;
        char buff[20];
        long tt=0l;
 
-       sprintf(oldpath,"%s/%s",HOMEPATH,USERFILE);
-       sprintf(newpath,"%s.new",oldpath);
<span style="color: #000000;background-color: #ddffdd">+        if (argc != 2) {
+               fprintf(stderr, "Usage: %s </path/to/user.bb>\n", argv[0]);
+               exit(1);
+       }
+       oldpath = argv[1];
+       asprintf(&newpath, "%s.new", oldpath);
</span> 
        if ((oldfile=open(oldpath,O_RDONLY))<0)
        {
                perror(oldpath);
-               exit(0);
<span style="color: #000000;background-color: #ddffdd">+                exit(1);
</span>   }
        if ((newfile=open(newpath,O_WRONLY|O_CREAT,0600))<0)
        {
                perror(newpath);
-               exit(0);
<span style="color: #000000;background-color: #ddffdd">+                exit(1);
</span>   }
 
        tt=time(0);
<span style="color: #aaaaaa">@@ -44,4 +48,6 @@ main()
</span>   }
        close(newfile);
        close(oldfile);
<span style="color: #000000;background-color: #ddffdd">+        free(newpath);
+       return 0;
</span> }
</code></pre>

<br>
</li>
<li id='diff-13'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-13'>
<strong>
src/utils/del_user.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/utils/del_user.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/utils/del_user.c
</span><span style="color: #aaaaaa">@@ -11,15 +11,23 @@
</span> int internet=0;
 struct person user;
 
-int main(void)
<span style="color: #000000;background-color: #ddffdd">+int main(int argc, char **argv)
</span> {
-       const char *newpath = USERFILE ".new";
<span style="color: #000000;background-color: #ddffdd">+        const char *origpath;
+       char *newpath;
</span>   int newfile,oldfile;
        long tt=0l;
 
-       if ((oldfile=open(USERFILE,O_RDONLY))<0)
<span style="color: #000000;background-color: #ddffdd">+        if (argc != 2) {
+               fprintf(stderr, "Usage: %s </path/to/users.bb>\n", argv[0]);
+               exit(1);
+       }
+       origpath = argv[1];
+       asprintf(&newpath, "%s.new", origpath);
+
+       if ((oldfile=open(origpath,O_RDONLY))<0)
</span>   {
-               perror(USERFILE);
<span style="color: #000000;background-color: #ddffdd">+                perror(origpath);
</span>           exit(1);
        }
        if ((newfile=open(newpath,O_WRONLY|O_CREAT,0600))<0)
<span style="color: #aaaaaa">@@ -55,4 +63,6 @@ int main(void)
</span>   }
        close(newfile);
        close(oldfile);
<span style="color: #000000;background-color: #ddffdd">+        free(newpath);
+       return 0;
</span> }
</code></pre>

<br>
</li>
<li id='diff-14'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-14'>
<strong>
src/utils/fixuser.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/utils/fixuser.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/utils/fixuser.c
</span><span style="color: #aaaaaa">@@ -12,7 +12,7 @@
</span> int main(void)
 {
        struct person user;
-       const char *path = USERFILE;
<span style="color: #000000;background-color: #ddffdd">+        const char *path = "users.bb";
</span>   int count=0;
        int ff, ff2;
 
</code></pre>

<br>
</li>
<li id='diff-15'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-15'>
<strong>
src/utils/listuser.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/utils/listuser.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/utils/listuser.c
</span><span style="color: #aaaaaa">@@ -5,14 +5,12 @@
</span> #include <string.h>
 #include <unistd.h>
 
-#include <bb.h>
 #include <user.h>
-#include <files.h>
 
 int main(int argc, char **argv)
 {
        struct person user;
-       const char *path = USERFILE;
<span style="color: #000000;background-color: #ddffdd">+        const char *path = "users.bb";
</span>   int count=0;
        int ff;
 
</code></pre>

<br>
</li>
<li id='diff-16'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-16'>
<strong>
src/webclient/import.c
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/webclient/import.c
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/webclient/import.c
</span><span style="color: #aaaaaa">@@ -36,18 +36,6 @@ int get_person(int file, struct person *tmp)
</span>         return(true);
 }
 
-void update_user(struct person *record, int32_t userposn)
-{
<span style="color: #000000;background-color: #ffdddd">-        int outfile;
</span>-
<span style="color: #000000;background-color: #ffdddd">-        outfile=userdb_open(O_RDWR|O_CREAT);
-        /*Lock_File(outfile); */
-        lseek(outfile,userposn,0);
-        write(outfile,record,sizeof(*record));
-        /*Unlock_File(outfile); */
-        close(outfile);
</span>-}
-
 /* chatmode flags, as in currently active modes */
 unsigned long cm_flags(unsigned long cm, unsigned long flags, int mode)
 {
<span style="color: #aaaaaa">@@ -137,21 +125,6 @@ char *remove_first_word(char *args)
</span>         } else return(NULL);
 }
 
-int is_old(struct person *usr, const char *name, int32_t *userposn)
-{
<span style="color: #000000;background-color: #ffdddd">-        int file,found=false;
</span>-
<span style="color: #000000;background-color: #ffdddd">-        if (access(USERFILE,00)) return(false);
-        file=userdb_open(O_RDONLY);
-        while (!found && get_person(file,usr))
-                if (!strcasecmp(usr->name,name) && !u_del(usr->status))
-                        found=true;
-        if (found)
-                *userposn=lseek(file,0,1)-sizeof(struct person);
-        close(file);
-        return(found);
</span>-}
-
 extern int userposn;
 
 void talk_send_to_room(const char * text, int channel, const char * type, int plural) {
</code></pre>

<br>
</li>
<li id='diff-17'>
<a href='https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d#diff-17'>
<strong>
src/webclient/import.h
</strong>
</a>
<hr>
<pre class="highlight"><code><span style="color: #000000;background-color: #ffdddd">--- a/src/webclient/import.h
</span><span style="color: #000000;background-color: #ddffdd">+++ b/src/webclient/import.h
</span><span style="color: #aaaaaa">@@ -4,7 +4,6 @@
</span> #include <user.h>
 
 int get_person(int file, struct person *tmp);
-void update_user(struct person *record, int32_t userposn);
 unsigned long cm_flags(unsigned long cm, unsigned long flags, int mode);
 char *quotetext(const char *a);
 void broadcast_onoffcode(int code, int method, const char *sourceuser, const char *reason);
<span style="color: #aaaaaa">@@ -12,6 +11,5 @@ void show_chatmodes(unsigned long cm, char *tmp, int flag);
</span> void show_chatprivs(unsigned long cp, char *tmp, int flag);
 char *remove_first_word(char *args) ;
 void talk_send_to_room(const char *text, int channel, const char *type, int plural);
-int is_old(struct person *usr, const char *name, int32_t *userposn);
 
 #endif /* IMPORT_H */
</code></pre>

<br>
</li>

</div>
<div class='footer' style='margin-top: 10px;'>
<p>

<br>
<a href="https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d">View it on GitLab</a>
<script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","action":{"@type":"ViewAction","name":["merge_requests","issues","commit"],"url":"https://projects.sucs.org/arthur/mw/compare/32d6e80e843389d695b5568eb6a40a02b1b4822b...bfb79d904743ef25cefa37ca59687eca790c9a2d"}}</script>
</p>
</div>
</body>
</html>