1 /* ========================================================================
2  * Copyright 1988-2006 University of Washington
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *
11  * ========================================================================
12  */
13 
14 /*
15  * Program:	Network message (SMTP/NNTP/POP2/POP3) routines
16  *
17  * Author:	Mark Crispin
18  *		Networks and Distributed Computing
19  *		Computing & Communications
20  *		University of Washington
21  *		Administration Building, AG-44
22  *		Seattle, WA  98195
23  *		Internet: MRC@CAC.Washington.EDU
24  *
25  * Date:	8 June 1995
26  * Last Edited:	6 December 2006
27  */
28 
29 
30 #include <stdio.h>
31 #include <errno.h>
32 extern int errno;		/* just in case */
33 #include "c-client.h"
34 #include "netmsg.h"
35 #include "flstring.h"
36 
37 /* Network message read
38  * Accepts: file
39  *	    number of bytes to read
40  *	    buffer address
41  * Returns: T if success, NIL otherwise
42  */
43 
netmsg_read(void * stream,unsigned long count,char * buffer)44 long netmsg_read (void *stream,unsigned long count,char *buffer)
45 {
46   return (fread (buffer,(size_t) 1,(size_t) count,(FILE *) stream) == count) ?
47     T : NIL;
48 }
49 
50 /* Slurp dot-terminated text from NET
51  * Accepts: NET stream
52  *	    place to return size
53  *	    place to return header size
54  * Returns: file descriptor
55  */
56 
netmsg_slurp(NETSTREAM * stream,unsigned long * size,unsigned long * hsiz)57 FILE *netmsg_slurp (NETSTREAM *stream,unsigned long *size,unsigned long *hsiz)
58 {
59   unsigned long i;
60   char *s,*t,tmp[MAILTMPLEN];
61   FILE *f = tmpfile ();
62   if (!f) {
63     sprintf (tmp,".%lx.%lx",(unsigned long) time (0),(unsigned long)getpid ());
64     if (f = fopen (tmp,"wb+")) unlink (tmp);
65     else {
66       sprintf (tmp,"Unable to create scratch file: %.80s",strerror (errno));
67       MM_LOG (tmp,ERROR);
68       return NIL;
69     }
70   }
71   *size = 0;			/* initially emtpy */
72   if (hsiz) *hsiz = 0;
73   while (s = net_getline (stream)) {
74     if (*s == '.') {		/* possible end of text? */
75       if (s[1]) t = s + 1;	/* pointer to true start of line */
76       else {
77 	fs_give ((void **) &s);	/* free the line */
78 	break;			/* end of data */
79       }
80     }
81     else t = s;			/* want the entire line */
82     if (f) {			/* copy it to the file */
83       i = strlen (t);		/* size of line */
84       if ((fwrite (t,(size_t) 1,(size_t) i,f) == i) &&
85 	  (fwrite ("\015\012",(size_t) 1,(size_t) 2,f) == 2)) {
86 	*size += i + 2;		/* tally up size of data */
87 				/* note header position */
88 	if (!i && hsiz && !*hsiz) *hsiz = *size;
89       }
90       else {
91 	sprintf (tmp,"Error writing scratch file at byte %lu",*size);
92 	MM_LOG (tmp,ERROR);
93 	fclose (f);		/* forget it */
94 	f = NIL;		/* failure now */
95       }
96     }
97     fs_give ((void **) &s);	/* free the line */
98   }
99 				/* if making a file, rewind to start of file */
100   if (f) fseek (f,(unsigned long) 0,SEEK_SET);
101 				/* header consumes entire message */
102   if (hsiz && !*hsiz) *hsiz = *size;
103   return f;			/* return the file descriptor */
104 }
105