First version of the configuration file and aliases works.
authorFrancois Fleuret <francois@fleuret.org>
Thu, 2 May 2013 09:29:20 +0000 (11:29 +0200)
committerFrancois Fleuret <francois@fleuret.org>
Thu, 2 May 2013 09:29:20 +0000 (11:29 +0200)
mymail.c

index 88c01f5..281929a 100644 (file)
--- a/mymail.c
+++ b/mymail.c
@@ -102,6 +102,15 @@ struct search_condition {
 
 /********************************************************************/
 
+struct alias_node {
+  char *alias, *value;
+  struct alias_node *next;
+};
+
+struct alias_node *global_alias_list;
+
+/********************************************************************/
+
 struct parsable_field {
   int id;
   int cflags;
@@ -186,6 +195,18 @@ char *default_value(char *current_value,
   }
 }
 
+/********************************************************************/
+
+void *safe_malloc(size_t n) {
+  void *p = malloc(n);
+  if(!p && n != 0) {
+    fprintf(stderr,
+            "selector: cannot allocate memory: %s\n", strerror(errno));
+    exit(EXIT_FAILURE);
+  }
+  return p;
+}
+
 FILE *safe_fopen(const char *path, const char *mode, const char *comment) {
   FILE *result = fopen(path, mode);
   if(result) {
@@ -396,6 +417,8 @@ void update_time(int db_key, const char *db_value, time_t *t) {
   const char *c;
   struct tm tm;
 
+  memset(&tm, 0, sizeof(struct tm));
+
   if(db_key == ID_LEADING_LINE) {
     c = db_value;
     while(*c && *c != ' ') c++; while(*c && *c == ' ') c++;
@@ -804,6 +827,7 @@ void init_condition(struct search_condition *condition, const char *full_string,
   char full_search_field[TOKEN_BUFFER_SIZE], *search_field;
   unsigned int k, m;
   const char *string;
+  struct alias_node *a;
 
   string = parse_token(full_search_field, TOKEN_BUFFER_SIZE, ' ', full_string);
   search_field = full_search_field;
@@ -815,6 +839,13 @@ void init_condition(struct search_condition *condition, const char *full_string,
     condition->negation = 0;
   }
 
+  for(a = global_alias_list; a; a = a->next) {
+    if(strcmp(search_field, a->alias) == 0) {
+      search_field = a->value;
+      break;
+    }
+  }
+
   condition->db_key = -1;
 
   /* Time condition */
@@ -888,6 +919,71 @@ void free_condition(struct search_condition *condition) {
   }
 }
 
+const char *eat_space(const char *s) {
+  while(*s == ' ' || *s == '\t') { s++; }
+  return s;
+}
+
+void read_rc_file(const char *rc_filename) {
+  char raw_line[BUFFER_SIZE];
+  char command[TOKEN_BUFFER_SIZE], tmp_token[TOKEN_BUFFER_SIZE];
+
+  FILE *rc_file;
+  int line_number;
+  const char *s;
+  char *t;
+
+  rc_file = fopen(rc_filename, "r");
+
+  if(rc_file) {
+    line_number = 1;
+    while(fgets(raw_line, BUFFER_SIZE, rc_file)) {
+      t = raw_line;
+      while(*t) { if(*t == '\n') { *t = '\0'; }; t++; }
+
+      s = raw_line;
+      s = eat_space(s);
+
+      if(*s && *s != '#') {
+        s = parse_token(command, TOKEN_BUFFER_SIZE, ' ', s);
+        if(strcmp(command, "alias") == 0) {
+          struct alias_node *a = safe_malloc(sizeof(struct alias_node));
+          a->next = global_alias_list;
+          global_alias_list = a;
+          if(s) {
+            s = eat_space(s);
+            s = parse_token(tmp_token, TOKEN_BUFFER_SIZE, '=', s);
+            a->alias = strdup(tmp_token);
+            if(s) {
+              s = eat_space(s);
+              a->value = strdup(s);
+            } else {
+              fprintf(stderr, "%s:%d syntax error, missing alias value.\n",
+                      rc_filename,
+                      line_number);
+              exit(EXIT_FAILURE);
+            }
+          } else {
+            fprintf(stderr, "%s:%d syntax error, missing alias key.\n",
+                    rc_filename,
+                    line_number);
+            exit(EXIT_FAILURE);
+          }
+        } else {
+          fprintf(stderr, "%s:%d syntax error, unknown command '%s'.\n",
+                  rc_filename,
+                  line_number,
+                  command);
+          exit(EXIT_FAILURE);
+        }
+      }
+
+      line_number++;
+    }
+    fclose(rc_file);
+  }
+}
+
 /*********************************************************************/
 /*********************************************************************/
 /*********************************************************************/
@@ -900,6 +996,7 @@ int main(int argc, char **argv) {
   char *mbox_filename_regexp_string = 0;
   char *default_search_field;
   char output_filename[PATH_MAX + 1];
+  char rc_filename[PATH_MAX + 1];
   int action_index = 0;
   int error = 0, show_help = 0;
   const unsigned int nb_fields_to_parse =
@@ -908,6 +1005,7 @@ int main(int argc, char **argv) {
   unsigned int f, n;
   unsigned int nb_search_conditions;
   struct search_condition search_conditions[MAX_NB_SEARCH_CONDITIONS];
+  struct alias_node *a, *b;
 
   if(regcomp(&global_leading_from_line_regexp, LEADING_FROM_LINE_REGEXP_STRING, 0)) {
     fprintf(stderr,
@@ -915,11 +1013,24 @@ int main(int argc, char **argv) {
     exit(EXIT_FAILURE);
   }
 
+  if(getenv("MYMAILRC")) {
+    sprintf(rc_filename, "%s", getenv("MYMAILRC"));
+  } else if(getenv("HOME")) {
+    sprintf(rc_filename, "%s/.mymailrc", getenv("HOME"));
+  } else {
+    rc_filename[0] = '\0';
+  }
+
+  global_alias_list = 0;
   global_quiet = 0;
   global_use_leading_time = 0;
   default_search_field = 0;
   strncpy(output_filename, "", PATH_MAX);
 
+  if(rc_filename[0]) {
+    read_rc_file(rc_filename);
+  }
+
   setlocale(LC_ALL, "");
 
   nb_search_conditions = 0;
@@ -1082,7 +1193,11 @@ int main(int argc, char **argv) {
       }
     }
 
-    fprintf(db_file, "%s version_%s format_%d raw\n", MYMAIL_DB_MAGIC_TOKEN, MYMAIL_VERSION, MYMAIL_DB_FORMAT_VERSION);
+    fprintf(db_file,
+            "%s version_%s format_%d raw\n",
+            MYMAIL_DB_MAGIC_TOKEN,
+            MYMAIL_VERSION,
+            MYMAIL_DB_FORMAT_VERSION);
 
     while(optind < argc) {
       recursive_index_mbox(db_file,
@@ -1185,6 +1300,15 @@ int main(int argc, char **argv) {
     free_condition(&search_conditions[n]);
   }
 
+  a = global_alias_list;
+  while(a) {
+    b = a->next;
+    free(a->alias);
+    free(a->value);
+    free(a);
+    a = b;
+  }
+
   free(db_filename);
   free(db_filename_regexp_string);
   free(db_root_path);