/* -*-C-*-
*******************************************************************************
*
* File:         listmail.m
* RCS:          /usr/local/sources/CVS/mailapp-utilities/listmail.m,v 1.4 1997/04/19 17:37:20 tom Exp
* Description:  List the contents of a Mail.app table_of_contents
* Author:       Carl Edman
* Created:      Fri Mar 12 18:21:23 1993
* Modified:     Sat Nov 30 23:29:31 1996 Tom Hageman <tom@basil.icce.rug.nl>
* Language:     Objective C
* Package:      mailapp-utilities
* Status:       First release.
*
* (C) Copyright 1993, but otherwise this file is perfect freeware.
*
*******************************************************************************
*/

#import <libc.h>
#import <errno.h>
//#import <stdlib.h>
//#import <stdio.h>
//#import <string.h>
//#import <time.h>
#import <regex.h>
//#import <sys/file.h>
//#import <sys/param.h>
//#import <sys/types.h>
//#import <sys/stat.h>
#import <defaults/defaults.h>
#import "mailutil.h"
#import "mailtoc.h"
#import "optutil.h"

#define USAGE "\
Usage: %s [-nv][-t][-H|-V] mbox...\n"

#define HELP "\
 -n           ignore mailbox locks, list regardless\n\
 -v           talkative mode\n\
 -t           show total number of messages\n\
 -V           show version\n\
 -H           this help\n\
"

char line[LINELEN];

int main(int ac,char *av[])
{
   int c,width;
   int verboseflg=0,nowaitflg=0,countonlyflg=0,lockedflg;
   FILE *tocf;
   char *p;
   struct table_of_contents_header *toch=0;
   struct message_index *mi=0;
   int status=EXIT_SUCCESS;

   set_progname(av[0]);

   while((c=getopt(ac,av,"nvtVH"))!=EOF) switch(c)
   {
    case 'v':
      verboseflg++;
      break;
    case 'n':
      nowaitflg++;
      break;
    case 't':
      countonlyflg++;
      break;
    case 'V':
      status=EXIT_VERSION;
      break;
    case 'H':
      status=EXIT_HELP;
      break;
    case '?':
    default:
      status=EXIT_USAGE;
   }
   if (status==EXIT_SUCCESS && optind>=ac) status=EXIT_USAGE;
   handle_usage_help_version(status, USAGE, HELP);

   for(;optind<ac;optind++)
   {
      int priority;
      time_t s,t;
      
      if (verboseflg) fprintf(stderr,"Entering %s...\n",av[optind]);
      if (cd_mbox(av[optind],0)) goto next;
      lockedflg=lock_mbox(nowaitflg);

      if ((tocf=fopen("table_of_contents","rb"))==NULL)
      {
         fprintf(stderr,"%s: %s: opening: %s\n",progname(),av[optind],strerror(errno));
         goto unlock;
      }

      toch=get_table_of_contents_header(tocf,0);
      if (!toch)
      {
         fprintf(stderr,"%s: %s: invalid table_of_contents\n",progname(),av[optind]);
         goto unlock;
      }

      if (countonlyflg)
      {
         printf("%d\n",toch->num_msgs);
         goto unlock;
      }
      // XXX wishlist: countall -- message count per category.

      printf("Table of contents (magic=%d):\n",toch->magic);
      printf("Number of messages:%5d   Modification Time:%25s",toch->num_msgs,
             ctime(&toch->mbox_time));
      if (toch->mbox_time!=mtime("mbox"))
      {
         s=mtime("mbox");
         printf("(!=%25s)",ctime(&s));
      }
      
      printf("\nAt (%.2f,%.2f) %.2fx%.2f(%.2f)\n",toch->window.origin.x,
             toch->window.origin.y,toch->window.size.width,toch->window.size.height,
             toch->list);

      for(c=toch->num_msgs,width=0;c>0;) { width++; c/=10; }
      for(c=0;c<toch->num_msgs;c++)
      {
         if ((mi=get_message_index(tocf))==0)
	 {
            fprintf(stderr,"%s: %s: reading mbox entries: %s\n",progname(),av[optind],(errno?strerror(errno):"invalid"));
            goto unlock;
	 }

         printf("%c%c%c%c%*d %8d %5d/%7d %s:%s",mi->status,mi->msgtype,mi->encrypted,mi->sync,width,c+1,mi->mes_date,mi->mes_length,mi->mes_offset,message_from(mi),message_subject(mi));
         if (*(p=message_reference(mi)))
	 {
            t=message_attachtime(mi);
            s=mtime(p);
	    printf("(%s:%d@%25s", p, message_attachsize(mi),ctime(&t));
            if (t!=s) printf("!= %25s",ctime(&s));
            printf(")");
	 }

         if ((priority=message_priority(mi))>0)
	 {
            printf("(pri=%d)",priority);
	 }
         
         printf("\n");
         free(mi); mi=0;
      }

    unlock:
      if (tocf!=NULL) fclose(tocf);
      if (!lockedflg) unlock_mbox();
    next:
      if (toch) { free(toch); toch=0; }
      if (mi) { free(mi); mi=0; }
      uncd_mbox();
   }
   exit(EXIT_SUCCESS);
}
