/*
 * Program:	An IMAP replacement for the ``from'' utility.
 *
 * Author:	Eric Horst
 *		Networks and Distributed Computing
 *		University of Washington
 *		Administration Building, AG-44
 *		Seattle, WA  98195
 *		Internet: erich@CAC.Washington.EDU
 *
 * Date:	12 April 1996
 * Last Edited:	2 January 2002
 *
 * The IMAP tools software provided in this Distribution is
 * Copyright 2002 University of Washington.
 * The full text of our legal notices is contained in the file called
 * CPYRIGHT, included with this Distribution.
 */

#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <pwd.h>
#include "mail.h"
#include "osdep.h"
#include "rfc822.h"
#include "smtp.h"
#include "nntp.h"
#include "misc.h"

/* Field sizes and formats */

#define MSGN_FIELD 5
#define STAT_FIELD 5
#define FROM_FIELD 23
#define DATE_FIELD 11
#define TIME_FIELD 5
#define SUBJ_FIELD 23
#define SEPARATOR  2
#define ADDR_FMT     "%s%s<%s%s%s>  "
#define ALT_ADDR_FMT "%s%s%s (%s)  "
#define MT_FIELD     "                         "

char *curhst = NIL;		/* currently connected host */
char *curusr = NIL;		/* current login user */
char personalname[MAILTMPLEN];	/* user's personal name */
int nostatus = NIL, nomsgno = NIL, nodate = NIL,  /* flags */
  notime = NIL, altffmt = NIL, nolimit = NIL;
int sfrom = FROM_FIELD, ssubj = SUBJ_FIELD;     /* var column widths */
char *afmt = ADDR_FMT;

int main (int argc,char *argv[]);
void mm (MAILSTREAM *stream,long debug);
void prompt (char *msg,char *txt);
int fail (char *string,int code);
void fetch_print (MAILSTREAM *stream, unsigned long i);
char *getpass ();

/* Main program - initialization */

int main (int argc,char *argv[])
{
  MAILSTREAM *stream = NIL;
  char *s,tmp[MAILTMPLEN];
  char *help = "usage: ifrom [-s] [-n] [-d] [-t] [-f] [-l] [-h|?] mailbox";
  long debug;
#include "linkage.c"

                                /* make sure have some arguments */
  if (--argc < 1) _exit (fail (help,1));
                                /* process all flags */
  while (argc && (*(s = *++argv)) == '-') {
    argc--;                     /* gobble this argument */
    switch (s[1]) {             /* what is this flag? */
    case 's':                   /* suppress status */
      nostatus = T;
      sfrom += (STAT_FIELD + 1);
      break;
    case 'n':                   /* suppress msgno */
      nomsgno = T;
      ssubj += (MSGN_FIELD + SEPARATOR);
      break;
    case 'd':                   /* suppress date */
      nodate = T;
      break;
    case 't':                   /* suppress time */
      notime = T;
      break;
    case 'f':                   /* alt from format */
      altffmt = T;
      afmt = ALT_ADDR_FMT;
      break;
    case 'l':                   /* no field limits */
      nolimit = T;
      break;
    case '?':                   /* give usage */
    case 'h':
      _exit (fail (help,1));
      break;
    default:                    /* anything else */
      _exit (fail ("unknown switch",1));
    }
  }

  if (nodate) {
    ssubj += (DATE_FIELD + TIME_FIELD + SEPARATOR +1);
  } 
  else if (notime) {
    ssubj += (TIME_FIELD);
  }

  curusr = cpystr(myusername());/* current user is this name */
  {
    char *suffix;
    struct passwd *pwd = getpwnam (curusr);
    if (pwd) {
      strcpy (tmp,pwd->pw_gecos);
				/* dyke out the office and phone poop */
      if (suffix = strchr (tmp,',')) suffix[0] = '\0';
      strcpy (personalname,tmp);/* make a permanent copy of it */
    }
    else personalname[0] = '\0';
  }

  curhst = cpystr (mylocalhost ());
  if (!*personalname) prompt ("Personal name: ",personalname);
  debug =  NIL;
  stream = mail_open (stream,*argv,OP_READONLY);
  if (stream) mm (stream,debug);	  /* run user interface if opened */

  return NIL;
}

/* Report an error
 * Accepts: string to output
 */
int fail (char *string,int code)
{
  mm_log (string,ERROR);        /* pass up the string */
  return code;                  /* error code to return */
}

/* MM command loop
 * Accepts: MAIL stream
 */

void mm (MAILSTREAM *stream,long debug)
{
  unsigned long i;

  for (i = 1; i <= stream->nmsgs; ++i)
    fetch_print (stream,i);

  mail_close (stream);
  stream = NIL;

  return;
}

/* Fetch message, format and print
 * Accepts: stream
 *          message number
 */

void fetch_print (MAILSTREAM *stream, unsigned long i)
{
  static char sout[MAILTMPLEN],tmp[MAILTMPLEN];
  static MESSAGECACHE *elt;
  static ENVELOPE *env;
  int c = NIL;

  sout[0] = '\0';
  elt = mail_elt (stream,i);
  env = mail_fetchenvelope (stream,i);

  if (!nomsgno) {
    sprintf (tmp,"%5ld  ",elt->msgno);
    strcat (sout, tmp);
  }

  if (!nostatus) {
    tmp[0] = elt->recent ? (elt->seen ? 'R': 'N') : ' ';
    tmp[1] = (elt->recent | elt->seen) ? ' ' : 'U';
    tmp[2] = elt->flagged ? 'F' : ' '; 
    tmp[3] = elt->answered ? 'A' : ' ';
    tmp[4] = elt->deleted ? 'D' : ' ';
    tmp[5] = ' ';
    tmp[6] = '\0';
    strcat (sout, tmp);
  }

  if (env->from) {
    if (!altffmt) {
      sprintf(tmp, afmt, 
	      (env->from->personal ? env->from->personal : ""), 
	      (env->from->personal ? " "                 : ""), 
	      (env->from->mailbox  ? env->from->mailbox  : ""), 
	      (env->from->host     ? "@"                 : ""), 
	      (env->from->host     ? env->from->host     : ""));
    }
    else {
      sprintf(tmp, afmt, 
	      (env->from->mailbox  ? env->from->mailbox  : ""), 
	      (env->from->host     ? "@"                 : ""), 
	      (env->from->host     ? env->from->host     : ""),
	      (env->from->personal ? env->from->personal : "")); 
    }
  }
  else {
    strcpy(tmp, MT_FIELD);
  }
  if (!nolimit) {
    tmp[sfrom] = ' ';
    tmp[sfrom+1] = ' ';
    tmp[sfrom+2] = '\0';
  }
  strcat (sout, tmp);

  if (!nodate) {
    mail_date (tmp,elt);
    if (notime) {
      tmp[12] = ' '; tmp[13] = '\0';
    }
    else {
      tmp[17] = ' '; tmp[18] = ' '; tmp[19] = '\0';
    }
    strcat (sout,tmp);
  }      

  if (env->subject) {
    strcpy (tmp, env->subject);
    if (!nolimit) tmp[ssubj] = '\0';
    strcat (sout, tmp);
  }
  puts(sout);
}

/* Prompt user for input
 * Accepts: pointer to prompt message
 *          pointer to input buffer
 */

void prompt (char *msg,char *txt)
{
  printf ("%s",msg);
  gets (txt);
}

/* Interfaces to C-client */


void mm_searched (MAILSTREAM *stream,unsigned long number)
{
}


void mm_exists (MAILSTREAM *stream,unsigned long number)
{
}


void mm_expunged (MAILSTREAM *stream,unsigned long number)
{
}


void mm_flags (MAILSTREAM *stream,unsigned long number)
{
}


void mm_notify (MAILSTREAM *stream,char *string,long errflg)
{
  mm_log (string,errflg);
}


void mm_list (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
{
}


void mm_lsub (MAILSTREAM *stream,int delimiter,char *mailbox,long attributes)
{
}


void mm_status (MAILSTREAM *stream,char *mailbox,MAILSTATUS *status)
{
}


void mm_log (char *string,long errflg)
{
  switch ((short) errflg) {
  case NIL:
    break;
  case PARSE:
    break;
  case WARN:
    printf ("%%%s\n",string);
    break;
  case ERROR:
    printf ("?%s\n",string);
    break;
  }
}


void mm_dlog (char *string)
{
  fprintf (stderr, "%s\n",string);
}


void mm_login (NETMBX *mb,char *user,char *pwd,long trial)
{
  char tmp[MAILTMPLEN];
  if (curhst) fs_give ((void **) &curhst);
  curhst = (char *) fs_get (1+strlen (mb->host));
  strcpy (curhst,mb->host);
  if (*mb->user) {
    strcpy (user,mb->user);
    sprintf (tmp,"{%s/%s/user=%s} password: ",mb->host,mb->service,mb->user);
  }
  else {
    sprintf (tmp,"{%s/%s} username: ",mb->host,mb->service);
    prompt (tmp,user);
    strcpy (tmp,"Password: ");
  }
  if (curusr) fs_give ((void **) &curusr);
  curusr = cpystr (user);
  strcpy (pwd,getpass (tmp));
}


void mm_critical (MAILSTREAM *stream)
{
}


void mm_nocritical (MAILSTREAM *stream)
{
}


long mm_diskerror (MAILSTREAM *stream,long errcode,long serious)
{
  kill (getpid (),SIGSTOP);
  return NIL;
}


void mm_fatal (char *string)
{
  fprintf (stderr,"?%s\n",string);
}


