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, 6 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

# User Rev Content
1 ab11 1.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