source: logging.c @ dab82f29

owl
Last change on this file since dab82f29 was dab82f29, checked in by James M. Kretchmar <kretch@mit.edu>, 16 years ago
Don't crash on mobile device AIM messages [BZ 20] Don't crash when sending to someone not on AIM buddy list [BZ 94] Fix overflow vulerability in zwrite.c and zcrypt.c Add stack protector and -D_FORTIFY_SOURCE=2 where possible Fix hang [barnowl 4c46dfdebc294ca24fef59924f01688b8ee07dee] Fix segfault on missing subs [barnowl 99dabeed7de6d19acb50f1e73aa0bfe5f9469c02] Fix zcrypt bufffer size bug [barnowl 559076cd86edc3a8317819814dd5877b8bc7c3cb] Fix double free [barnowl e97c4a306ae2c9d2147d83da29fee59918198e70] Memory leak fix [barnowl c0a90c2c7ab97b9465c9873757faf312faa0021e] Memory leak fix [barnowl 95caa16b2e9ba10770d87d0955198c14c2d0e16a] Memory leak fix [barnowl 1716fed8c2650e46892cf6571555eac937266c6e] Add getstyle command [barnowl 216c73421653e3ef0e957aa9a9804e208a77c80e] Binary search for msgid [barnowl 0c8ab5eadbb6ecc97a120c91b9a824b33538c764] File-handle leak [barnowl e78397d6ac5da0de31a4e269c0ba7f3d691857a3] Fix delay in jump from top to bottom [barnowl 801b7ac63b962640debbcfd422cb9a60da5fea31] Load subs in chunks [barnowl 93e883d60051b80bf6d35391f9d76fd7dfd198e3] Load subs in chunks [barnowl f6050ee9b0a171a5031f84409eb181062afacd18] Better zsig logging [barnowl d857b667a5a9b108b1a2a26b4a5513bef2b53f80] free() -> owlfree() [barnowl d524c838ac7c115628424b8ac171c3489622ea3a] Escape AIM users in smartfilters [barnowl af9b92e3e7ccb7de276a94b5c7e5861b24e71eff] Better regex escape chars [barnowl 80e54a7631f091be8c9762adb9746bad38104738] Deal with quotes in smart filters [barnowl 4099cf83702763fa8d1efc4f1582a605431bdb77] Deal with 0 length zephyr fields [barnowl 128171aaf7cefa91a4bb1eada93a19d8fd0c355c] Deal with 0 length zephyr fields [barnowl 50e29e35c64d64e223d378d350a7bc4f038d78f5] Deal with 0 length zephyr fields [barnowl 804ab8af8b6d00bcd7e2402df892db8fbd61a3ec] Leave curmsg on screen after resize [barnowl c0f9e3009bc03e80a44de64cd5f2b4033290236e] Rip out brower stuff [barnowl 8e5935d11c699a7ce5a3e6e9a47799564c696d6a] Rip out browser stuff [barnowl 4f15e8e9ceada0d4b2cc969ebf43b0a1fb3709ea] No passwords in command history [barnowl 6e400cc71aa59e041dce677aadf50dc1f25228e2] Format NOC mssages [barnowl a1bb1980e4bca23b8329cc0e7c0bd5027055ea0a] Expand ~ in loadsubs [barnowl 27d8d835dc6d58c08fae10e75aae306c49215143] Expand ~ in source [barnowl 10d67d57cb29221f63a43a30643c697fc7b38911] Only use resizeterm() if it's available Debian backports Change license to GPLv3
  • Property mode set to 100644
File size: 13.7 KB
Line 
1/* Copyright (c) 2002,2003,2004,2009 James M. Kretchmar
2 *
3 * This file is part of Owl.
4 *
5 * Owl is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * Owl is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with Owl.  If not, see <http://www.gnu.org/licenses/>.
17 *
18 * ---------------------------------------------------------------
19 *
20 * As of Owl version 2.1.12 there are patches contributed by
21 * developers of the the branched BarnOwl project, Copyright (c)
22 * 2006-2008 The BarnOwl Developers. All rights reserved.
23 */
24
25#include "owl.h"
26#include <stdlib.h>
27#include <string.h>
28#include <ctype.h>
29#include <sys/param.h>
30
31static const char fileIdent[] = "$Id$";
32
33/* This is now the one function that should be called to log a
34 * message.  It will do all the work necessary by calling the other
35 * functions in this file as necessary.
36 */
37void owl_log_message(owl_message *m) {
38  owl_function_debugmsg("owl_log_message: entering");
39
40  /* should we be logging this message? */
41  if (!owl_log_shouldlog_message(m)) {
42    owl_function_debugmsg("owl_log_message: not logging message");
43    return;
44  }
45
46  /* handle incmoing messages */
47  if (owl_message_is_direction_in(m)) {
48    owl_log_incoming(m);
49    owl_function_debugmsg("owl_log_message: leaving");
50    return;
51  }
52
53  /* handle outgoing messages */
54  if (owl_message_is_type_aim(m)) {
55    owl_log_outgoing_aim(m);
56  } else if (owl_message_is_type_zephyr(m)) {
57    owl_log_outgoing_zephyr(m);
58  } else if (owl_message_is_type_loopback(m)) {
59    owl_log_outgoing_loopback(m);
60  } else {
61    owl_function_error("Unknown message type for logging");
62  }
63  owl_function_debugmsg("owl_log_message: leaving");
64}
65
66/* Return 1 if we should log the given message, otherwise return 0 */
67int owl_log_shouldlog_message(owl_message *m) {
68  owl_filter *f;
69
70  /* If there's a logfilter and this message matches it, log */
71  f=owl_global_get_filter(&g, owl_global_get_logfilter(&g));
72  if (f && owl_filter_message_match(f, m)) return(1);
73
74  /* otherwise we do things based on the logging variables */
75
76  /* skip login/logout messages if appropriate */
77  if (!owl_global_is_loglogins(&g) && owl_message_is_loginout(m)) return(0);
78     
79  /* check for nolog */
80  if (!strcasecmp(owl_message_get_opcode(m), "nolog") || !strcasecmp(owl_message_get_instance(m), "nolog")) return(0);
81
82  /* check direction */
83  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_IN) && owl_message_is_direction_out(m)) {
84    return(0);
85  }
86  if ((owl_global_get_loggingdirection(&g)==OWL_LOGGING_DIRECTION_OUT) && owl_message_is_direction_in(m)) {
87    return(0);
88  }
89
90  if (owl_message_is_type_zephyr(m)) {
91    if (owl_message_is_personal(m) && !owl_global_is_logging(&g)) return(0);
92    if (!owl_message_is_personal(m) && !owl_global_is_classlogging(&g)) return(0);
93  } else {
94    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
95      if (!owl_global_is_logging(&g)) return(0);
96    } else {
97      if (!owl_global_is_classlogging(&g)) return(0);
98    }
99  }
100  return(1);
101}
102
103void owl_log_outgoing_zephyr(owl_message *m)
104{
105  FILE *file;
106  char filename[MAXPATHLEN], *logpath;
107  char *to, *text;
108
109  /* strip local realm */
110  to=short_zuser(owl_message_get_recipient(m));
111
112  /* expand ~ in path names */
113  logpath=owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
114
115  text=owl_message_get_body(m);
116
117  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, to);
118  file=fopen(filename, "a");
119  if (!file) {
120    owl_function_error("Unable to open file for outgoing logging");
121    owl_free(logpath);
122    owl_free(to);
123    return;
124  }
125  fprintf(file, "OUTGOING (owl): %s\n%s\n", to, text);
126  if (text[strlen(text)-1]!='\n') {
127    fprintf(file, "\n");
128  }
129  fclose(file);
130
131  snprintf(filename, MAXPATHLEN, "%s/all", logpath);
132  owl_free(logpath);
133  file=fopen(filename, "a");
134  if (!file) {
135    owl_function_error("Unable to open file for outgoing logging");
136    owl_free(to);
137    return;
138  }
139  fprintf(file, "OUTGOING (owl): %s\n%s\n", to, text);
140  if (text[strlen(text)-1]!='\n') {
141    fprintf(file, "\n");
142  }
143  fclose(file);
144
145  owl_free(to);
146}
147
148void owl_log_outgoing_zephyr_error(char *to, char *text)
149{
150  FILE *file;
151  char filename[MAXPATHLEN], *logpath;
152  char *tobuff, *zwriteline;
153  owl_message *m;
154
155  /* create a present message so we can pass it to
156   * owl_log_shouldlog_message()
157   */
158  zwriteline=owl_sprintf("zwrite %s", to);
159  m=owl_function_make_outgoing_zephyr(text, zwriteline, "");
160  owl_free(zwriteline);
161  if (!owl_log_shouldlog_message(m)) {
162    owl_message_free(m);
163    return;
164  }
165  owl_message_free(m);
166
167  /* chop off a local realm */
168  tobuff=short_zuser(to);
169
170  /* expand ~ in path names */
171  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
172
173  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
174  file=fopen(filename, "a");
175  if (!file) {
176    owl_function_error("Unable to open file for outgoing logging");
177    owl_free(logpath);
178    owl_free(tobuff);
179    return;
180  }
181  fprintf(file, "ERROR (owl): %s\n%s\n", tobuff, text);
182  if (text[strlen(text)-1]!='\n') {
183    fprintf(file, "\n");
184  }
185  fclose(file);
186
187  snprintf(filename, MAXPATHLEN, "%s/all", logpath);
188  owl_free(logpath);
189  file=fopen(filename, "a");
190  if (!file) {
191    owl_function_error("Unable to open file for outgoing logging");
192    owl_free(tobuff);
193    return;
194  }
195  fprintf(file, "ERROR (owl): %s\n%s\n", tobuff, text);
196  if (text[strlen(text)-1]!='\n') {
197    fprintf(file, "\n");
198  }
199  fclose(file);
200
201  owl_free(tobuff);
202}
203
204void owl_log_outgoing_aim(owl_message *m)
205{
206  FILE *file;
207  char filename[MAXPATHLEN], *logpath;
208  char *tobuff, *normalto, *text;
209
210  owl_function_debugmsg("owl_log_outgoing_aim: entering");
211
212  /* normalize and downcase the screenname */
213  normalto=owl_aim_normalize_screenname(owl_message_get_recipient(m));
214  downstr(normalto);
215  tobuff=owl_sprintf("aim:%s", normalto);
216  owl_free(normalto);
217
218  /* expand ~ in path names */
219  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
220
221  text=owl_message_get_body(m);
222 
223  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
224  file=fopen(filename, "a");
225  if (!file) {
226    owl_function_error("Unable to open file for outgoing logging");
227    owl_free(logpath);
228    owl_free(tobuff);
229    return;
230  }
231  fprintf(file, "OUTGOING (owl): %s\n%s\n", tobuff, text);
232  if (text[strlen(text)-1]!='\n') {
233    fprintf(file, "\n");
234  }
235  fclose(file);
236
237  snprintf(filename, MAXPATHLEN, "%s/all", logpath);
238  owl_free(logpath);
239  file=fopen(filename, "a");
240  if (!file) {
241    owl_function_error("Unable to open file for outgoing logging");
242    owl_free(tobuff);
243    return;
244  }
245  fprintf(file, "OUTGOING (owl): %s\n%s\n", tobuff, text);
246  if (text[strlen(text)-1]!='\n') {
247    fprintf(file, "\n");
248  }
249  fclose(file);
250
251  owl_free(tobuff);
252}
253
254void owl_log_outgoing_loopback(owl_message *m)
255{
256  FILE *file;
257  char filename[MAXPATHLEN], *logpath;
258  char *tobuff, *text;
259
260  tobuff=owl_sprintf("loopback");
261
262  /* expand ~ in path names */
263  logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
264
265  text=owl_message_get_body(m);
266
267  snprintf(filename, MAXPATHLEN, "%s/%s", logpath, tobuff);
268  file=fopen(filename, "a");
269  if (!file) {
270    owl_function_error("Unable to open file for outgoing logging");
271    owl_free(logpath);
272    owl_free(tobuff);
273    return;
274  }
275  fprintf(file, "OUTGOING (owl): %s\n%s\n", tobuff, text);
276  if (text[strlen(text)-1]!='\n') {
277    fprintf(file, "\n");
278  }
279  fclose(file);
280
281  snprintf(filename, MAXPATHLEN, "%s/all", logpath);
282  owl_free(logpath);
283  file=fopen(filename, "a");
284  if (!file) {
285    owl_function_error("Unable to open file for outgoing logging");
286    owl_free(tobuff);
287    return;
288  }
289  fprintf(file, "OUTGOING (owl): %s\n%s\n", tobuff, text);
290  if (text[strlen(text)-1]!='\n') {
291    fprintf(file, "\n");
292  }
293  fclose(file);
294
295  owl_free(tobuff);
296}
297
298void owl_log_incoming(owl_message *m)
299{
300  FILE *file, *allfile;
301  char filename[MAXPATHLEN], allfilename[MAXPATHLEN], *logpath;
302  char *frombuff=NULL, *from=NULL, *zsig=NULL;
303  int len, ch, i, personal;
304
305  /* figure out if it's a "personal" message or not */
306  if (owl_message_is_type_zephyr(m)) {
307    if (owl_message_is_personal(m)) {
308      personal=1;
309    } else {
310      personal=0;
311    }
312  } else {
313    if (owl_message_is_private(m) || owl_message_is_loginout(m)) {
314      personal=1;
315    } else {
316      personal=0;
317    }
318  }
319
320  if (owl_message_is_type_zephyr(m)) {
321    if (personal) {
322      if (owl_message_is_type_zephyr(m)) {
323        from=frombuff=short_zuser(owl_message_get_sender(m));
324      }
325    } else {
326      from=frombuff=owl_strdup(owl_message_get_class(m));
327    }
328  } else if (owl_message_is_type_aim(m)) {
329    /* we do not yet handle chat rooms */
330    char *normalto;
331    normalto=owl_aim_normalize_screenname(owl_message_get_sender(m));
332    downstr(normalto);
333    from=frombuff=owl_sprintf("aim:%s", normalto);
334    owl_free(normalto);
335  } else if (owl_message_is_type_loopback(m)) {
336    from=frombuff=owl_strdup("loopback");
337  } else {
338    from=frombuff=owl_strdup("unknown");
339  }
340 
341  /* check for malicious sender formats */
342  len=strlen(frombuff);
343  if (len<1 || len>35) from="weird";
344  if (strchr(frombuff, '/')) from="weird";
345
346  ch=frombuff[0];
347  if (!isalnum(ch)) from="weird";
348
349  for (i=0; i<len; i++) {
350    if (frombuff[i]<'!' || frombuff[i]>='~') from="weird";
351  }
352
353  if (!strcmp(frombuff, ".") || !strcasecmp(frombuff, "..")) from="weird";
354
355  if (!personal) {
356    if (strcmp(from, "weird")) downstr(from);
357  }
358
359  /* create the filename (expanding ~ in path names) */
360  if (personal) {
361    logpath = owl_text_substitute(owl_global_get_logpath(&g), "~", owl_global_get_homedir(&g));
362    snprintf(filename, MAXPATHLEN, "%s/%s", logpath, from);
363    snprintf(allfilename, MAXPATHLEN, "%s/all", logpath);
364
365  } else {
366    logpath = owl_text_substitute(owl_global_get_classlogpath(&g), "~", owl_global_get_homedir(&g));
367    snprintf(filename, MAXPATHLEN, "%s/%s", logpath, from);
368  }
369  owl_free(logpath);
370 
371  file=fopen(filename, "a");
372  if (!file) {
373    owl_function_error("Unable to open file for incoming logging");
374    owl_free(frombuff);
375    return;
376  }
377
378  allfile=NULL;
379  if (personal) {
380    allfile=fopen(allfilename, "a");
381    if (!allfile) {
382      owl_function_error("Unable to open file for incoming logging");
383      owl_free(frombuff);
384      fclose(file);
385      return;
386    }
387  }
388
389  /* write to the main file */
390  if (owl_message_is_type_zephyr(m)) {
391    char *tmp;
392   
393    tmp=short_zuser(owl_message_get_sender(m));
394    fprintf(file, "Class: %s Instance: %s", owl_message_get_class(m), owl_message_get_instance(m));
395    if (strcmp(owl_message_get_opcode(m), "")) fprintf(file, " Opcode: %s", owl_message_get_opcode(m));
396    fprintf(file, "\n");
397    fprintf(file, "Time: %s Host: %s\n", owl_message_get_timestr(m), owl_message_get_hostname(m));
398    zsig=owl_message_get_zsig(m);
399    fprintf(file, "From: %s <%s>\n\n", zsig, tmp);
400    fprintf(file, "%s\n\n", owl_message_get_body(m));
401    owl_free(tmp);
402  } else if (owl_message_is_type_aim(m) && !owl_message_is_loginout(m)) {
403    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
404    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
405    fprintf(file, "%s\n\n", owl_message_get_body(m));
406  } else if (owl_message_is_type_aim(m) && owl_message_is_loginout(m)) {
407    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
408    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
409    if (owl_message_is_login(m)) fprintf(file, "LOGIN\n\n");
410    if (owl_message_is_logout(m)) fprintf(file, "LOGOUT\n\n");
411  } else {
412    fprintf(file, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
413    fprintf(file, "Time: %s\n\n", owl_message_get_timestr(m));
414    fprintf(file, "%s\n\n", owl_message_get_body(m));
415  }
416
417  fclose(file);
418
419  /* if it's a personal message, also write to the 'all' file */
420  if (personal) {
421    if (owl_message_is_type_zephyr(m)) {
422      char *tmp;
423
424      tmp=short_zuser(owl_message_get_sender(m));
425      fprintf(allfile, "Class: %s Instance: %s", owl_message_get_class(m), owl_message_get_instance(m));
426      if (strcmp(owl_message_get_opcode(m), "")) fprintf(allfile, " Opcode: %s", owl_message_get_opcode(m));
427      fprintf(allfile, "\n");
428      fprintf(allfile, "Time: %s Host: %s\n", owl_message_get_timestr(m), owl_message_get_hostname(m));
429      fprintf(allfile, "From: %s <%s>\n\n", zsig, tmp);
430      fprintf(allfile, "%s\n\n", owl_message_get_body(m));
431      owl_free(tmp);
432    } else if (owl_message_is_type_aim(m) && !owl_message_is_loginout(m)) {
433      fprintf(allfile, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
434      fprintf(allfile, "Time: %s\n\n", owl_message_get_timestr(m));
435      fprintf(allfile, "%s\n\n", owl_message_get_body(m));
436    } else if (owl_message_is_type_aim(m) && owl_message_is_loginout(m)) {
437      fprintf(allfile, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
438      fprintf(allfile, "Time: %s\n\n", owl_message_get_timestr(m));
439      if (owl_message_is_login(m)) fprintf(allfile, "LOGIN\n\n");
440      if (owl_message_is_logout(m)) fprintf(allfile, "LOGOUT\n\n");
441    } else {
442      fprintf(allfile, "From: <%s> To: <%s>\n", owl_message_get_sender(m), owl_message_get_recipient(m));
443      fprintf(allfile, "Time: %s\n\n", owl_message_get_timestr(m));
444      fprintf(allfile, "%s\n\n", owl_message_get_body(m));
445    }
446    fclose(allfile);
447  }
448
449  owl_free(frombuff);
450}
Note: See TracBrowser for help on using the repository browser.