/* imapfncs.c */

#include "ml.h"

/* globals defined here */

char last_notify_string[FILEBUFFLEN];
MAILSTREAM *last_notify_stream;
char *warning = NULL;
char *error   = NULL;

#ifdef __STDC__
void mm_status(MAILSTREAM *stream, char *mailbox, MAILSTATUS *status)
#else
void mm_status(stream,mailbox,status)
     MAILSTREAM *stream;
     char *mailbox;
     MAILSTATUS *status;
#endif
{
  return;
}

/* 
 * Some compilers can't promote the default c-client defs of the next
 * two functions. For that reason, the __STDC__ is shifted so that
 * the defs won't be picked up by the prototype parser. These functions 
 * are _only_ called by c-client; which supposedly has the master 
 * prototypes. Yah, right. If you're using ANSI. At any rate, we'll pick
 * 'em up here, but we don't need 'em in the prototypes.h file.
 */


#ifdef           __STDC__
void mm_list(MAILSTREAM *stream, char delimiter, char *str, long attributes)
#else
void mm_list(stream,delimiter,str,attributes)
     MAILSTREAM *stream;
     char delimiter;
     char *str;
     long attributes;
#endif
{
  Mailbox_List *mailbox_list;
  Server_Config *server;

  for(server = session->servers; server; server = server->next)
    if(server->in_use == TRUE) {
      mailbox_list = new_mailbox_list();
      mailbox_list->name = cpystr(str);
      mailbox_list->attribute = attributes;
      mailbox_list->delimiter = delimiter;
      mailbox_list->prev = server->unsubscribed;
      server->unsubscribed = mailbox_list;
    }
  return;
}

#ifdef            __STDC__
void mm_lsub(MAILSTREAM *stream, char delimiter, char *str, long attributes)
#else
void mm_lsub(stream,delimiter,str,attributes)
     MAILSTREAM *stream;
     char delimiter;
     char *str;
     long attributes;
#endif
{
  Mailbox_List *mailbox_list;
  Server_Config *server;

  for(server = session->servers; server; server = server->next)
    if(server->in_use == TRUE) {
      mailbox_list = new_mailbox_list();
      mailbox_list->name = cpystr(str);
      mailbox_list->attribute = attributes;
      mailbox_list->delimiter = delimiter;
      mailbox_list->prev = server->subscribed;
      server->subscribed = mailbox_list;
    }
  return;
}


#ifdef __STDC__
void mm_searched(MAILSTREAM *stream, unsigned long msgno)
#else
void mm_searched( stream, msgno )
     MAILSTREAM *stream;
     unsigned long msgno;
#endif
{
  Mailbox *mailbox;
  Message_List *message_list;
  Message_List *prev = NULL;
  Message *message;

  mailbox = find_mailbox_from_mailstream(stream);
  if(mailbox == NULL)
    return;

  message = get_message_from_mailbox(mailbox,msgno);
  if(message) {
    message_list = new_message_list();
    message_list->message = message;
    if(mailbox->found) {
      for(prev = mailbox->found; prev->next; prev = prev->next)
	;
    }
    if(! prev) {
      mailbox->found = message_list;
      message_list->prev = NULL;
    }
    else {
      prev->next = message_list;
      message_list->prev = prev;
    }
  }
  return;
}

#ifdef __STDC__
void mm_exists(MAILSTREAM *stream, unsigned long number)
#else
void mm_exists( stream, number )
     MAILSTREAM *stream;
     unsigned long number;
#endif
{

  Mailbox *mailbox;

  char buffer[FILEBUFFLEN];

  int delta;

  mailbox = find_mailbox_from_mailstream(stream);
  if(! mailbox)
    return;

  if(mailbox->nmsgs < number) {
    delta = number - mailbox->nmsgs;
    sprintf(buffer,MLGetLocalized(XtNmsgNewMessage,MsgNewMessage),
	    delta, 
	    (delta == 1) 
	    ? MLGetLocalized(XtNmsgMessageSingular,MsgMessageSingular)
	    : MLGetLocalized(XtNmsgMessagePlural, MsgMessagePlural));
    mm_log(buffer,NIL);
    mailbox->has_new_mail = TRUE;
  }

  mailbox->nmsgs = number;
  return;
}


#ifdef __STDC__
void mm_expunged(MAILSTREAM *stream, unsigned long msgno)
#else
void mm_expunged( stream, msgno )
     MAILSTREAM *stream;
     unsigned long msgno;
#endif
{
  Mailbox *mailbox;

  mailbox = find_mailbox_from_mailstream(stream);
  if(! mailbox)
    return;

  mailbox->nmsgs --;

  compose_expunge(stream,msgno);
  view_expunge(stream,msgno);
  read_expunge(stream,msgno);
  return;
}


#ifdef __STDC__
void mm_notify( MAILSTREAM *stream, char *string, long errorflag )
#else
void mm_notify( stream, string, errorflag )
     MAILSTREAM *stream;
     char *string;
     long errorflag;
#endif
{

  if(string == NULL)
    return;

  /* 
   * Save the results in case we need to refer to 
   * them from the program, like "[TRYCREATE]" 
   */

  strcpy(last_notify_string, string );
  last_notify_stream = stream;

  mm_log(string,errorflag);
  return;
}

#ifdef __STDC__
void mm_log( char *string, long errorflag )
#else
void mm_log( string, errorflag )
     char *string;
     long errorflag;
#endif
{
  time_t t;
  struct tm *local_time;
  char t_buf[CURRTIMESIZE];
  FILE *fp;

  if(warning == NULL)
    warning = MLGetLocalized(XtNstrWarn,StrWarn);
  if(error == NULL)
    error = MLGetLocalized(XtNstrError,StrError);


  if(string == NULL)
    string = "<NULL>";

  if(strncasecmp(string, CHECKMSG, strlen(CHECKMSG)) == 0) 
    return;

  t = time(0);
  local_time = localtime(&t);
  if((local_time) && (errorflag != PARSE)) {
    strftime(t_buf,sizeof(t_buf),LOGTIME_FMT,local_time);
    log_error(t_buf, NIL);
  }

  switch(errorflag) {
  case PARSE:
    if(preferences.developer_debug == FALSE)
      return;
    break;
  case NIL:
  case BYE:
  case MLNOTIFY:
    break;
  case WARN:
    log_error(warning, NIL);
    break;
  case ERROR:
  default:
    log_error(error, NIL);
    break;
  }

  log_error(string,NIL);
  if(string[strlen(string) - 1] != LFCHAR)
    log_error(LFSTR, NIL);
  if(errorflag)
    log_error(EMPTYSTR,errorflag);

  if(preferences.developer_debug == TRUE) {
    fp = fopen(".mldata/log","a");
    if(fp) {
      fprintf(fp,"%s\n",string);
      fclose(fp);
    }
  }
  return;
}


#ifdef __STDC__
void mm_dlog(char *string)
#else
void mm_dlog( string )
     char *string;
#endif
{
  FILE *fp;

  log_error(string, NIL);
  if(string[strlen(string) - 1] != LFCHAR)
    log_error(LFSTR, NIL);

  if(preferences.developer_debug == TRUE) {
    fp = fopen(".mldata/log","a");
    if(fp) {
      fprintf(fp,"%s\n",string);
      fclose(fp);
    }
  }

  return;
}

#ifdef __STDC__
void mm_login ( NETMBX *mb, char *username, char *password, long trial )
#else
void mm_login ( mb, username, password, trial )
     NETMBX *mb;
     char *username;
     char *password;
     long trial;
#endif
{

  long maxtrials;
  Server_Config *server_config;
  Remote_Auth *authst = NULL, *authtmp = NULL;
  char *tmp = NULL;

  /*
   * First check to see if we can re-use previous credentials.
   * If we have stashed auth credentials and we're being asked a
   * second time for authentication, the stashed ones aren't any good. 
   * Unfortunately, there's no way to dump the cache from the program,
   * in case somebody wants to login to a previously opened server under
   * a different account. Sorry. that's the way it is. They'll have to
   * run a second instance of the program.
   */

  maxtrials  = (long) mail_parameters(NIL, GET_MAXLOGINTRIALS, NULL);
  server_config = session->active;


  if(trial != 0) { /* dump old credentials */
    authtmp = session->authorizations;
    if(authtmp) {
      session->authorizations = authtmp->next;
      free_remote_auth(authtmp);
    }
  }
  else {   /* reuse the last valid credentials, if possible */
    for(authtmp = session->authorizations; authtmp; authtmp = authtmp->next) {
      if(((strcmp(mb->host, authtmp->hostname)) == STRMATCH) 
	 && ((strcmp(authtmp->authtype,"IMAP")) == STRMATCH)
	 && (authtmp->config == server_config)) {
	strcpy(username,(authtmp->username) ? authtmp->username : EMPTYSTR ); 
	if((tmp = scramble(authtmp->password)) != NULL) {
	  strcpy(password,tmp);
	  wipeout(tmp);
	  fs_give((void **) &tmp);
	}
	return;
      }
    }
  }
	
  /* no stashed credentials, fresh authentication */

  if(server_config)
    authst = login(session->shell, server_config, mb->host, "IMAP", 
		   (*mb->user) ? mb->user : server_config->username, NULL );
  else
    authst = login(session->shell, NULL, mb->host, "IMAP", 
		   (*mb->user) ? mb->user : local_auth.username, NULL );
  
  if(authst) {
    strcpy(username,(authst->username) ? authst->username : EMPTYSTR );
    if((tmp = scramble(authst->password)) != NULL) {
      strcpy(password,tmp);
      wipeout(tmp);
      fs_give((void **) &tmp);
    }

    /* save for re-use */
    if((*username != NUL_TERM) && (*password != NUL_TERM)) {
      authst->next = session->authorizations;
      session->authorizations = authst;
    }
  }
  return;
}


#ifdef __STDC__
void mm_critical(MAILSTREAM *stream)
#else
void mm_critical( stream )
     MAILSTREAM *stream;
#endif
{
  return;
}

#ifdef __STDC__
void mm_nocritical(MAILSTREAM *stream)
#else
void mm_nocritical( stream )
     MAILSTREAM *stream;
#endif
{
  return;
}

#ifdef __STDC__
void mm_fatal(char *string)
#else
void mm_fatal( string )
     char *string;
#endif
{

  /* We're going to crash... */

  mm_log(string,ERROR);
  if(preferences.developer_debug == TRUE)
    abort();
  return;

}


#ifdef __STDC__
long mm_diskerror( MAILSTREAM *stream, long errcode, long serious )
#else
long mm_diskerror( stream, errcode, serious )
     MAILSTREAM *stream;
     long         errcode;
     long         serious;
#endif
{
    return(0L);
}

#ifdef __STDC__
void mm_flags ( MAILSTREAM *stream, unsigned long msgno )
#else
void mm_flags ( stream, msgno )
     MAILSTREAM *stream;
     unsigned long msgno;
#endif
{
  update_view_line_stream_msgno(stream,msgno);
  return;
}

#ifdef __STDC__
void mm_idle(void)
#else
void mm_idle()
#endif
{
  return;
}


syntax highlighted by Code2HTML, v. 0.9.1