1 /**
2 * \file util.c
3 * \brief Util functions for string management
4 *
5 * \author Fernando J. Pereda <ferdy@ferdyx.org>
6 * \author Ricardo Cervera Navarro <ricardo@zonasiete.org>
7 *
8 * This is part of nbsmtp. nbsmtp is free software;
9 * you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * nbsmtp is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with nbsmtp; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 *
23 * See COPYING for details.
24 */
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <syslog.h>
28 #include <time.h>
29 #include <string.h>
30 #include <stdarg.h>
31 #include "util.h"
32
33 /**
34 * \brief Wheter we should accept LOG_DEBUG messages or not. If debug = 2 we will print all
35 * messages to stdout
36 */
37 int debug = 0;
38
39 /**
40 * \brief Increases memory for a string_t
41 *
42 * \param[in,out] buffer Pointer to string_t
43 * \param[in] incr Number of bytes (chars) to increment buffer size
44 */
str_incr_space(string_t * buffer,int incr)45 void str_incr_space(string_t *buffer, int incr)
46 {
47 int i = buffer->len;
48 buffer->str = realloc(buffer->str, buffer->len+(incr*sizeof(char)));
49 buffer->len += incr;
50
51 for (; i < buffer->len; i++ )
52 {
53 buffer->str[i] = 0;
54 }
55 }
56
57 /**
58 * \brief Frees a string_t element
59 *
60 * \param[out] buffer Pointer to string_t
61 */
str_free(string_t * buffer)62 void str_free(string_t *buffer)
63 {
64 if (buffer->len > 0)
65 {
66 free(buffer->str);
67 buffer->len = 0;
68 }
69 }
70
71 /**
72 * \brief Initialize a string_t element
73 *
74 * \param[out] buffer Pointer to string_t
75 * \param[in] size Num of chars that will be reserved
76 */
str_init(string_t * buffer,int size)77 void str_init(string_t *buffer, int size)
78 {
79 buffer->str = malloc((size+1)*sizeof(char));
80 buffer->len = size;
81 }
82
83 /**
84 * \brief Generates a date with the RFC822 (ARPA Internet Text) format
85 *
86 * \param[out] buf Where to store the string
87 */
arpadate(char * buf)88 void arpadate(char *buf)
89 {
90 struct tm *date;
91 time_t now;
92 const char *const format = "%a, %e %b %Y %H:%M:%S %z (%Z)";
93
94 now = time(NULL);
95
96 date = localtime((const time_t *)&now);
97 strftime(buf,40,format,date);
98 }
99
100 /**
101 * \brief Logs a message to syslog, checks for debug if the priority is LOG_DEBUG
102 *
103 * \param[in] priority An int with the message priority (LOG_INFO,LOG_DEBUG,LOG_ERR...)
104 * \param[in] format A pointer to the message format
105 * \param[in] ... Variable list.
106 */
log_msg(int priority,char * format,...)107 void log_msg(int priority, char *format, ...)
108 {
109 static int mask_next = 0;
110 char buffer[BUFSIZ];
111 char *p;
112 va_list list;
113
114 /*
115 * If we are receiving a LOG_DEBUG message, we check for debug
116 * to write it.
117 */
118 if ((priority==LOG_DEBUG) && (debug==0))
119 {
120 return;
121 }
122
123 /*
124 * Copy in buffer the result of parsing format with list
125 * up to BUFSIZ bytes
126 */
127 va_start(list,format);
128 vsnprintf(buffer,BUFSIZ,format,list);
129 va_end(list);
130
131 /*
132 * Strip \r and \n so we don't mess syslog
133 */
134 if ((p = strchr(buffer,'\r')) != NULL)
135 {
136 *p = '\0';
137 }
138
139 if ((p = strchr(buffer,'\n')) != NULL)
140 {
141 *p = '\0';
142 }
143
144 /*
145 * Remove passwords (they are only sent with debug>0)
146 */
147 if (debug>0 && debug<3)
148 {
149 if (mask_next==1)
150 {
151 p = NULL;
152
153 if (buffer[2]=='>')
154 {
155 /* Skip the ' ' */
156 p = strchr(buffer,' ')+1;
157 mask_next = 0;
158 }
159 }
160 else if ((p = strstr(buffer,"AUTH PLAIN ")) != NULL)
161 {
162 p += strlen("AUTH PLAIN ");
163 }
164 else if ((p = strstr(buffer,"AUTH LOGIN ")) != NULL)
165 {
166 p += strlen("AUTH LOGIN ");
167 mask_next = 1;
168 }
169 else
170 {
171 p = NULL;
172 }
173
174 if (p!=NULL)
175 {
176 int k;
177
178 for ( k = 0 ; k < 10 && *p ; k++ , p++ )
179 {
180 *p='X';
181 }
182
183 *p = (char)NULL;
184 }
185 }
186
187 if (debug==0 || debug==1)
188 {
189 openlog("nbSMTP", LOG_PID, LOG_MAIL);
190 syslog(priority,"%s",buffer);
191 closelog();
192 }
193 else /* if (debug==2) */
194 {
195 fprintf(stderr,"%s\n",buffer);
196 }
197 }
198
199 /**
200 * \brief Prints an usage string
201 *
202 * \param[in] prog A pointer to argv[0]
203 */
print_usage(char * prog)204 void print_usage(char *prog)
205 {
206 printf("Usage: %s -f from@address.com -h relayhost [OPTIONS] (use -H for help)\n",prog);
207 }
208
209 /**
210 * \brief Prints information on how to use nbsmtp and some Copyright info.
211 *
212 * \param[in] prog A pointer to argv[0]
213 */
print_help(char * prog)214 void print_help(char *prog)
215 {
216 int i = 0;
217
218 printf("nbSMTP %s\n\n",PACKAGE_VERSION);
219
220 printf("Features compiled-in: ");
221
222 puts(""
223 #ifdef HAVE_SSL
224 "SSL "
225 #endif
226 #ifdef HAVE_INET6
227 "IPv6 "
228 #endif
229 #ifdef HAVE_DEBUG
230 "DEBUG "
231 #endif
232 #ifdef HAVE_OSX
233 "OSX "
234 #endif
235 );
236
237 putchar('\n');
238
239 printf("nbSMTP comes with ABSOLUTELY NO WARRANTY\n\n");
240
241 do
242 {
243 printf("%s\n",authors[i]);
244 } while (authors[++i]);
245
246 print_usage(prog);
247 printf(" -d\tdomain to send in HELO request\n");
248 printf(" -f\temail address to send in MAIL FROM request\n");
249 printf(" -h\thost to relay mail to\n");
250 printf(" -p\tport to connect to\n");
251 #ifdef HAVE_SSL
252 printf(" -s\tuse SSL to transfer mail\n");
253 printf(" -S\tuse STARTTLS to connect to server\n");
254 #endif
255 printf(" -U\tSASL user\n");
256 printf(" -P\tSASL password\n");
257 printf(" -M\t{l,p} SASL mechanism to use: l - login (default) , p - plain\n");
258 printf(" -D\tenable debug to syslog (LOG_DEBUG)\n");
259 printf(" -N\tdo not read system-wide config file\n");
260 printf(" -n\tdo not read local config file\n");
261 printf(" -V\tlog to stderr instead of using syslog (implies -D)\n");
262 printf(" -v\tprint version and exit\n");
263 printf(" -c\tuse an additional config file\n");
264 printf(" -H\tthis help message\n");
265
266 printf("\nSend bug reports and comments to <%s>.\n\n",PACKAGE_BUGREPORT);
267 }
268