pop_send.c
上传用户:dayuan858
上传日期:2007-01-04
资源大小:194k
文件大小:4k
源码类别:

网络编程

开发平台:

Unix_Linux

  1. /*
  2.  * Copyright (c) 1989 Regents of the University of California.
  3.  * All rights reserved.  The Berkeley software License Agreement
  4.  * specifies the terms and conditions for redistribution.
  5.  */
  6. /*
  7.  * Copyright (c) 1997 by Qualcomm Incorporated.
  8.  */
  9. #include <config.h>
  10. #include <stdio.h>
  11. #include <sys/types.h>
  12. #include <string.h>
  13. #ifndef HAVE_BCOPY
  14. # define bcopy(src,dest,len) (void) (memcpy(dest,src,len))
  15. # define bzero(dest,len)   (void) (memset(dest, (char)NULL, len))
  16. # define bcmp(b1,b2,n) (void) (memcmp(b1,b2,n))
  17. #endif
  18. #ifndef HAVE_INDEX
  19. # define index(s,c) strchr(s,c)
  20. # define rindex(s,c) strrchr(s,c)
  21. #endif
  22. #if HAVE_STRINGS_H
  23. # include <strings.h>
  24. #endif
  25. #include <popper.h>
  26. /* 
  27.  *  send:   Send the header and a specified number of lines 
  28.  *          from a mail message to a POP client.
  29.  */
  30. pop_send(p)
  31. POP     *   p;
  32. {
  33.     MsgInfoList         *   mp;         /*  Pointer to message info list */
  34.     register int            msg_num;
  35.     register int            msg_lines;
  36.     register int     uidl_sent = 0;
  37.     char                    buffer[MAXMSGLINELEN];
  38.     /*  Convert the first parameter into an integer */
  39.     msg_num = atoi(p->pop_parm[1]);
  40.     /*  Is requested message out of range? */
  41.     if ((msg_num < 1) || (msg_num > p->msg_count))
  42.         return (pop_msg (p,POP_FAILURE,"Message %d does not exist.",msg_num));
  43.     /*  Get a pointer to the message in the message list */
  44.     mp = &p->mlp[msg_num-1];
  45.     /*  Is the message flagged for deletion? */
  46.     if (mp->del_flag)
  47.         return (pop_msg (p,POP_FAILURE,
  48.             "Message %d has been deleted.",msg_num));
  49.     /*  If this is a TOP command, get the number of lines to send */
  50.     if (strcmp(p->pop_command,"top") == 0) {
  51.         /*  Convert the second parameter into an integer */
  52.         msg_lines = atoi(p->pop_parm[2]) + 1;
  53. msg_lines = msg_lines > mp->body_lines ? mp->body_lines : msg_lines; 
  54.     }
  55.     else {
  56. /* NO_STATUS does not dirty the mailspool if a status is changed */
  57. #ifndef NO_STATUS
  58.         /*  Assume that a RETR (retrieve) command was issued */
  59. if (mp->retr_flag != TRUE)
  60.     p->dirty = 1;
  61. #endif
  62.         msg_lines = mp->body_lines;
  63.         /*  Flag the message as retreived */
  64.         mp->retr_flag = TRUE;
  65.     }
  66.     
  67.     /*  Display the number of bytes in the message */
  68.     pop_msg(p,POP_SUCCESS,"%u octets",mp->length);
  69.     /*  Position to the start of the message */
  70.     (void)fseek(p->drop, mp->offset, 0);
  71.     /*  Skip the first line (the sendmail "From" or MMDF line) */
  72.     (void)fgets (buffer,MAXMSGLINELEN,p->drop);
  73.     /*  Send the header of the message followed by a blank line */
  74.     while (fgets(buffer, MAXMSGLINELEN, p->drop)) {
  75. if (!strncasecmp(buffer, "Content-Length:", 15) ||
  76.     !strncasecmp(buffer, "X-UIDL:", 7)) { /* Skip UIDLs */
  77.     continue; /* Content-Length is MTA dependent, don't send to MUA */
  78. }
  79. if (!uidl_sent && (*buffer=='n' || !strncasecmp(buffer,"Status:",7))) {
  80.     char uidl_buf[MAXMSGLINELEN];
  81.     sprintf(uidl_buf, "%s %s", "X-UIDL:", mp->uidl_str);
  82.     pop_sendline(p, uidl_buf);
  83.     uidl_sent++;
  84. }
  85. pop_sendline(p, buffer);
  86.         /*  A single newline (blank line) signals the end of the header.
  87.     pop_sendline turns n into  */
  88. if (*buffer == '')
  89.     break;
  90. if (hangup)
  91.           return(pop_msg(p, POP_FAILURE, "SIGHUP or SIGPIPE flagged"));
  92.     }
  93.     /*  Send the message body */
  94.     while(fgets(buffer, MAXMSGLINELEN, p->drop)) {
  95.         /*  Decrement the lines sent (for a TOP command) */
  96.         if (--msg_lines <= 0) break;
  97.         pop_sendline(p,buffer);
  98. if (hangup)
  99.           return(pop_msg(p, POP_FAILURE, "SIGHUP or SIGPIPE flagged"));
  100.     }
  101.     /*  "." signals the end of a multi-line transmission */
  102.     /*  Must be an fputs because pop_sendline inserts an additional . */
  103.     (void)fputs(".rn", p->output);
  104.     (void)fflush(p->output);
  105.     return(POP_SUCCESS);
  106. }
  107. /*
  108.  *  sendline:   Send a line of a multi-line response to a client.
  109.  */
  110. pop_sendline(p,buffer)
  111. POP         *   p;
  112. char        *   buffer;
  113. {
  114.     char        *   bp;
  115.     /*  Byte stuff lines that begin with the temirnation octet */
  116.     if (*buffer == POP_TERMINATE) (void)fputc(POP_TERMINATE,p->output);
  117.     /*  Look for a <NL> in the buffer */
  118.     if (bp = index(buffer,NEWLINE)) *bp = 0;
  119.     /*  Send the line to the client */
  120.     (void)fputs(buffer,p->output);
  121. #ifdef DEBUG
  122.     if(p->debug)pop_log(p,POP_DEBUG,"Sending line "%.1000s"",buffer);
  123. #endif
  124.     /*  Put a <CR><NL> if a newline was removed from the buffer */
  125.     if (bp) (void)fputs ("rn",p->output);
  126. }