home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Mail / qpopper-2.4-MIHS / pop_send.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-09-11  |  4.4 KB  |  158 lines

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