#include <stdio.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <ctype.h>

#if defined(SOLARIS2) || defined(SYSV) || defined(AIX)
#include <string.h>
#define index(s,c)		strchr(s,c)
#else
#include <strings.h>
#endif

#include "popper.h"

/*
 *  uidl:   POP UIDL function to list messages by message-ids
 */

pop_uidl (p)
POP     *   p;
{
    char                    buffer[MAXLINELEN];     /*  Read buffer */
    char		    *nl, *bp;
    MsgInfoList         *   mp;         /*  Pointer to message info list */
    int msg_id = 0, x;
    int len = 0;

    if (p->parm_count == 1) {
      len = strlen(p->pop_parm[1]);

      /*  Convert the parameter into an integer */
      msg_id = atoi(p->pop_parm[1]);
    }

    /*  Is requested message out of range? */
    if (len > 0 && msg_id == 0)
    {
      return (pop_msg (p,POP_FAILURE,"Parameter must be a number (range 1 to %d)", p->msg_count));
    }

    if (len > 0 && (msg_id < 1 || msg_id > p->msg_count))
      return (pop_msg (p,POP_FAILURE,
	      "Message out of range.  %d messages in mail drop.",p->msg_count));

    if (msg_id > 0) {
      /*  Get a pointer to the message in the message list */
      mp = &p->mlp[msg_id-1];

      if (mp->del_flag) {
        return (pop_msg (p,POP_FAILURE,
			    "Message %d has been marked for deletion.",msg_id));
      } else {
	/*  Position to the start of the message */
	(void)fseek(p->drop,mp->offset,0);

	/*  Skip the first line (the sendmail "From" line) */
	(void)fgets (buffer,MAXMSGLINELEN,p->drop);

	/*  scan until we fine the header or a blank line */
	while (fgets(buffer,MAXMSGLINELEN,p->drop)) {
	    if (*buffer=='\n') break;
	    if (!strncasecmp(buffer,MSGUIDL,strlen(MSGUIDL)))
	    {
	      /* found it! */
	      bp = buffer;
	      while (*bp && ! isspace(*bp))
		  bp++;
	      while (*bp && isspace(*bp))
		  bp++;

	      if (nl = index(buffer,NEWLINE)) *nl = 0;
	      return (pop_msg (p,POP_SUCCESS, "%d %s", msg_id, bp));
	    }
	}

	return (pop_msg (p,POP_FAILURE,"Message-Id Header not found."));
      }
    } else {
	/* yes, we can do this */
	pop_msg (p,POP_SUCCESS,"uidl command accepted.");

	for (x = 1; x <= p->msg_count; x++)
	{
	  /*  Get a pointer to the message in the message list */
	  mp = &p->mlp[x-1];

	  /*  Is the message flagged for deletion? */
	  if (mp->del_flag) continue;

	  /*  Position to the start of the message */
	  (void)fseek(p->drop,mp->offset,0);

	  /*  Skip the first line (the sendmail "From" line) */
	  (void)fgets (buffer,MAXMSGLINELEN,p->drop);

	  /*  scan until we fine the header or a blank line */
	  while (fgets(buffer,MAXMSGLINELEN,p->drop)) {
	      if (*buffer=='\n') break;
	      if (!strncasecmp(buffer,MSGUIDL,strlen(MSGUIDL)))
	      {
		/* found it! */
		fprintf(p->output,"%d ",x);
		bp = buffer;
		while (*bp && ! isspace(*bp))
		    bp++;
		while (*bp && isspace(*bp))
		    bp++;
		pop_sendline (p,bp);
		while (fgets(buffer,MAXMSGLINELEN,p->drop))
		{
		  if (*buffer!=' ' && *buffer!='\t') break;
		  pop_sendline(p,buffer);
		}
		break;
	      }
	  }
      }
  }

  /*  "." signals the end of a multi-line transmission */
  (void)fputs(".\r\n",p->output);
  (void)fflush(p->output);

  return(POP_SUCCESS);
}

