X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=uip%2Fnew.c;h=976337664d2909e3de4a9209130924f35a843cde;hp=c4026ba48d20057bfdb383fe05bb34616d5abad7;hb=6e9577f324bef90765a5edc02044eb111ec48072;hpb=682962d94b21e120c78a52a8bdcb6aa994330a14 diff --git a/uip/new.c b/uip/new.c index c4026ba..9763376 100644 --- a/uip/new.c +++ b/uip/new.c @@ -10,28 +10,31 @@ ** Inspired by Luke Mewburn's new: http://www.mewburn.net/luke/src/new */ +#include +#include +#include #include - #include #include #include - -#include -#include -#include +#include +#include +#include static struct swit switches[] = { #define MODESW 0 - { "mode", 1 }, + { "mode", 0 }, #define FOLDERSSW 1 - { "folders", 1 }, + { "folders", 0 }, #define VERSIONSW 2 - { "version", 1 }, + { "Version", 0 }, #define HELPSW 3 - { "help", 1 }, + { "help", 0 }, { NULL, 0 } }; +char *version=VERSION; + static enum { NEW, FNEXT, FPREV, UNSEEN } run_mode = NEW; /* @@ -54,7 +57,7 @@ count_messages(char *field) int j, k; char *cp, **ap; - field = getcpy(field); + field = mh_xstrdup(field); /* copied from seq_read.c:seq_init */ for (ap = brkstring(field, " ", "\n"); *ap; ap++) { @@ -67,7 +70,7 @@ count_messages(char *field) } } - free(field); + mh_free0(&field); return total; } @@ -94,11 +97,10 @@ seq_in_list(char *name, char *sequences[]) static char * get_msgnums(char *folder, char *sequences[]) { + enum state state; + struct field f = {{0}}; char *seqfile = concat(toabsdir(folder), "/", mh_seq, (void *)NULL); FILE *fp = fopen(seqfile, "r"); - int state; - char name[NAMESZ], field[BUFSIZ]; - char *cp; char *msgnums = NULL, *this_msgnums, *old_msgnums; /* no sequences file -> no messages */ @@ -106,72 +108,43 @@ get_msgnums(char *folder, char *sequences[]) return NULL; } - /* copied from seq_read.c:seq_public */ - for (state = FLD;;) { - switch (state = m_getfld(state, name, field, sizeof(field), - fp)) { - case FLD: - case FLDPLUS: - case FLDEOF: - if (state == FLDPLUS) { - cp = getcpy(field); - while (state == FLDPLUS) { - state = m_getfld(state, name, - field, - sizeof(field), - fp); - cp = add(field, cp); - } - - /* - ** Here's where we differ from - ** seq_public: if it's in a - ** sequence we want, save the list - ** of messages. - */ - if (seq_in_list(name, sequences)) { - this_msgnums = trimcpy(cp); - if (msgnums == NULL) { - msgnums = this_msgnums; - } else { - old_msgnums = msgnums; - msgnums = concat(old_msgnums, " ", this_msgnums, (void *)NULL); - free(old_msgnums); - free(this_msgnums); - } - } - free(cp); + for (state = FLD2;;) { + switch (state = m_getfld2(state, &f, fp)) { + case LENERR2: + state = FLD2; + /* FALL */ + + case FLD2: + /* + ** if it's in a sequence we want, + ** save the list of messages. + */ + if (seq_in_list(f.name, sequences)) { + this_msgnums = trimcpy(f.value); + if (msgnums == NULL) { + msgnums = this_msgnums; } else { - /* and here */ - if (seq_in_list(name, sequences)) { - this_msgnums = trimcpy(field); - if (msgnums == NULL) { - msgnums = this_msgnums; - } else { - old_msgnums = msgnums; - msgnums = concat(old_msgnums, " ", this_msgnums, (void *)NULL); - free(old_msgnums); - free(this_msgnums); - } - } + old_msgnums = msgnums; + msgnums = concat(old_msgnums, " ", + this_msgnums, + NULL); + mh_free0(&old_msgnums); + mh_free0(&this_msgnums); } + } + continue; - if (state == FLDEOF) - break; - continue; - - case BODY: - case BODYEOF: - adios(NULL, "no blank lines are permitted in %s", seqfile); - /* fall */ + case BODY2: + adios(EX_DATAERR, NULL, "no blank lines are permitted in %s", seqfile); + /* FALL */ - case FILEEOF: - break; + case FILEEOF2: + break; - default: - adios(NULL, "%s is poorly formatted", seqfile); + default: + adios(EX_SOFTWARE, NULL, "%s is poorly formatted", seqfile); } - break; /* break from for loop */ + break; } fclose(fp); @@ -191,9 +164,9 @@ check_folder(char *folder, size_t len, struct list_state *b) if (is_cur || msgnums != NULL) { if (*b->first == NULL) { - *b->first = b->node = mh_xmalloc(sizeof(*b->node)); + *b->first = b->node = mh_xcalloc(1, sizeof(*b->node)); } else { - b->node->n_next = mh_xmalloc(sizeof(*b->node)); + b->node->n_next = mh_xcalloc(1, sizeof(*b->node)); b->node = b->node->n_next; } b->node->n_name = folder; @@ -257,12 +230,12 @@ check_folders(struct node **first, struct node **last, } else { fp = fopen(folders, "r"); if (fp == NULL) { - adios(NULL, "failed to read %s", folders); + adios(EX_IOERR, NULL, "failed to read %s", folders); } while (vfgets(fp, &line) == OK) { len = strlen(line) - 1; line[len] = '\0'; - check_folder(getcpy(line), len, &b); + check_folder(mh_xstrdup(line), len, &b); } fclose(fp); } @@ -284,7 +257,7 @@ join_sequences(char *sequences[]) for (i = 0; sequences[i] != NULL; i++) { len += strlen(sequences[i]) + 1; } - result = mh_xmalloc(len + 1); + result = mh_xcalloc(len + 1, sizeof(char)); for (i = 0, cp = result; sequences[i] != NULL; i++, cp += len + 1) { len = strlen(sequences[i]); @@ -309,10 +282,14 @@ join_sequences(char *sequences[]) static struct node * doit(char *cur, char *folders, char *sequences[]) { - struct node *first, *cur_node, *node, *last, *prev; + struct node *first, *cur_node, *node, *last = NULL, *prev; size_t folder_len; int count, total = 0; - char *command = NULL, *sequences_s = NULL; + char *sequences_s = NULL; + int argc = 0; + char *argv[MAXARGS]; + char **seqp; + char buf[BUFSIZ]; if (cur == NULL || cur[0] == '\0') { cur = "inbox"; @@ -384,14 +361,15 @@ doit(char *cur, char *folders, char *sequences[]) } fflush(stdout); - /* - ** TODO: Split enough of scan.c out so that we can - ** call it here. - */ - command = concat("scan +", node->n_name, " ", - sequences_s, (void *)NULL); - system(command); - free(command); + argc = 0; + argv[argc++] = "scan"; + snprintf(buf, sizeof buf, "+%s", node->n_name); + argv[argc++] = buf; + for (seqp=sequences; *seqp; seqp++) { + argv[argc++] = *seqp; + } + argv[argc] = (char *)NULL; + execprog(*argv, argv); } else { if (node->n_field == NULL) { continue; @@ -433,9 +411,10 @@ main(int argc, char **argv) char *unseen; struct node *folder; -#ifdef LOCALE + sequences[0] = NULL; + sequences[1] = NULL; + setlocale(LC_ALL, ""); -#endif invo_name = mhbasename(argv[0]); /* read user profile/context */ @@ -452,28 +431,28 @@ main(int argc, char **argv) switch (smatch(++cp, switches)) { case AMBIGSW: ambigsw(cp, switches); - done(1); + exit(EX_USAGE); case UNKWNSW: - adios(NULL, "-%s unknown", cp); + adios(EX_USAGE, NULL, "-%s unknown", cp); case HELPSW: snprintf(help, sizeof(help), "%s [switches] [sequences]", invo_name); print_help(help, switches, 1); - done(1); + exit(argc == 2 ? EX_OK : EX_USAGE); case VERSIONSW: print_version(invo_name); - done(1); + exit(argc == 2 ? EX_OK : EX_USAGE); case FOLDERSSW: if (!(folders = *argp++) || *folders == '-') - adios(NULL, "missing argument to %s", + adios(EX_USAGE, NULL, "missing argument to %s", argp[-2]); continue; case MODESW: if (!(invo_name = *argp++) || *invo_name == '-') - adios(NULL, "missing argument to %s", + adios(EX_USAGE, NULL, "missing argument to %s", argp[-2]); invo_name = mhbasename(invo_name); continue; @@ -482,6 +461,7 @@ main(int argc, char **argv) /* have a sequence argument */ if (!seq_in_list(cp, sequences)) { sequences[i++] = cp; + sequences[i] = NULL; } } @@ -502,12 +482,17 @@ main(int argc, char **argv) } if (i == 0) { + char *dp; /* no sequence arguments; use unseen */ - unseen = context_find(usequence); - if (unseen == NULL || unseen[0] == '\0') { - adios(NULL, "must specify sequences or set %s", usequence); + if ((unseen = context_find(usequence))) { + if (!*unseen) { + adios(EX_CONFIG, NULL, "profile entry %s set, but empty, and no sequences given", usequence); + } + } else { + unseen = seq_unseen; /* use default */ } - for (ap = brkstring(unseen, " ", "\n"); *ap; ap++) { + dp = mh_xstrdup(unseen); + for (ap = brkstring(dp, " ", "\n"); *ap; ap++) { sequences[i++] = *ap; } } @@ -515,7 +500,7 @@ main(int argc, char **argv) folder = doit(context_find(curfolder), folders, sequences); if (folder == NULL) { - done(0); + exit(EX_OK); return 1; } @@ -539,6 +524,5 @@ main(int argc, char **argv) context_save(); - done(0); - return 1; + return 0; }