ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/cms/source/host/c++/socket++-1.10/smtp.C
Revision: 1.1
Committed: Mon Feb 26 15:01:39 2001 UTC (23 years, 9 months ago) by ab11
Content type: text/plain
Branch: MAIN
CVS Tags: PROJECT_COMPLETION
Log Message:
Networking class. Assumed to be bug free.

File Contents

# Content
1 // smtp.C -*- C++ -*- socket library
2 // Copyright (C) 1992,1993,1994 Gnanasekaran Swaminathan <gs4t@virginia.edu>
3 //
4 // Permission is granted to use at your own risk and distribute this software
5 // in source and binary forms provided the above copyright
6 // notice and this paragraph are preserved on all copies.
7 // This software is provided "as is" with no express or implied warranty.
8 //
9 // Version: 17Oct95 1.10
10
11 #include <config.h>
12
13 #include <smtp.h>
14 #include <Fork.h>
15 #include <fcntl.h>
16 #include <unistd.h>
17 #include <stdlib.h>
18 #include <string.h>
19
20 void smtp::smtpbuf::get_response ()
21 // get all the response that one can get and send all of them to o
22 {
23 // if o is 0, then we trash data.
24 while (underflow () != EOF) {
25 int n = in_avail ();
26 if (n < 5)
27 continue;
28
29 // data is of this form: 221 repsonse <CRLF> or 221-response <CRLF>
30 char* q = gptr ();
31 char* p = q;
32
33 // zap upto <CRLF>
34 for (int i = 2; i <= n; i++, p++)
35 if (*p == '\r' && *(p+1) == '\n') {
36 if (o)
37 o->write (q, i);
38 gbump (i);
39 break;
40 }
41
42 if (q [3] != '-')
43 break;
44 }
45 }
46
47 void smtp::smtpbuf::send_cmd (const char* cmd, const char* s, const char* p)
48 {
49 xsputn (cmd, ::strlen (cmd));
50 if (s)
51 xsputn (s, ::strlen (s));
52 if (p)
53 xsputn (p, ::strlen (p));
54 xsputn ("\r\n", 2);
55 flush_output ();
56
57 if (o)
58 get_response ();
59 }
60
61 void smtp::smtpbuf::helo ()
62 {
63 if (o)
64 get_response ();
65 send_cmd ("HELO ", localhost ());
66 }
67
68 void smtp::smtpbuf::mail (const char* reverse_path)
69 {
70 if (reverse_path)
71 send_cmd ("MAIL FROM:<", reverse_path, ">");
72 else
73 send_cmd ("MAIL FROM:<>");
74 }
75
76 void smtp::smtpbuf::rcpt (const char* forward_path)
77 {
78 if (forward_path)
79 send_cmd ("RCPT TO:<", forward_path, ">");
80 }
81
82 void smtp::smtpbuf::help (const char* s)
83 {
84 send_cmd ("HELP ", s);
85 }
86
87 void smtp::smtpbuf::send_buf (const char* buf, int len)
88 {
89 if (buf == 0 || len <= 0)
90 return;
91
92 // send line by line
93 const unsigned char* p = (const unsigned char*) buf;
94
95 #ifdef buggy
96 // this doesn't work correctly for ".\n" on a line by itself
97 if (*p == '.')
98 sputc ((unsigned int) '.');
99 #endif
100
101 for (int i = 0; i < len; i++, p++) {
102 if (*p == '\n') {
103 sputc ((unsigned int) '\r');
104 sputc (*p);
105 #ifdef buggy
106 // this doesn't work correctly for "\n.\n" - RGL
107 if (*(p+1) == '.')
108 sputc ((unsigned int) '.');
109 #endif
110 } else
111 sputc (*p);
112 }
113
114 // XXX: Need to flush or \r\n.\r\n may not be sent - RGL
115 flush_output();
116 }
117
118 void smtp::smtpbuf::data (const char* buf, int len)
119 {
120 data ();
121 send_buf (buf, len);
122 xsputn ("\r\n.\r\n", 5);
123 flush_output ();
124
125 if (o)
126 get_response ();
127 }
128
129 void smtp::smtpbuf::data (const char* filename)
130 {
131 data ();
132
133 int fd = 0;
134 char buf [1024];
135 int rcnt;
136
137 if (filename == 0 || (fd = ::open (filename, O_RDONLY )) == -1)
138 fd = 0;
139
140 while ((rcnt = ::read (fd, buf, 1024)) > 0)
141 send_buf (buf, rcnt);
142
143 xsputn ("\r\n.\r\n", 5);
144 flush_output ();
145
146 if (o)
147 get_response ();
148 }
149
150 int smtp::get_response (char* buf, int len)
151 // same as get line except what it returns
152 // return 1 if output continues after this line
153 // return 0 if output has terminated
154 {
155 if (len < 8) {
156 this->getline (buf, len);
157 return 0;
158 }
159
160 buf [3] = 0;
161 this->getline (buf, len);
162 return buf [3] == '-';
163 }
164
165 ostream& operator << (ostream& o, smtp& s)
166 {
167 char buf [1024];
168 int cont = 1;
169 while (cont) {
170 cont = s.get_response (buf, 1024);
171 o << buf << endl;
172 }
173 return o;
174 }
175
176
177 void smtp::smtpbuf::serve_clients (int portno)
178 {
179 }
180