1 /*
2 ** Modular Logfile Analyzer
3 ** Copyright 2000 Jan Kneschke <jan@kneschke.de>
4 **
5 ** Homepage: http://www.modlogan.org
6 **
7 
8     This program is free software; you can redistribute it and/or modify
9     it under the terms of the GNU General Public License as published by
10     the Free Software Foundation; either version 2 of the License, or
11     (at your option) any later version, and provided that the above
12     copyright and permission notice is included with all distributed
13     copies of this or derived software.
14 
15     This program is distributed in the hope that it will be useful,
16     but WITHOUT ANY WARRANTY; without even the implied warranty of
17     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18     GNU General Public License for more details.
19 
20     You should have received a copy of the GNU General Public License
21     along with this program; if not, write to the Free Software
22     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
23 
24 **
25 ** $Id: parse.c,v 1.7 2004/03/18 02:31:51 ostborn Exp $
26 */
27 
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <string.h>
31 #include <time.h>
32 #include <ctype.h>
33 #include <errno.h>
34 
35 #include "mlocale.h"
36 #include "mplugins.h"
37 #include "mrecord.h"
38 #include "mdatatypes.h"
39 #include "misc.h"
40 
41 #include "plugin_config.h"
42 
parse_record_pcre(mconfig * ext_conf,mlogrec * record,buffer * b)43 int parse_record_pcre(mconfig *ext_conf, mlogrec *record, buffer *b) {
44 #define N 20 + 1
45 	const char **list;
46 	int ovector[3 * N], n;
47 
48 	config_input *conf = ext_conf->plugin_conf;
49 	mlogrec_web *recweb = NULL;
50 	mlogrec_web_ftp *recftp = NULL;
51 
52 	if (record->ext_type != M_RECORD_TYPE_WEB) {
53 		if (record->ext_type != M_RECORD_TYPE_UNSET) {
54 			mrecord_free_ext(record);
55 		}
56 
57 		record->ext_type = M_RECORD_TYPE_WEB;
58 		record->ext = mrecord_init_web();
59 	}
60 
61 	recweb = record->ext;
62 
63 	if (recweb == NULL) return M_RECORD_HARD_ERROR;
64 
65 	recweb->ext = mrecord_init_web_ftp();
66 	recweb->ext_type = M_RECORD_TYPE_WEB_FTP;
67 
68 	recftp = recweb->ext;
69 
70 	if (recftp == NULL) return M_RECORD_HARD_ERROR;
71 
72 	if ((n = pcre_exec(conf->match_pureftpd, conf->match_pureftpd_extra, b->ptr, b->used - 1, 0, 0, ovector, 3 * N)) < 0) {
73 		if (n == PCRE_ERROR_NOMATCH) {
74 			fprintf(stderr, "%s.%d: string doesn't match: %s\n", __FILE__, __LINE__, b->ptr);
75 			return M_RECORD_CORRUPT;
76 		} else {
77 			fprintf(stderr, "%s.%d: execution error while matching: %d\n", __FILE__, __LINE__, n);
78 			return M_RECORD_HARD_ERROR;
79 		}
80 	}
81 
82 	if (n) {
83 		pcre_get_substring_list(b->ptr, ovector, n, &list);
84 
85 		/* the meaning of the different fields (pureftpd) */
86 
87 		/*
88 		 * 1 - timestamp in sec
89 		 * 2 - session id
90 		 * 3 - username
91 		 * 4 - client-ip
92 		 * 5 - up/download
93 		 * 6 - size
94 		 * 7 - duration
95 		 * 8 - filename
96 		 */
97 
98 		record->timestamp = strtol(list[1], NULL, 10);
99 
100 		buffer_copy_string(recweb->req_user, (char *)list[3]);
101 
102 		buffer_copy_string(recweb->req_host_ip, (char *)list[4]);
103 
104 		switch(*list[5]) {
105 		case 'D':
106 			recftp->trans_command = M_RECORD_FTP_COMMAND_GET;
107 			break;
108 		case 'U':
109 			recftp->trans_command = M_RECORD_FTP_COMMAND_PUT;
110 			break;
111 		default:
112 			break;
113 		}
114 
115 		recweb->xfersize = strtol(list[6], NULL,10);
116 
117 		recftp->trans_duration = strtol(list[7], NULL,10);
118 
119 		buffer_copy_string(recweb->req_url, (char *)list[8]);
120 
121 		free(list);
122 	}
123 
124 	return M_RECORD_NO_ERROR;
125 }
126 
127 
mplugins_input_pureftpd_get_next_record(mconfig * ext_conf,mlogrec * record)128 int mplugins_input_pureftpd_get_next_record(mconfig *ext_conf, mlogrec *record) {
129 	int ret = 0;
130 	config_input *conf = ext_conf->plugin_conf;
131 
132 	if (record == NULL) return M_RECORD_HARD_ERROR;
133 
134 	/* fill the line buffer */
135 	if (NULL == mgets(&(conf->inputfile), conf->buf)) return M_RECORD_EOF;
136 
137 	ret = parse_record_pcre   (ext_conf, record, conf->buf);
138 
139 	if (ret == M_RECORD_CORRUPT) {
140 		M_DEBUG1(ext_conf->debug_level, M_DEBUG_SECTION_PARSING, M_DEBUG_LEVEL_WARNINGS,
141 			 "affected Record: %s\n",
142 			 conf->buf->ptr
143 			 );
144 	}
145 	return ret;
146 }
147