source: logging.c @ ab6d8f0

release-1.8release-1.9
Last change on this file since ab6d8f0 was fe3b017, checked in by David Benjamin <davidben@mit.edu>, 11 years ago
Correctly set the realm in outgoing zwrite errors Don't set the zwrite realm, as that only confuses things. Also take the realm (which we now don't set) into account when extracting the recipient.
  • Property mode set to 100644
File size: 10.2 KB
Line 
1#include "owl.h"
2#include <stdlib.h>
3#include <string.h>
4#include <ctype.h>
5#include <sys/param.h>
6
7/* This is now the one function that should be called to log a
8 * message.  It will do all the work necessary by calling the other
9 * functions in this file as necessary.
10 */
11void owl_log_message(const owl_message *m) {
12  owl_function_debugmsg("owl_log_message: entering");
13
14  if (m == NULL) {
15    owl_function_debugmsg("owl_log_message: passed null message");
16    return;
17  }
18
19  /* should we be logging this message? */
20  if (!owl_log_shouldlog_message(m)) {
21    owl_function_debugmsg("owl_log_message: not logging message");
22    return;
23  }
24
25  /* handle incmoing messages */
26  if (owl_message_is_direction_in(m)) {
27    owl_log_incoming(m);
28    owl_function_debugmsg("owl_log_message: leaving");
29    return;
30  }
31
32  /* handle outgoing messages */
33  owl_log_outgoing(m);
34
35  owl_function_debugmsg("owl_log_message: leaving");
36}
37
38/* Return 1 if we should log the given message, otherwise return 0 */
39int owl_log_shouldlog_message(const owl_message *m) {
40  const owl_filter *f;
41
42  /* If there's a logfilter and this message matches it, log */
43  f=owl_global_get_filter(&g, owl_global_get_logfilter(&g));
44  if (f && owl_filter_message_match(f, m)) return(1);
45
46  /* otherwise we do things based on the logging variables */
47
48  /* skip login/logout messages if appropriate */
49  if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
50     
51  /* check direction */
52  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
53    return(0);
54  }
55  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) && owl_message_is_direction_in(m)) {
56    return(0);
57  }
58
59  if (owl_message_is_type_zephyr(m)) {
60    if (owl_message_is_personal(m) && !owl_global_is_logging(&g)) return(0);
61    if (!owl_message_is_personal(m) && !owl_global_is_classlogging(&g)) return(0);
62  } else {
63    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
64      if (!owl_global_is_logging(&g)) return(0);
65    } else {
66      if (!owl_global_is_classlogging(&g)) return(0);
67    }
68  }
69  return(1);
70}
71
72void owl_log_zephyr(const owl_message *m, FILE *file) {
73    char *tmp;
74    tmp=short_zuser(owl_message_get_sender(m));
75    fprintf(file, "Class: %s Instance: %s", owl_message_get_class(m), owl_message_get_instance(m));
76    if (strcmp(owl_message_get_opcode(m), "")) fprintf(file, " Opcode: %s", owl_message_get_opcode(m));
77    fprintf(file, "\n");
78    fprintf(file, "Time: %s Host: %s\n", owl_message_get_timestr(m), owl_message_get_hostname(m));
79    fprintf(file, "From: %s <%s>\n\n", owl_message_get_zsig(m), tmp);
80    fprintf(file, "%s\n\n", owl_message_get_body(m));
81    g_free(tmp);
82}
83
84void owl_log_aim(const owl_message *m, FILE *file) {
85    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
86    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
87    if (owl_message_is_login(m))
88        fprintf(file, "LOGIN\n\n");
89    else if (owl_message_is_logout(m))
90        fprintf(file, "LOGOUT\n\n");
91    else
92        fprintf(file, "%s\n\n", owl_message_get_body(m));
93}
94
95void owl_log_jabber(const owl_message *m, FILE *file) {
96    fprintf(file, "From: <%s> To: <%s>\n",owl_message_get_sender(m), owl_message_get_recipient(m));
97    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
98    fprintf(file, "%s\n\n",owl_message_get_body(m));
99}
100
101void owl_log_generic(const owl_message *m, FILE *file) {
102    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
103    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
104    fprintf(file, "%s\n\n", owl_message_get_body(m));
105}
106
107void owl_log_append(const owl_message *m, const char *filename) {
108    FILE *file;
109    file=fopen(filename, "a");
110    if (!file) {
111        owl_function_error("Unable to open file for logging");
112        return;
113    }
114    if (owl_message_is_type_zephyr(m)) {
115        owl_log_zephyr(m, file);
116    } else if (owl_message_is_type_jabber(m)) {
117        owl_log_jabber(m, file);
118    } else if (owl_message_is_type_aim(m)) {
119        owl_log_aim(m, file);
120    } else {
121        owl_log_generic(m, file);
122    }
123    fclose(file);
124}
125
126void owl_log_outgoing(const owl_message *m)
127{
128  char *filename, *logpath;
129  char *to, *temp;
130  GList *cc;
131
132  /* expand ~ in path names */
133  logpath = owl_util_makepath(owl_global_get_logpath(&g));
134
135  /* Figure out what path to log to */
136  if (owl_message_is_type_zephyr(m)) {
137    /* If this has CC's, do all but the "recipient" which we'll do below */
138    cc = owl_message_get_cc_without_recipient(m);
139    while (cc != NULL) {
140      temp = short_zuser(cc->data);
141      filename = g_strdup_printf("%s/%s", logpath, temp);
142      owl_log_append(m, filename);
143
144      g_free(filename);
145      g_free(temp);
146      g_free(cc->data);
147      cc = g_list_delete_link(cc, cc);
148    }
149
150    to = short_zuser(owl_message_get_recipient(m));
151  } else if (owl_message_is_type_jabber(m)) {
152    to = g_strdup_printf("jabber:%s", owl_message_get_recipient(m));
153    owl_text_tr(to, '/', '_');
154  } else if (owl_message_is_type_aim(m)) {
155    char *temp2;
156    temp = owl_aim_normalize_screenname(owl_message_get_recipient(m));
157    temp2 = g_utf8_strdown(temp,-1);
158    to = g_strdup_printf("aim:%s", temp2);
159    g_free(temp2);
160    g_free(temp);
161  } else {
162    to = g_strdup("loopback");
163  }
164
165  filename = g_strdup_printf("%s/%s", logpath, to);
166  owl_log_append(m, filename);
167  g_free(to);
168  g_free(filename);
169
170  filename = g_strdup_printf("%s/all", logpath);
171  owl_log_append(m, filename);
172  g_free(logpath);
173  g_free(filename);
174}
175
176
177void owl_log_outgoing_zephyr_error(const owl_zwrite *zw, const char *text)
178{
179  FILE *file;
180  char *filename, *logpath;
181  char *tobuff, *recip;
182  owl_message *m;
183
184  /* create a present message so we can pass it to
185   * owl_log_shouldlog_message(void)
186   */
187  m = g_new(owl_message, 1);
188  /* recip_index = 0 because there can only be one recipient anyway */
189  owl_message_create_from_zwrite(m, zw, text, 0);
190  if (!owl_log_shouldlog_message(m)) {
191    owl_message_delete(m);
192    return;
193  }
194  owl_message_delete(m);
195
196  /* chop off a local realm */
197  recip = owl_zwrite_get_recip_n_with_realm(zw, 0);
198  tobuff = short_zuser(recip);
199  g_free(recip);
200
201  /* expand ~ in path names */
202  logpath = owl_util_makepath(owl_global_get_logpath(&g));
203
204  filename = g_strdup_printf("%s/%s", logpath, tobuff);
205  file=fopen(filename, "a");
206  g_free(filename);
207  if (!file) {
208    owl_function_error("Unable to open file for outgoing logging");
209    g_free(logpath);
210    g_free(tobuff);
211    return;
212  }
213  fprintf(file, "ERROR (owl): %s\n%s\n", tobuff, text);
214  if (text[strlen(text)-1]!='\n') {
215    fprintf(file, "\n");
216  }
217  fclose(file);
218
219  filename = g_strdup_printf("%s/all", logpath);
220  g_free(logpath);
221  file=fopen(filename, "a");
222  g_free(filename);
223  if (!file) {
224    owl_function_error("Unable to open file for outgoing logging");
225    g_free(tobuff);
226    return;
227  }
228  fprintf(file, "ERROR (owl): %s\n%s\n", tobuff, text);
229  if (text[strlen(text)-1]!='\n') {
230    fprintf(file, "\n");
231  }
232  fclose(file);
233
234  g_free(tobuff);
235}
236
237void owl_log_incoming(const owl_message *m)
238{
239  char *filename, *allfilename, *logpath;
240  const char *from=NULL;
241  char *frombuff=NULL;
242  int len, ch, i, personal;
243
244  /* figure out if it's a "personal" message or not */
245  if (owl_message_is_type_zephyr(m)) {
246    if (owl_message_is_personal(m)) {
247      personal = 1;
248    } else {
249      personal = 0;
250    }
251  } else if (owl_message_is_type_jabber(m)) {
252    /* This needs to be fixed to handle groupchat */
253    const char* msgtype = owl_message_get_attribute_value(m,"jtype");
254    if (msgtype && !strcmp(msgtype,"groupchat")) {
255      personal = 0;
256    } else {
257      personal = 1;
258    }
259  } else {
260    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
261      personal = 1;
262    } else {
263      personal = 0;
264    }
265  }
266
267
268  if (owl_message_is_type_zephyr(m)) {
269    if (personal) {
270      from=frombuff=short_zuser(owl_message_get_sender(m));
271    } else {
272      from=frombuff=g_strdup(owl_message_get_class(m));
273    }
274  } else if (owl_message_is_type_aim(m)) {
275    /* we do not yet handle chat rooms */
276    char *normalto, *temp;
277    temp = owl_aim_normalize_screenname(owl_message_get_sender(m));
278    normalto = g_utf8_strdown(temp, -1);
279    from=frombuff=g_strdup_printf("aim:%s", normalto);
280    g_free(normalto);
281    g_free(temp);
282  } else if (owl_message_is_type_loopback(m)) {
283    from=frombuff=g_strdup("loopback");
284  } else if (owl_message_is_type_jabber(m)) {
285    if (personal) {
286      from=frombuff=g_strdup_printf("jabber:%s",owl_message_get_sender(m));
287    } else {
288      from=frombuff=g_strdup_printf("jabber:%s",owl_message_get_recipient(m));
289    }
290  } else {
291    from=frombuff=g_strdup("unknown");
292  }
293 
294  /* check for malicious sender formats */
295  len=strlen(frombuff);
296  if (len<1 || len>35) from="weird";
297  if (strchr(frombuff, '/')) from="weird";
298
299  ch=frombuff[0];
300  if (!g_ascii_isalnum(ch)) from="weird";
301
302  for (i=0; i<len; i++) {
303    if (frombuff[i]<'!' || frombuff[i]>='~') from="weird";
304  }
305
306  if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird";
307
308  if (!personal) {
309    if (strcmp(from, "weird")) {
310      char* temp = g_utf8_strdown(frombuff, -1);
311      if (temp) {
312        g_free(frombuff);
313        from = frombuff = temp;
314      }
315    }
316  }
317
318  /* create the filename (expanding ~ in path names) */
319  if (personal) {
320    logpath = owl_util_makepath(owl_global_get_logpath(&g));
321    filename = g_strdup_printf("%s/%s", logpath, from);
322    allfilename = g_strdup_printf("%s/all", logpath);
323    owl_log_append(m, allfilename);
324    g_free(allfilename);
325  } else {
326    logpath = owl_util_makepath(owl_global_get_classlogpath(&g));
327    filename = g_strdup_printf("%s/%s", logpath, from);
328  }
329
330  owl_log_append(m, filename);
331  g_free(filename);
332
333  if (personal && owl_message_is_type_zephyr(m)) {
334    /* We want to log to all of the CC'd people who were not us, or
335     * the sender, as well.
336     */
337    char *temp;
338    GList *cc;
339    cc = owl_message_get_cc_without_recipient(m);
340    while (cc != NULL) {
341      temp = short_zuser(cc->data);
342      if (strcasecmp(temp, frombuff) != 0) {
343        filename = g_strdup_printf("%s/%s", logpath, temp);
344        owl_log_append(m, filename);
345        g_free(filename);
346      }
347
348      g_free(temp);
349      g_free(cc->data);
350      cc = g_list_delete_link(cc, cc);
351    }
352  }
353
354  g_free(frombuff);
355  g_free(logpath);
356}
Note: See TracBrowser for help on using the repository browser.