/*
 *  wmpop3.c
 *  multi pop3 mail checker.
 *  written by Louis-Benoit JOURDAIN (lb@jourdain.org)
 *  based on the original work by Scott Holden (scotth@thezone.net)
 *
*/


#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <time.h>

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/ioctl.h>

#include <X11/xpm.h>
#include <X11/Xlib.h>
#include <X11/extensions/shape.h>

#include <dirent.h>

#include <libdockapp/wmgeneral.h>
#include "Pop3Client.h"

#include "wmpop3.xpm"

char wminet_mask_bits[64*64];
int  wminet_mask_width = 64;
int  wminet_mask_height = 64;

char *ProgName;

char mailclient[32]   = "pine";
char password[32];
char username[32];
char popserver[128];
int  serverport       = 110;
int  mailCheckDelay   = 10;  /* default */
int  autoChecking     = YES; /* default */
int  newMessagesOnly  = YES; /* default */
int  displaydelay = 1;
char	tempdir[1024];
char config_file[256] = "not-defined";
int	scrollspeed = 100;

Pop3	conf[6];
int	nb_conf;	/* number of configured pop servers */
int	summess;	/* total number of messages */
int	color;

#ifdef _DEBUG
int	haspassed = 0;
#endif

t_scrollbar	scrollbar;

void usage(void);
void printversion(void);
void wmCheckMail_routine(int, char **);
int  readConfigFile( char *filename );

void BlitString(char *name, int x, int y, int fragment);
void BlitNum(int num, int x, int y, int todelete);

int	pop3DeleteMail(int num, Pop3 pc);
int	pop3VerifStats(Pop3 pc);

/********************************
 *           Main Program
 ********************************/
void	deleteoldtmpfiles()
{
  char	buf[1024];
  DIR	*dir;
  struct dirent	*dp;

  if (tempdir) {
    if ((dir = opendir(tempdir))) {
      chdir(tempdir);
      while((dp = readdir(dir))) {
	if (!strncmp(dp->d_name, TMPPREFIX, TMPPREFIXLEN)) {
	  sprintf(buf, "%s/%s", tempdir, dp->d_name);
#ifdef _DEBUG
	  printf("  delete old tmp file: %s\n", buf);
#endif
	  unlink(buf);
	}
	}
      closedir(dir);
    }
  }
}

int main(int argc, char *argv[]) {

	int		i;

	ProgName = argv[0];
	if (strlen(ProgName) >= 5)
		ProgName += (strlen(ProgName) - 5);

	for (i=1; i<argc; i++) {
		char *arg = argv[i];

		if (*arg=='-') {
			switch (arg[1]) {
			case 'd' :
				if (strcmp(arg+1, "display")) {
					usage();
					exit(1);
				}
				break;
			case 'g' :
				if (strcmp(arg+1, "geometry")) {
					usage();
					exit(1);
				}
				break;
			case 'v' :
				printversion();
				exit(0);
				break;
            case 'c' :
                if (argc > (i+1))
                {
                    strcpy(config_file, argv[i+1]);
                    i++;
                }
                break;
            default:
				usage();
				exit(0);
				break;
			}
		}
	}
	wmCheckMail_routine(argc, argv);

	return 0;
}

void		build_line(char *buf, int num, int index, Pop3 pc)
{
  int		len;
  int		pos;
  char		tmp[256];

  /* display spaces in case alias is less than 3 char long */
  memset(tmp, ' ', sizeof(char) * 3);
  memset(tmp + 3, 0, sizeof(char) * (256 - 3));
  memcpy(tmp, pc->alias, strlen(pc->alias));
  tmp[3] = ':';
  pos = 4;
  for (len = 0; len < MAIL_BUFLEN && pc->mails[num].from[len]; len++);
  memcpy(tmp + pos, pc->mails[num].from, len);
  tmp[pos + len] = '/';
  pos += len + 1;
  for (len = 0; len < MAIL_BUFLEN && pc->mails[num].subject[len]; len++);
  memcpy(tmp + pos, pc->mails[num].subject, len);
  len += pos;
  tmp[len++] = ' ';
  tmp[len++] = '*';
  tmp[len++] = ' ';
  tmp[len] = '\0';
  pos = index % len;
  if (len - pos < (NB_DISP + EXTRA)) { /* We are at the end of the string */
    memcpy(buf, tmp + pos, len - pos);
    memcpy(buf + len - pos, tmp, (NB_DISP + EXTRA) - len + pos);
  }
  else {
    memcpy(buf, tmp + pos, NB_DISP + EXTRA);
  }
}

void		display_index(int mail_index, int line, Pop3 pc)
{
#ifdef _DEBUG
  if (haspassed) {
    printf("  mail_index: %d, line: %d, todelete: %d\n",
	   mail_index, line, pc->mails[mail_index].todelete);
  }
#endif
  if (pc->mails[mail_index].todelete) {
    copyXPMArea(67, 12, 2, 5, 7, (line * 6) + TOP_MARGIN);
  }
  else {
    copyXPMArea(69, 11, 2, 6, 7, (line * 6) + TOP_MARGIN - 1);
  }
}

void		ClearDisplay() {
  int		i;

  copyXPMArea(72, 4, 3, 42, LEFT_MARGIN, 4);
  copyXPMArea(72, 4, 50, 42, 9, 4 );
  for (i = 0; i < NB_LINE; i++) {
    copyXPMArea(69, 11, 2, 6, 7, (i * 6) + TOP_MARGIN - 1);
  }
}

/* return < 0 if error
   0 if no pb
   else nb of mails which couldn't be deleted */
int	DeleteMail(Pop3 pc)
{
  int	etat = 0;
  int	old_sizeOfAllMessages;
  int	i;

  old_sizeOfAllMessages = pc->sizeOfAllMessages;
  BlitString(pc->alias, 10, TOP_MARGIN, 0);
  BlitString("connect", 10, 6*2 + TOP_MARGIN, 0);
  RedrawWindow();
  etat = pop3MakeConnection(pc, pc->popserver, pc->serverport);
  if (-1 != etat) {
    BlitString("login", 10, (6*3) + TOP_MARGIN, 0);
    RedrawWindow();
    etat = pop3Login(pc, pc->username, pc->password);
  }
  if (-1 != etat) {
    BlitString("chk cont", 10, (6*4) + TOP_MARGIN, 0);
    RedrawWindow();
    etat = pop3VerifStats(pc);
  }
  if (-1 != etat) {
    if (etat != old_sizeOfAllMessages) {
      BlitString("mailbox", 10, TOP_MARGIN, 0);
      BlitString("content", 10, 6 + TOP_MARGIN, 0);
      BlitString("changed", 10, 6*2 + TOP_MARGIN, 0);
      BlitString("between", 10, 6*3 + TOP_MARGIN, 0);
      BlitString("updates", 10, 6*4 + TOP_MARGIN, 0);
      BlitString("del can.", 10, 6*6 + TOP_MARGIN, 0);
      RedrawWindow();
      sleep(displaydelay);
      for (i = 0, etat = 0; i < pc->numOfMessages; i++) {
	etat += pc->mails[i].todelete;
      }
    }
    else {
      etat = 0;
      for (i = 0; i < pc->numOfMessages; i++) {
	if (pc->mails[i].todelete) {
	  etat += pop3DeleteMail(i + 1, pc);
	}
      }
    }
  }
  pop3Quit(pc);
  return (etat);
}

/*
void		launch_mail_client(int iS)
{
  int		i;
  int		j;
  char		str[16];
  char		**args;

  ClearDisplay();
  if ((args = conf[iS]->mailclient)) {
    BlitString("starting", 10, TOP_MARGIN, 0);
    for (i = 0; i < 5 && args[i]; i++) {
      for (j = 0; j < 8 && args[i][j]; j++);
      memcpy(str, args[i], j);
      str[j] = '\0';
      BlitString(str, 10, (i + 2)*6 + TOP_MARGIN, 0);
    }
    if (0 == fork()) {
      if (execvp(args[0], args)) {
	perror("execvp");
	copyXPMArea(72, 4, 3, 42, LEFT_MARGIN, 4);
	copyXPMArea(72, 4, 50, 6, 9, 4 );
	copyXPMArea(69, 11, 2, 6, 7, TOP_MARGIN - 1);
	BlitString("Error", 10, TOP_MARGIN, 0);
      }
    }
    else {
      conf[iS]->nextCheckTime = time(0) + 30;
    }
  }
  else {
    BlitString("  mail", 10, TOP_MARGIN, 0);
    BlitString(" client", 10, 6 + TOP_MARGIN, 0);
    BlitString("not  set", 10, 6*2 + TOP_MARGIN, 0);
    BlitString(" check", 15, 6*5 + TOP_MARGIN, 0);
    BlitString("wmpop3rc", 10, 6*6 + TOP_MARGIN, 0);
  }
  RedrawWindow();
  sleep(displaydelay);
}
*/

void		display_scrollbar(int index, int totalmessages,
				  int maxlines, int scrollmode)
{
  int		delta;
  int		scrollen;
  int		vertpos;

  if (totalmessages <= maxlines) {
#ifdef _DEBUG
    if (haspassed)
      printf("  full scrollbar\n");
#endif
    copyXPMArea((scrollmode) ? 68 : 65, 18, SCROLL_W,
		SCROLL_H + (2 * SCROLL_EXT), SCROLL_LX, SCROLL_TY);
    scrollbar.top = SCROLL_TY;
    scrollbar.bottom = SCROLL_TY + SCROLL_H;
    scrollbar.allowedspace = SCROLL_H;
  }
  else {
    delta = totalmessages - maxlines;
    /* determine the size of the scrollbar */
    if (0 >= (scrollen = SCROLL_H - ((SCROLL_H / maxlines) * delta)))
      scrollen = 1;
    /* determine the position */
    scrollbar.allowedspace = SCROLL_H - scrollen;
    vertpos = scrollbar.allowedspace * index / delta;
    copyXPMArea((scrollmode) ? 68 : 65, 18, SCROLL_W, SCROLL_EXT,
		SCROLL_LX, vertpos + SCROLL_TY);
    copyXPMArea((scrollmode) ? 68 : 65, 18 + SCROLL_EXT, SCROLL_W, scrollen,
		SCROLL_LX, vertpos + SCROLL_TY + SCROLL_EXT);
    copyXPMArea((scrollmode) ? 68 : 65, 18 + SCROLL_EXT + SCROLL_H,
		SCROLL_W, SCROLL_EXT,
		SCROLL_LX, vertpos + SCROLL_TY + SCROLL_EXT + scrollen);
    scrollbar.top = vertpos + SCROLL_TY;
    scrollbar.bottom = vertpos + SCROLL_TY + (SCROLL_EXT * 2) + scrollen;

#ifdef _DEBUG
    if (haspassed) {
      printf("  index: %d, totalmess:%d, mxli: %d, delta: %d, vertpos: %d, allowedspace: %d, sl:%d\n",
	     index, totalmessages, maxlines, delta, vertpos,
	     scrollbar.allowedspace, scrollen);
    }
#endif
  }
  /*  RedrawWindow(); */
}

int		is_for_each_mail(char **command)
{
  int		i;

  if (command) {
    for (i = 0; command[i]; i++) {
      if ('%' == command[i][0]) {
	if (('f' == command[i][1]) ||
	    ('s' == command[i][1]) ||
	    ('m' == command[i][1]) ||
	    ('n' == command[i][1]))
	  return (1);
      }
    }
  }
  return (0);
}

char		*quotify(char *str)
{
  char		*retour;
  int		len;

  len = strlen(str);
  if (NULL != (retour = (char *) malloc(sizeof(char) * len + 3))) {
    retour[0] = '\'';
    memcpy(retour + 1, str, len);
    retour[len + 1] = '\'';
    retour[len + 2] = '\0';
  }
  return (retour);
}

/* nb: number of the mail on the server - 1 (if -1: for all mails)
   path: allocated buffer to store path of tmp file
   newonly: only for new messages
   onlyselected: only for selected messages
   pc: main struct.
   on success return 0 */
int		writemailstofile(int nb, char *path, int newonly,
				 int onlyselected, Pop3 pc)
{
  int		fd;
  int		len;
  int		i;
  int		retour = 0;
  int		goforwritemail = 0;
  int		mustdisconnect = 0;

  len = strlen(tempdir);
  if (len) {
    path[0] = '\0';
    strcat(path, tempdir);
    if ('/' != tempdir[len - 1])
      strcat(path, "/");
    strcat(path, TMPPREFIX);
    strcat(path, "XXXXXX");
#ifdef _DEBUG
    printf("  creating temporary file [%s]\n", path);
    printf("  nb=%d, newonly=%d, onlyselected=%d\n",
	   nb, newonly, onlyselected);
#endif
    if (-1 == (fd = mkstemp(path))) {
      fprintf(stderr, "Error: writing mail to file\n");
      perror(path);
      retour++;
    }
    else {
      /* to prevent connecting many times, do it now. */
      if (NOT_CONNECTED == pc->connected) {
#ifdef _DEBUG
	printf("  writemailstofile not connected, connecting\n");
#endif
	if (pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
	  return (1);
	}
	if (pop3Login(pc, pc->username, pc->password) == -1) {
	  return (1);
	}
	mustdisconnect = 1;
      }

      if (nb < 0) {
	/* concatenate all the mails into 1 file */
	for (i = 0; i < pc->numOfMessages; i++) {
	  goforwritemail = 0;
#ifdef _DEBUG
	  printf("  mail %d:", i);
#endif
	  if (!newonly && !onlyselected) {
#ifdef _DEBUG
	    printf("  !newonly && !onlyselected\n");
#endif
	    goforwritemail = 1;
	  }
	  else if (newonly) {
	    if (pc->mails[i].new &&
		(!onlyselected || (onlyselected && pc->mails[i].todelete))) {
#ifdef _DEBUG
	      printf("  newonly\n");
#endif
	      goforwritemail = 1;
	    }
	  }
	  else if (onlyselected && pc->mails[i].todelete) {
#ifdef _DEBUG
	    printf("  onlyselected\n");
#endif
	    goforwritemail = 1;
	  }
	  if (goforwritemail) {
	    /* put the mail separator */
	    if (strlen(pc->mailseparator)) {
#ifdef _DEBUG
	      printf("  pc->mailseparator: [%s]\n", pc->mailseparator);
#endif
	      write(fd, pc->mailseparator, strlen(pc->mailseparator));
	    }
	    else {
#ifdef _DEBUG
	      printf("  TXT_SEPARATOR: [%s]\n", TXT_SEPARATOR);
#endif
	      write(fd, TXT_SEPARATOR, strlen(TXT_SEPARATOR));
	    }
	    if (pop3WriteOneMail(i + 1, fd, pc)) {
	      retour++;
	    }
	  }
	}

      }
      else {
	if (pop3WriteOneMail(nb + 1, fd, pc))
	  retour++;
      }
      close(fd);
      /* close the connection if we've opened it */
      if (mustdisconnect) {
#ifdef _DEBUG
	printf("  writemailstofile disconnecting\n");
#endif
	pop3Quit(pc);
      }
    }
  }
  else {
    fprintf(stderr, "no tempdir configured, can't create file\n");
    retour++;
  }
  return (retour);
}

/*
 * do_command_completion
 * returned array should be freed by calling function
 * if nbnewmail == 0, for %c option concatenate _all_ the messages
 */
char		**do_command_completion(int num, char **command,
					int nbnewmail, Pop3 pc)
{
  char		**retour;
  int		i;
  int		yaerreur = 0;
  char		path[1024];

  for (i = 0; command[i]; i++);
#ifdef _DEBUG
  printf("  %d args to the command, mail num %d\n", i, num);
#endif
  if (NULL == (retour = (char **) malloc (sizeof(char *) * i + 1))) {
    return (NULL);
  }
  memset(retour, 0, sizeof(char *) * i + 1);
  for (i = 0; command[i]; i++) {
#ifdef _DEBUG
    printf("  arg %d: [%s]\n", i, command[i]);
#endif
    if ('%' == command[i][0]) {
      switch (command[i][1]) {
      case 'T': /* total nb of mails */
	if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
	  sprintf(retour[i], "%d", pc->numOfMessages);
	else
	  yaerreur = 1;
	break;
      case 't': /* total nb of new mails */
	if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
	  sprintf(retour[i], "%d", (nbnewmail < 0) ? 0 : 1);
	else
	  yaerreur = 1;
	break;
      case 'C': /* concatenate all the selected mails in 1 file */
	if (writemailstofile(-1, path, 0, SELECTONLY, pc))
	  yaerreur = 1;
	else
	  if (NULL == (retour[i] = strdup(path))) {
	    yaerreur = 1;
	  }
	break;
      case 'c': /* concatenate all the mails in 1 file */
	if (writemailstofile(-1, path, (nbnewmail > 0), NOSELECTONLY, pc))
	  yaerreur = 1;
	else
	  if (NULL == (retour[i] = strdup(path))) {
	    yaerreur = 1;
	  }
	break;
      case 'f': /* from field */
#ifdef _DEBUG
	printf("  from field: [%s]\n", pc->mails[num].from);
#endif
	if (NULL == (retour[i] = quotify(pc->mails[num].from)))
	  yaerreur = 1;
	break;
      case 's': /* subject of the mail */
#ifdef _DEBUG
	printf("  subject field: [%s]\n", pc->mails[num].subject);
#endif
	if (NULL == (retour[i] = quotify(pc->mails[num].subject)))
	  yaerreur = 1;
	break;
      case 'm': /* copy the mail to tmp file */
	if (0 <= num) {
	  if (writemailstofile(num, path, (nbnewmail > 0), NOSELECTONLY, pc))
	    yaerreur = 1;
	  else
	    if (NULL == (retour[i] = strdup(path))) {
	      yaerreur = 1;
	  }
	}
	break;
      case 'n': /* number of the message on the mail server */
	if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
	  sprintf(retour[i], "%d", num + 1);
	else
	  yaerreur = 1;
	break;
      case 'S': /* server name */
	if (NULL == (retour[i] = strdup(pc->popserver)))
	  yaerreur = 1;
	break;
      case 'a': /* server alias */
	if (NULL == (retour[i] = strdup(pc->alias)))
	  yaerreur = 1;
	break;
      case 'u': /* user name */
	if (NULL == (retour[i] = strdup(pc->username)))
	  yaerreur = 1;
	break;
      case 'w': /* user password */
	if (NULL == (retour[i] = strdup(pc->password)))
	  yaerreur = 1;
	break;
      case 'P': /* server port */
	if (NULL != (retour[i] = (char *) malloc(sizeof(char) * 8)))
	  sprintf(retour[i], "%d", pc->serverport);
	else
	  yaerreur = 1;
	break;
      case '%': /* % character, leave in place */
	 if (NULL == (retour[i] = strdup(command[i])))
	   yaerreur = 1;
	break;
      default:
	break;
      }
    }
    else {
#ifdef _DEBUG
      printf("    just copying arg [%s]\n", command[i]);
#endif
      if (NULL == (retour[i] = strdup(command[i])))
	yaerreur = 1;
    }
  }
  retour[i] = NULL;
#ifdef _DEBUG
  printf("  retour: %ld\n", (long) retour);
#endif
  if (!yaerreur)
    return (retour);
  else
    return (NULL);
}

/* num is the index of the mail in the mail array
   if num == -1, means that the command isn't for each mail */


void		spawn_command(int num, char **command, int nbnewmail,
			      char *display, Pop3 pc)
{
  char		**tmpcommand;
  char		str[16];
  int		i, j;

  if (display) {
    ClearDisplay();
    if (!command) {
      BlitString(display, 10, 6 + TOP_MARGIN, 0);
      BlitString("not  set", 10, 6*2 + TOP_MARGIN, 0);
      BlitString(" check", 15, 6*5 + TOP_MARGIN, 0);
      BlitString("wmpop3rc", 10, 6*6 + TOP_MARGIN, 0);
    }
    else {
      BlitString("starting", 10, TOP_MARGIN, 0);
      for (i = 0; i < 5 && command[i]; i++) {
	for (j = 0; j < 8 && command[i][j]; j++);
	memcpy(str, command[i], j);
	str[j] = '\0';
	BlitString(str, 10, (i + 2)*6 + TOP_MARGIN, 0);
      }
      RedrawWindow();
    }
  }
  if (command) {
    /* check for any '%' sign in the command and complete it */
    tmpcommand = do_command_completion(num, command, nbnewmail, pc);
    if (tmpcommand) {
      /* launch the command in a new process */
      if (0 == fork()) {
#ifdef _DEBUG
	printf("  spawning command: [");
	for (i = 0; tmpcommand[i]; i++) {
	  printf("  %s ", tmpcommand[i]);
	}
	printf("]\n");
#endif
	if (execvp(tmpcommand[0], tmpcommand)) {
	  perror("execvp");
	}
      }
      else {
	if (display) {
	  /* set the check delay to 30 seconds */
	  pc->nextCheckTime = time(0) + 30;
	}
	/* free the memory (in the parent process...) */
	for (i = 0; tmpcommand[i]; i++) {
	  free (tmpcommand[i]);
	}
	free (tmpcommand);
      }
    }
    else {
      if (display) {
	ClearDisplay();
	BlitString(" Error", 15, TOP_MARGIN, 0);
	BlitString(" While", 15, 6*2 + TOP_MARGIN, 0);
	BlitString("parsing", 15, 6*3 + TOP_MARGIN, 0);
	BlitString("command", 15, 6*4 +TOP_MARGIN, 0);
	BlitString(display, 10, 6*6 + TOP_MARGIN, 0);
	fprintf(stderr, "Error while parsing %s\n", display);
      }
      else
	fprintf(stderr, "Error while parsing command\n");
    }
  }
  if (display) {
    RedrawWindow();
    sleep(displaydelay);
  }
}

/*
 * wmCheckMail_routine : This function is used to set up the X display
 *           for wmpop3 and check for mail every n number of minutes.
 */

void		wmCheckMail_routine(int argc, char **argv){

  int		buttonStatus   = -1;
  int		iS;
  Pop3		pc;
  int		i, j, k;
  XEvent	Event;
  char		str[256];
  int		index = 0;
  int		fragment = 0;
  int		index_vert = 0;
  int		oldnbmess = 0;
  int		nbsel;
  int		selectedmess;
  int		justreloaded;
  long		thistime;
  char		*linestodel[7];
  int		unreachable;
  long		sleeplenght;
  int		scrollmode = 0;
  int		nbnewmail;
  char		separ;

  if( !strcmp( config_file, "not-defined") )
    sprintf(config_file, "%s/.wmpop3rc", getenv("HOME"));

  if( readConfigFile(config_file) == -1){
    exit(0);
  }
  /* Set up timer for checking mail */
  createXBMfromXPM(wminet_mask_bits, wmpop3_xpm
		   , wminet_mask_width, wminet_mask_height);

  openXwindow(argc, argv, wmpop3_xpm, wminet_mask_bits
	      , wminet_mask_width, wminet_mask_height);

  AddMouseRegion(0, 19, 49, 30, 58); /* check button */
  AddMouseRegion(1, 46, 49, 50, 58 ); /* autocheck button   */
  AddMouseRegion(2, 53, 49, 57, 58 ); /* switch display button  */
  AddMouseRegion(3, 5, 49, 16, 58 ); /* delete button */
  AddMouseRegion(4, 33, 49, 44, 53); /* top arrow */
  AddMouseRegion(5, 33, 54, 44, 58); /* botton arrow */
  /* add the mouse regions for each line */
  for (i = 0; i < NB_LINE; i++) {
    AddMouseRegion(6 + i, 9, (i*6) + TOP_MARGIN,
		   58, (i*6) + TOP_MARGIN + CHAR_HEIGHT);
  }


  /* Check if Autochecking is on or off */
  if(autoChecking == NO ){
    copyXPMArea(142, 38, 7, 11, 45, 48);
  }
  else {
    copyXPMArea(142, 49, 7, 11, 45, 48);
  }

  RedrawWindow();

  summess = 0;

  deleteoldtmpfiles();

  sleeplenght = (long) 20000L + (20000L - (20000L * scrollspeed / 100));
  while (1) {
    RSET_COLOR;
    for (iS = 0; iS < nb_conf; iS++) {
      pc = conf[iS];
      if( (((time(0) > pc->nextCheckTime) ||
	    (pc->nextCheckTime == 0)) && ( autoChecking == YES))
	  || (pc->forcedCheck == YES)){
	justreloaded = 1;
	ClearDisplay();
	BlitString(pc->alias, 10, TOP_MARGIN, 0);
	BlitString("connect", 10, (6*2) + TOP_MARGIN, 0);
	RedrawWindow();
	pc->status = 0;
	if(pop3MakeConnection(pc,pc->popserver,pc->serverport) == -1){
	  pc->status = 1;
	}
	if (!pc->status) {
	  BlitString("login", 10, (6*3) + TOP_MARGIN, 0);
	  RedrawWindow();
	  if (pop3Login(pc, pc->username, pc->password) == -1 )
	    pc->status = 2;
	}
	if (!pc->status) {
	  BlitString("get mail", 10, (6*4) + TOP_MARGIN, 0);
	  RedrawWindow();
	  if (pop3CheckMail(pc) == -1)
	    pc->status = 3;
	}
	pc->nextCheckTime = time(0) + (pc->mailCheckDelay * SEC_IN_MIN);
	index = 0;
	pc->forcedCheck = NO;
	/* check if new mail has arrived */
	for (i = 0, nbnewmail = 0; i < pc->numOfMessages; i++)
	  if (pc->mails[i].new)
	    nbnewmail++;
	/* launch the new mail command */
	if (pc->newmailcommand && (-1 != pc->sizechanged)) {
	  if (nbnewmail) {
#ifdef _DEBUG
	    printf("  %d New mail(s) ha(s)(ve) arrived!\n", nbnewmail);
#endif
	    if (is_for_each_mail(pc->newmailcommand)) {
	      for (i = 0; i < pc->numOfMessages; i++)
		if (pc->mails[i].new)
		  spawn_command(i, pc->newmailcommand, nbnewmail, NULL, pc);
	    }
	    else {
	      spawn_command(-1, pc->newmailcommand, nbnewmail, NULL, pc);
	    }
	  }
	}
	/* close the connection */
	pop3Quit(pc);
	pc->sizechanged = 0;
      }
    }
    waitpid(0, NULL, WNOHANG);
    /* reset the number of messages */
    unreachable = 1;
    for (summess = 0, iS = 0; iS < nb_conf; iS++) {
      pc = conf[iS];
      if (!pc->status) {
	unreachable = 0;
	summess += pc->numOfMessages;
      }
    }
    /* set the offset from the beginning of the list */
    if (summess != oldnbmess) {
      oldnbmess = summess;
      if (summess < NB_LINE)
	index_vert = 0;
      else {
	index_vert = summess - NB_LINE;
      }
    }
    memset(str, 0, 128);
    /* clear the display */
    ClearDisplay();
    nbsel = 0;
    for (iS = 0; iS < nb_conf; iS++) {
      pc = conf[iS];
      for (i = 0; i < summess && i < pc->numOfMessages; i++) {
#ifdef _DEBUG
	if (haspassed) {
	  printf("  %s, mails[%d], todelete=%d\n",
	       pc->alias, i, pc->mails[i].todelete);
	}
#endif
	nbsel += pc->mails[i].todelete;
      }
    }
    if (justreloaded) {
      /* make sure we display the correct buttons */
      justreloaded = 0;
      if ((NO == newMessagesOnly) && nbsel)
	copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
      else
	copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
    }
    if (newMessagesOnly == YES ){
      /* Show messages waiting */
      RSET_COLOR;
      for (color = 0, iS = 0; iS < nb_conf; iS++) {
	pc = conf[iS];
	if (pc->countunreadonly)
	  separ = '-';
	else
	  separ = ':';
	switch(pc->status) {
	case 1:
	  sprintf(str, "%-3s%cC*ER", pc->alias, separ);
	  break;
	case 2:
	  sprintf(str, "%-3s%cL*ER", pc->alias, separ);
	  break;
	case 3:
	  sprintf(str, "%-3s%cM*ER", pc->alias, separ);
	  break;
	default:
	  sprintf(str, "%-3s%c %3d", pc->alias, separ,
		  (pc->countunreadonly) ? pc->numOfUnreadMessages :
		  pc->numOfMessages);
	  break;
	}
	BlitString(str, 10, (int) (6*iS) + TOP_MARGIN, 0);
	SWAP_COLOR;
      }
      RSET_COLOR;
      sprintf(str, "sel.: %2d", nbsel);
      BlitString(str, 10, (int) (6*6) + TOP_MARGIN, 0);
    }
    else {
      RSET_COLOR;
      if (0 == summess) {
	if (unreachable) {
	  BlitString(" error", 10, TOP_MARGIN, 0);
	}
	else {
	  BlitString("No  Mesg", 10, TOP_MARGIN, 0);
	}
	if (autoChecking == YES) {
	  BlitString("  next", 10, 6*2 + TOP_MARGIN, 0);
	  BlitString(" update", 10, 6*3 + TOP_MARGIN, 0);
	  j = SEC_IN_MIN * 1000;
	  thistime = time(0);
	  for (i = 0, k = 0; i < nb_conf; i++) {
	    if ((conf[i]->nextCheckTime - thistime) < j) {
	      j = conf[i]->nextCheckTime - thistime;
	      k = i;
	    }
	  }
	  sprintf(str, " is:%s", conf[k]->alias);
	  BlitString(str, 10, 6*4 + TOP_MARGIN, 0);
	  BlitString("   in", 10, 6*5 + TOP_MARGIN, 0);
	  sprintf(str, "%-5d s.", j);
	  BlitString(str, 10, 6*6 + TOP_MARGIN, 0);
	}
      }
      else {
	RSET_COLOR;
	/* iS = index in the conf struct
	   i = index of the mail
	   j = line nb on display */
	memset(linestodel, 0, sizeof(char *));
	for (iS = 0, j = 0; iS < nb_conf && j < NB_LINE + index_vert; iS++) {
	  pc = conf[iS];
	  for (i = 0; (j < NB_LINE + index_vert) && i < pc->numOfMessages;
	       j++, i++) {
	    if (j >= index_vert) {
	      build_line(str, i, index, pc);
	      BlitString(str, 10, ((j - index_vert) * 6) + TOP_MARGIN,
			 fragment);
	      display_index(i, (j - index_vert), pc);
	      /* store the address of the delete flag, so that it will */
	      /* be easier to modify it afterwards */
	      linestodel[j - index_vert] = &(pc->mails[i].todelete);
	    }
	  }
	  SWAP_COLOR;
	}
	display_scrollbar(index_vert, summess, NB_LINE, scrollmode);
      }
      fragment++;
      if (0 == (fragment % (CHAR_WIDTH + 1))) {
	index++;
	fragment = 0;
	/*	printf("index=%d, fragment=%d\n", index, fragment); */
      }
    }
#ifdef _DEBUG
    haspassed = 0;
#endif

    RedrawWindow();

    RSET_COLOR;
    /* X Events */
    while (XPending(display)){
      XNextEvent(display, &Event);
      switch (Event.type) {
      case Expose:
	RedrawWindow();
	break;
      case DestroyNotify:
	XCloseDisplay(display);
	exit(0);
	break;
      case MotionNotify:
	if (scrollmode) {
#ifdef _DEBUG
	  printf("  ca bouge... index_vert before = %d, %d x %d, allowedspace: %d, summess: %d\n",
		 index_vert,
		 Event.xbutton.x, Event.xbutton.y,
		 scrollbar.allowedspace,
		 summess);

#endif
	  if (summess > NB_LINE) {
	    index_vert = scrollbar.orig_index_vert +
	      ((Event.xbutton.y  - scrollbar.orig_y) * (summess - NB_LINE) /
	       scrollbar.allowedspace);
	    if (0 > index_vert)
	      index_vert = 0;
	    if (index_vert + NB_LINE > summess)
	      index_vert = summess - NB_LINE;
	  }
#ifdef _DEBUG
	  printf("  deplacement de %d pixels --> index_vert = %d\n",
		 Event.xbutton.y  - scrollbar.orig_y, index_vert);
#endif
	}
	break;
      case ButtonPress:
	buttonStatus = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
	if (buttonStatus >= 0){
	  switch (buttonStatus){
	  case 0 : /* check / open button pressed */
	    if ((NO == newMessagesOnly) && nbsel)
	      copyXPMArea(128, 60 ,14 ,11 ,18 ,48 );
	    else
	      copyXPMArea(128,38 ,14 ,11 ,18 ,48 );
	    break;
	  case 1 : /* autocheck button pressed */
	    break;
	  case 2: /* switch display button pressed */
	    break;
	  case 3: /* delete button pressed */
	    copyXPMArea(127, 15, 14, 11, 4, 48);
	    break;
	  case 4: /* top arrow button pressed */
	    break;
	  case 5: /* bottom arrow button pressed */
	    break;
	  default:
	    break;
	  }
	  RedrawWindow();
	}
	else if (SCROLL_LX <= Event.xbutton.x && SCROLL_RX >= Event.xbutton.x
		 && scrollbar.top <= Event.xbutton.y &&
		 scrollbar.bottom >= Event.xbutton.y) {
	  scrollbar.orig_y = Event.xbutton.y;
	  scrollbar.orig_index_vert = index_vert;
	  scrollmode = 1;
	}
	break;
      case ButtonRelease:
	i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);

	if (buttonStatus == i && buttonStatus >= 0){
	  switch (buttonStatus){
	  case 0 :   /* check button */
	    if (nbsel && !newMessagesOnly) {
	      copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
	      /* this is where you launch the open mail command */
	      for (iS = 0; iS < nb_conf; iS++) {
		pc = conf[iS];
		for (i = 0, selectedmess = 0; i < pc->numOfMessages; i++) {
		  if (pc->mails[i].todelete) {
		    selectedmess = 1;
		    break;
		  }
		}
		if (selectedmess) {
#ifdef _DEBUG
		  printf("  launching selectedmesgcommand command for conf %d\n",
			 iS);
#endif

		  if (is_for_each_mail(pc->selectedmesgcommand)) {
#ifdef _DEBUG
		    if (!pc->numOfMessages) {
		      printf("  command is for each mail but there's no mail\n");
		    }
		    else
		      printf("  command is for each mail\n");
#endif
		    for (i = 0; i < pc->numOfMessages; i++)
		      spawn_command(i, pc->selectedmesgcommand, 0,
				    "selectm.", pc);
		  }
		  else {
		    spawn_command(-1, pc->selectedmesgcommand, 0,
				  "selectm.", pc);
		  }
		}
	      }
	    }
	    else {
	      copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
	      for (iS = 0; iS < nb_conf; iS++)
		conf[iS]->forcedCheck = YES;
	    }
	    break;
	  case 1 :   /* autocheck Button */
	    if (autoChecking == YES){
	      autoChecking = NO;
	      copyXPMArea(142, 38, 7, 11, 45, 48);
	    }
	    else {
	      autoChecking = YES;
	      for (iS = 0; iS < nb_conf; iS++)
		conf[iS]->nextCheckTime = time(0) +
		  (conf[iS]->mailCheckDelay * SEC_IN_MIN);
	      copyXPMArea(142, 49, 7, 11, 45, 48);
	    }
	    break;
 	  case 2:  /* switch display Button */
	    index = 0;
	    /* change view on # of messages */
	    if( newMessagesOnly == YES ) {
	      newMessagesOnly = NO;
	      copyXPMArea(149,38 , 7 , 11, 52, 48);
	      if (nbsel) {
		copyXPMArea(128,49,14,11,18,48);
	      }
	      else {
		copyXPMArea(128,27,14,11,18,48);
	      }
	    }
	    else {
	      newMessagesOnly = YES;
	      copyXPMArea(149,49 , 7 , 11, 52, 48);
	      copyXPMArea(128,27,14,11,18,48);
	    }
#ifdef _DEBUG
	    haspassed = 1;
#endif
	    break;
	  case 3: /* delete button */
	    copyXPMArea(143, 15, 14, 11, 4, 48);
	    j = 0;
	    RSET_COLOR;
	    for (iS = 0; iS < nb_conf; iS++) {
	      pc = conf[iS];
	      for (i = 0, k = 0; i < pc->numOfMessages; i++)
		k += pc->mails[i].todelete;
	      if (k) {
		/* clear the display */
		ClearDisplay();
		k = DeleteMail(pc);
		if (k < 0) {
		  sprintf(pc->delstatus, "%-3s: Err", pc->alias);
		}
		else if (k > 0) {
		  sprintf(pc->delstatus, "%-3s/D:%2d", pc->alias, k);
		}
		else
		  sprintf(pc->delstatus, "%-3s:  ok", pc->alias);
		pc->forcedCheck = YES;
	      }
	      else {
		sprintf(pc->delstatus, "%-3s:none", pc->alias);
	      }
	    }
	    /* clear the display */
	    ClearDisplay();
	    RSET_COLOR;
	    for (iS = 0; iS < nb_conf; iS++) {
	      BlitString(conf[iS]->delstatus, 10, 6*iS + TOP_MARGIN, 0);
	      SWAP_COLOR;
	    }
	    RedrawWindow();
	    sleep(displaydelay);
	    break;
	  case 4: /* top arrow button pressed */
	    index_vert--;
	    if (0 > index_vert)
	      index_vert = 0;
#ifdef _DEBUG
	    haspassed = 1;
#endif
	    break;
	  case 5: /* bottom arrow button pressed */
	    if (summess > NB_LINE) {
	      index_vert++;
	      if (index_vert + NB_LINE > summess)
		index_vert = summess - NB_LINE;
	    }
#ifdef _DEBUG
	    haspassed = 1;
#endif
	    break;
	  default:
	    if (newMessagesOnly == NO) { /* message view mode */
	      if ((5 < buttonStatus) && (buttonStatus <= 5 + NB_LINE)) {
		if ((buttonStatus - 6 + index_vert) < summess) {
		  /* first update lines to del */
		  *(linestodel[buttonStatus - 6]) =
		    1 - *(linestodel[buttonStatus - 6]);
#ifdef _DEBUG
		  printf("  button %d pressed, j'update lines to del\n",
			 buttonStatus - 6);
		  haspassed = 1;
#endif
		  nbsel = 0;
		  for (iS = 0; iS < nb_conf; iS++) {
		    pc = conf[iS];
		    for (i = 0; i < pc->numOfMessages; i++) {
		      nbsel += pc->mails[i].todelete;
#ifdef _DEBUG
		      printf("  conf %d, mail %d, todelete = %d\n",
			     iS, i, pc->mails[i].todelete);
#endif
		    }
		  }
		  /* display open or reload buttons */
		  if (nbsel) {
		    copyXPMArea(128,49,14,11,18,48);
		  }
		  else {
		    copyXPMArea(128,27,14,11,18,48);
		  }
		}
	      }
	    }
	    else { /* summary view mode */
	      if ((5 < buttonStatus) && (buttonStatus <= 5 + nb_conf)) {
		if ((Event.xbutton.x > 10) &&
		    (Event.xbutton.x < (10 + (4 * (CHAR_WIDTH + 1))))) {
#ifdef _DEBUG
		  printf("  launching command for conf %d\n",
			 buttonStatus - 6);
#endif
		  pc = conf[buttonStatus - 6];
		  if (is_for_each_mail(pc->mailclient)) {
#ifdef _DEBUG
		    if (!pc->numOfMessages) {
		      printf("  command is for each mail but there's no mail\n");
		    }
#endif
		    for (i = 0; i < pc->numOfMessages; i++)
		      spawn_command(i, pc->mailclient, nbnewmail,
				    "mailcli.", pc);
		  }
		  else {
		    spawn_command(-1, pc->mailclient, nbnewmail,
				  "mailcli.", pc);
		  }
		}
		else if ((Event.xbutton.x > (10 + (4 * (CHAR_WIDTH + 1)))) &&
			 (Event.xbutton.x < (10 + (8 * (CHAR_WIDTH + 1))))) {
		  /* swap view mode */
		  conf[buttonStatus - 6]->countunreadonly =
		    1 - conf[buttonStatus - 6]->countunreadonly;
#ifdef _DEBUG
		  printf("  swapping view mode for conf %d: %s\n",
			 buttonStatus - 6,
			 (conf[buttonStatus - 6]->countunreadonly) ?
			 "UnreadMessages" : "TotalMessages");

#endif
		}
	      }
	      else if ((5 + NB_LINE) == buttonStatus) {
		/* status summary line pressed */
		if ((Event.xbutton.x > 10) &&
		    (Event.xbutton.x < (10 + (4 * (CHAR_WIDTH + 1))))) {
		  /* select all messages */
		  for (iS = 0; iS < nb_conf; iS++) {
		    for (pc = conf[iS], i = 0; i < pc->numOfMessages; i++) {
		      pc->mails[i].todelete = 1;
		    }
		  }
		}
		else if ((Event.xbutton.x > (10 + (4 * (CHAR_WIDTH + 1)))) &&
			 (Event.xbutton.x < (10 + (8 * (CHAR_WIDTH + 1))))) {
		  /* unselect all messages */
		  for (iS = 0; iS < nb_conf; iS++) {
		    for (pc = conf[iS], i = 0; i < pc->numOfMessages; i++) {
		      pc->mails[i].todelete = 0;
		    }
		  }
		}
	      }
	    }
	    break;
	  }
	}
	else {
	  if (buttonStatus >= 0) {
	    /* button has been pressed correctly but released somewhere else */
	    switch(buttonStatus) {
	    case 0: /* check button was pressed */
	      if ((NO == newMessagesOnly) && nbsel)
		copyXPMArea(128,49 ,14 ,11 ,18 ,48 );
	      else
		copyXPMArea(128,27 ,14 ,11 ,18 ,48 );
	      break;
	    case 3: /* delete button was pressed */
	      copyXPMArea(143, 15, 14, 11, 4, 48);
	      break;
	    }
	  }
	}
	RedrawWindow();
	buttonStatus = -1;
	scrollmode = 0;
	break;
      }
    }
    usleep(sleeplenght);
  }
}


/*
 * usage : Prints proper command parameters of wmpop3.
 */
void usage(void)
{
  fprintf(stdout, "\nWMPop3LB - Louis-Benoit JOURDAIN (wmpop3lb@jourdain.org)\n");
  fprintf(stdout, "based on the work by Scott Holden <scotth@thezone.net>\n\n");
  fprintf(stdout, "usage:\n");
  fprintf(stdout, "    -display <display name>\n");
  fprintf(stdout, "    -geometry +XPOS+YPOS      initial window position\n");
  fprintf(stdout, "    -c <filename>             use specified config file\n");
  fprintf(stdout, "    -h                        this help screen\n");
  fprintf(stdout, "    -v                        print the version number\n");
  fprintf(stdout, "\n");
}

void printversion(void)
{
  fprintf(stdout, "wmpop3 v%s\n", WMPOP3_VERSION);
}

// Blits a string at given co-ordinates
void BlitString(char *name, int x, int y, int fragment)
{
  int		i;
  int		c;
  int		k;
  int		row;

  /*  printf("--name: [%s] \n", name); */
  for (i = 0, k = x; name[i]; i++) {
    c = toupper(name[i]);
    if (c >= 'A' && c <= 'Z') {   /* its a letter */
      c -= 'A';
      row = LETTERS;
    }
    else if (c >= '0' && c <= '9') {   /* its a number */
      c -= '0';
      row = NUMBERS;
    }
    else switch(c) {
    case '-':
      c = 26;
      row = LETTERS;
      break;
    case '*':
      c = 27;
      row = LETTERS;
      break;
    case ':':
      c = 10;
      row = NUMBERS;
      break;
    case '/':
      c = 11;
      row = NUMBERS;
      break;
    case '@':
      c = 12;
      row = NUMBERS;
      break;
    case '%':
      c = 15;
      row = NUMBERS;
      break;
    case ' ':
      c = 13;
      row = NUMBERS;
      break;
    case '.':
      c = 28;
      row = LETTERS;
      break;
    default:
      c = 14;
       row = NUMBERS;
       break;
    }
    /*    printf("c:%2d (%c), fragment: %d, i:%d, k=%d ",
	  c, name[i], fragment, i, k); */
    if (i > 0 && i < NB_DISP) {
      copyXPMArea(c * CHAR_WIDTH, CH_COLOR(row), CHAR_WIDTH + 1, CHAR_HEIGHT,
		  k, y);
      /*      printf(" - k1: %d += %d + 1", k, CHAR_WIDTH); */
      k += CHAR_WIDTH + 1;
    }
    else if (0 == i) {
      copyXPMArea(c * CHAR_WIDTH + fragment, CH_COLOR(row),
		  CHAR_WIDTH + 1 - fragment, CHAR_HEIGHT,
		  k, y);
      /*      printf(" - k2: %d += %d + 1 - %d", k, CHAR_WIDTH, fragment); */
      k += CHAR_WIDTH + 1 - fragment;
    }
    else if (fragment && (NB_DISP == i)) {
      copyXPMArea(c * CHAR_WIDTH, CH_COLOR(row), fragment + 1, CHAR_HEIGHT,
		  k, y);
      /*       printf(" - k3: %d += %d ", k, fragment); */
      k += fragment;
    }
    /*    printf("  -- apres k=%d\n", k); */
  }
}


/* Blits number to given coordinates...*/

void BlitNum(int num, int x, int y, int todelete)
{
  if (todelete)
    num += 19;
  copyXPMArea(((num - 1) * (SN_CHAR_W + 1)) + 1, CH_COLOR(SMALL_NUM),
	      SN_CHAR_W, CHAR_HEIGHT + 1, x, y);
}

int	parsestring(char *buf, char *data, int max, FILE *fp)
{
  char	*deb;
  char	*end;
  char	*bal;
  int	go = 1;
  int	linelen = 0;

  /* trim the leading spaces */
  memset(data, 0, max);
  for (deb = buf; *deb && isspace(*deb); deb++);
  if (!*deb)
    return (-1);
  if ('"' == *deb) {
    ++deb;
    bal = data;
    while (go) {
#ifdef _DEBUG
      printf("  line to parse: [%s]\n", deb);
#endif
      /* get to the end of the line */
      for (end = deb; *end && ('"' != *end); end++);
      if (!*end) { /* this is a multiline entry */
	linelen += (int) (end - deb);
	if (linelen > max) {
#ifdef _DEBUG
	  printf("  maximum line length reached\n");
#endif
	  return (-1);
	}
	memcpy(bal, deb, (int) (end - deb));
	bal = data + linelen;
	if (fgets(buf, CONF_BUFLEN, fp)) {
	  deb = buf;
	}
	else { /* end of file reached */
	  return (-1);
	}
      }
      else {
	memcpy(bal, deb, end - deb);
	go = 0;
      }
    }
  }
  else {
    for (end = deb; *end && !isspace(*end); end++);
    memcpy(data, deb, ((end - deb) > max) ? max : end - deb);
  }
#ifdef _DEBUG
  printf("  parsed string (len=%d) : [%s]\n", strlen(data), data);
#endif
  return (0);
}

int	parsenum(char *buf, int *data)
{
  char	*deb;
  char	*end;
  char	temp[32];

  memset(temp, 0, 32);
  for (deb = buf; *deb && isspace(*deb); deb++);
  if (!*deb)
    return (-1);
  if ('"' == *deb) {
    for (end = ++deb; *end && ('"' != *end); end++);
    if (!*end)
      return (-1);
    memcpy(temp, deb, end - deb);
    *data = atoi(temp);
  }
  else {
    for (end = deb; *end && !isspace(*end); end++);
    memcpy(temp, deb, end - deb);
    *data = atoi(temp);
  }
  return (0);
}

char		**build_arg_list(char *buf, int len)
{
  int		espaces;
  int		i, j;
  char		**retour;

  /* count number of args */
  for (espaces = 0, i = 0; buf[i] && i < len; i++)
    if (isspace(buf[i]))
      espaces++;
  /* allocate space for the structure */
  if (NULL == (retour = (char **) malloc(sizeof(char *) * espaces + 2)))
    return (NULL);
  /* get each arg one by one */
  for (i = 0, j = 0; j < len && i < 256; i++) {
    /* get the end of the arg */
    for (espaces = j; espaces < len && !isspace(buf[espaces]); espaces++);
    /* allocate space for the arg */
    if (0 == (retour[i] = malloc(sizeof(char) * (espaces - j) + 1))) {
      /* free what has been allocated */
      for (j = 0; j < i; j++)
	free(retour[j]);
      return (NULL);
    }
    memcpy(retour[i], buf +  j, espaces - j);
    retour[i][espaces - j] = '\0';
    j = espaces + 1;
  }
  retour[i] = 0;
  return (retour);
}


int		readConfigFile( char *filename ){
    char	buf[CONF_BUFLEN];
    char	tmp[CONF_BUFLEN];
    FILE	*fp;
    char	*bal;

    if( (fp = fopen( filename, "r")) == 0 ){
        sprintf(config_file, "%s/.wmpop3rc", getenv("HOME"));
        fprintf(stderr, "-Config file does not exit : %s\n",config_file);
        fprintf(stderr, "+Trying to create new config file.\n");
        if((fp = fopen(config_file,"w")) == 0){
            fprintf(stderr, "-Error creating new config file\n");
            return -1;
        }
	fprintf(fp, "#####################################################\n");
	fprintf(fp, "#             wmpop3lb configuration file           #\n");
	fprintf(fp, "#                                                   #\n");
	fprintf(fp, "# for more information about wmpop3lb, please see:  #\n");
	fprintf(fp, "#          http://wmpop3lb.jourdain.org             #\n");
	fprintf(fp, "#               or send a mail to                   #\n");
	fprintf(fp, "#             wmpop3lb@jourdain.org                 #\n");
	fprintf(fp, "#####################################################\n");
        fprintf(fp, "autochecking         0   # 1 enables, 0 disables\n");
	fprintf(fp, "displaydelay         2   # nb of seconds error info is displayed\n");
	fprintf(fp, "scrollspeed          100 # percentage of original scrool speed\n");
	fprintf(fp, "tempdir              /tmp # directory for tmp files\n");
        fprintf(fp, "viewallmessages      0   # 0 Shows the from and subject\n");
        fprintf(fp, "#                          1 Shows the number of messages\n");
        fprintf(fp, "#\n# Replace all values with appropriate data\n#\n");
	fprintf(fp, "[Server]  # server section\n");
	fprintf(fp, "alias                \"3 alphanum. char. long alias\"\n");
        fprintf(fp, "popserver            \" pop3 server name \"\n");
        fprintf(fp, "port                 110 # default port\n");
        fprintf(fp, "username             \" pop3 login name  \"\n");
        fprintf(fp, "password             \" pop3 password   \"\n");
        fprintf(fp, "mailcheckdelay       10  # default mail check time in minutes\n");
	fprintf(fp, "countUnreadOnly      0   # count unread messages only\n");
	fprintf(fp, "mailclient           \"netscape -mail\" # for example...\n");
	fprintf(fp, "newmailcommand       \" specify new mail command \"\n");
	fprintf(fp, "selectedmesgcommand  \"specify command for selected mess\"\n");
	fprintf(fp, "mailseparator        \" separator when concatening messages\"\n");
	fprintf(fp, "maxdlsize		  -1 # (no limit)\n");
	fprintf(fp, "#\n# start new [server] section below (up to a total of 6)\n");
        fprintf(stderr, "+New config file created : ~/.wmpop3rc\n\n");
        fprintf(stderr, "+ ~/.wmpop3rc must be configured before running wmpop3.\n");
        fclose(fp);
        return -1;
    }

    nb_conf = 0;
    tempdir[0] = '\0';

    while ((nb_conf < 7) && fgets(buf, CONF_BUFLEN, fp) != 0) {
      if (buf[0] != '#') {
	if (!nb_conf && !strncasecmp( buf, "autochecking", 12) ){
	  if (parsenum(buf + 12, &autoChecking))
	    fprintf(stderr, "syntax error for parameter autochecking\n");
	}
	else if (!nb_conf && !strncasecmp( buf, "scrollspeed", 11) ){
	  if (parsenum(buf + 11, &scrollspeed))
	    fprintf(stderr, "syntax error for parameter scrollspeed\n");
	}
	else if (!nb_conf && !strncasecmp( buf, "displaydelay", 12) ){
	  if (parsenum(buf + 12, &displaydelay))
	    fprintf(stderr, "syntax error for parameter displaydelay\n");
	}
	else if (!nb_conf && !strncasecmp(buf, "tempdir", 7)) {
	  if (parsestring(buf + 7, tempdir, 1024, fp))
	    fprintf(stderr, "syntax error for parameter tempdir\n");
	}
	else if (!strncasecmp(buf, "[server]", 8)) {
	  nb_conf++;
	  if (!(conf[nb_conf - 1] = pop3Create(nb_conf))) {
	    fprintf(stderr, "Can't allocate memory for config structure\n");
	    fclose(fp);
	    return (-1);
	  }
	}
	else if (nb_conf && !strncasecmp(buf, "username", 8) ) {
	  if (parsestring(buf + 8, conf[nb_conf -1]->username, 256, fp))
	    fprintf(stderr, "section %d: invalid syntax for username\n",
		    nb_conf);
	}
	else if (nb_conf && !strncasecmp( buf, "password", 8) ){
	  if (parsestring(buf + 8, conf[nb_conf - 1]->password, 256, fp))
	    fprintf(stderr, "section %d: invalid syntax for password\n",
		    nb_conf);
	}
	else if (nb_conf && !strncasecmp(buf, "alias", 5) ) {
	  if (parsestring(buf + 5, conf[nb_conf -1]->alias, 3, fp))
	    fprintf(stderr, "section %d: invalid syntax for alias\n", nb_conf);
	}
	else if (nb_conf && !strncasecmp( buf, "popserver", 9) ){
	  if (parsestring(buf + 9, conf[nb_conf - 1]->popserver, 128, fp))
	    fprintf(stderr, "section %d: invalid syntax for popserver\n",
		    nb_conf);
	}
	else if (nb_conf && !strncasecmp( buf, "port", 4) ){
	  if (parsenum(buf + 4, &(conf[nb_conf - 1]->serverport)))
	    fprintf(stderr, "section %d: Invalid popserver port number.\n",
		    nb_conf);
	}
	else if (!nb_conf && !strncasecmp( buf, "viewallmessages", 15) ){
	  if (parsenum(buf + 15, &newMessagesOnly))
	    fprintf(stderr, "section %d: Invalid number ( viewallmessages )\n",
		    nb_conf);
	}
	else if (nb_conf && !strncasecmp(buf, "countunreadonly", 15)) {
	  if (parsenum(buf + 15, &(conf[nb_conf - 1]->countunreadonly)))
	    fprintf(stderr, "section %d: Invalid number ( countunreadonly )\n",
		    nb_conf);
	}
	else if (nb_conf && !strncasecmp( buf, "mailcheckdelay", 14) ){
	  if (parsenum(buf + 14, &(conf[nb_conf -1]->mailCheckDelay)))
	    fprintf(stderr, "section %d: Invalid delay time.\n", nb_conf);
	}
	else if (nb_conf && !strncasecmp(buf, "mailclient", 10)) {
	  if (parsestring(buf + 10, tmp, 256, fp))
	    fprintf(stderr, "section %d: Invalid syntax for mailclient.\n",
		    nb_conf);
	  else
	    conf[nb_conf - 1]->mailclient = build_arg_list(tmp, strlen(tmp));
	}
	else if (nb_conf && !strncasecmp(buf, "newmailcommand", 14)) {
	  if (parsestring(buf + 14, tmp, 256, fp))
	    fprintf(stderr,"section %d: Invalid syntax for newmailcommand.\n",
		    nb_conf);
	  else
	    conf[nb_conf - 1]->newmailcommand =
	      build_arg_list(tmp, strlen(tmp));
	}
	else if (nb_conf && !strncasecmp(buf, "selectedmesgcommand", 19)) {
	  if (parsestring(buf + 19, tmp, 256, fp))
	    fprintf(stderr,
		    "section %d: Invalid syntax for selectedmesgcommand.\n",
		    nb_conf);
	  else
	    conf[nb_conf - 1]->selectedmesgcommand =
	      build_arg_list(tmp, strlen(tmp));
	}
	else if (nb_conf && !strncasecmp(buf, "mailseparator", 13)) {
	  if (parsestring(buf + 13, conf[nb_conf - 1]->mailseparator, 256, fp))
	    fprintf(stderr, "section %d: Invalid syntax for mailseparator\n",
		    nb_conf);
	}
	else if (nb_conf && !strncasecmp( buf, "maxdlsize", 9) ){
	  if (parsenum(buf + 9, &(conf[nb_conf -1]->maxdlsize)))
	    fprintf(stderr, "section %d: Invalid maxdlsize.\n", nb_conf);
	}
	else if (nb_conf) {
	  if (*buf && (isalpha(*buf) || isalnum(*buf)))
	    fprintf(stderr, "section %d: Unknown indentifier : [%s]\n",
		    nb_conf, buf);
	}
	else {
	  for (bal = buf; *bal && !isalnum(*bal); bal++);
	  if (*bal)
	    fprintf(stderr, "identifier outside Server section: [%s]\n", buf);
	}
      }
    }
    fclose(fp);
    return 0;
}