#include #include #include #include #include #include #include extern const char *__progname; #include "seq.h" #include "msgarg.h" #include "folder.h" #include "system.h" #include "format.h" #include "profile.h" #include "context.h" static int nargs; static char **argstr; static ARG *args; static FOLDER *curfolder; static FOLDER *msgfolder; static int us_n; static const char **us_v; static FORMAT *fmt; static const char *progtag = "read"; static void crack_arglist(int ac, char **av) { char *arg; int errs; for (ac--,av++;ac;ac--,av++) { if ((ac > 1) && !strcmp(*av,"-prog")) { progtag = av[1]; ac --; av ++; continue; } break; } nargs = 0; args = malloc(ac*sizeof(ARG)); argstr = malloc(ac*sizeof(char *)); errs = 0; for (;ac;ac--,av++) { arg = *av; if (! msgarg_parse(arg,args+nargs,0)) { fprintf(stderr,"%s: invalid argument `%s'\n",__progname,arg); errs ++; } else { argstr[nargs] = arg; nargs ++; } } if (errs) exit(1); } static void ws_split(const char *s, int *np, const char ***vp) { int n; const char **v; const char *s0; char *t; n = 0; v = 0; while (1) { while (*s && isspace(*s)) s ++; if (! *s) break; s0 = s; while (*s && !isspace(*s)) s ++; t = malloc((s-s0)+1); bcopy(s0,t,s-s0); t[s-s0] = '\0'; v = realloc(v,(n+1)*sizeof(*v)); v[n++] = t; } *np = n; *vp = v; } static void report_err(const char *msg, void *mvp) { MESSAGE *m; m = mvp; fprintf(stderr,"%s: read program error for +%s:%d: %s\n",__progname,folder_name(message_folder(m)),message_number(m),msg); } static void read_message_n(int n, const char *arg) { MESSAGE *m; SEQS *ss; int i; m = message_make(msgfolder,n); if (message_open(m,O_RDONLY|O_SHLOCK,0) < 0) { if (errno == ENOENT) { fprintf(stderr,"%s: no message %d in +%s\n",__progname,n,folder_name(msgfolder)); } else { fprintf(stderr,"%s: %s (%s): %s\n",__progname,arg,message_path(m),strerror(errno)); } message_free(m); return; } format_run(fmt,m,0,report_err,m,FOPT_OUTFD,1,FOPT_END); message_unlock(m); message_close(m); ss = seqs_open(msgfolder); if (ss) { SEQ *ps; SEQ *cs; SEQ *ns; int n; int nm; int lx; int mx; int hx; int v; n = message_number(m); nm = folder_get_msgnos(msgfolder,0,-1,0); if (us_n > 0) { for (i=0;i 1) { mx = (hx + lx) / 2; if (folder_get_msgnos(msgfolder,1,mx,&v) != nm) { phaseerr:; fprintf(stderr,"%s: phase error on +%s updating next/prev\n",__progname,folder_name(msgfolder)); goto out; } if (v <= n) lx = mx; if (v >= n) hx = mx; } if (lx == hx) { lx --; hx ++; } else { /* can't find new curmsg, warn and set next/prev anyway */ fprintf(stderr,"%s: warning: can't find new current message in +%s\n",__progname,folder_name(msgfolder)); } if (lx < 0) { /* no previous message */ if (hx >= nm) { /* no next message */ } else { /* have a next message */ if (folder_get_msgnos(msgfolder,1,hx,&v) != nm) goto phaseerr; seq_add(ns,v); } } else { /* have a previous message */ if (hx >= nm) { /* no next message */ if (folder_get_msgnos(msgfolder,1,lx,&v) != nm) goto phaseerr; seq_add(ps,v); } else { /* have a next message - get both before setting either */ int v2; if (folder_get_msgnos(msgfolder,1,lx,&v) != nm) goto phaseerr; if (folder_get_msgnos(msgfolder,1,hx,&v2) != nm) goto phaseerr; seq_add(ps,v); seq_add(ns,v2); } } out:; seqs_close(ss); } else { fprintf(stderr,"%s: can't open sequence database in +%s: %s\n",__progname,folder_name(msgfolder),strerror(errno)); } message_free(m); } static void do_messages(int *vec, int nv, void *svp) { int i; for (i=0;ifolder = 0; args->type = AT_SINGLE; args->u.n = MA_CUR; argstr = malloc(sizeof(char *)); argstr[0] = strdup("(default)"); nargs = 1; } for (a=0;a