return to first page linux journal archive
keywordscontents

Source for cntr_module

  1-86  /* Comments */
 87 #include "httpd.h"
 88 #include "http_config.h"
 89 #include "http_core.h"
 90 #include "http_log.h"
 91 #include "http_protocol.h"
 92 #include <ndbm.h>
 93 #include <msql.h>
 94 
 95 module cntr_module;
 96 
 97 /*  Data structures  */
100 typedef enum { CntrMsql } CounterType;
101 typedef struct {
102 	unsigned long	count;
103 	char*		date;
104 } cntr_results;
106 typedef struct {
107 	int	cntr_default;
108 	CounterType	cntr_type;
109 	int	cntr_auto_add;
110 	char*	cntr_db;
111 	char*	cntr_table;
112 } cntr_config_rec;
113 
114 #define	DEF_CNTRTYPE	01
115 #define	DEF_CNTRAA	02
116 #define	DEF_CNTRDB	04
117 #define	DEF_ALL		
 (DEF_CNTRTYPE|DEF_CNTRAA|DEF_CNTRDB)
118 
119 /*  Set defaults  */
122 #define DEFAULT_CNTR_TYPE	CntrMsql
123 #define DEFAULT_TIME_FORMAT	
 "%A, %d-%b-%y %T %Z"
124 #define DEFAULT_DIRCNTR_DB	""
125 #define DEFAULT_DIRCNTR_TABLE	""
126 #define DEFAULT_SVRCNTR_DB	""
127 #define DEFAULT_SVRCNTR_TABLE	""
128 
129 /* Create config data structure */
132 void* create_cntr_dir_config_rec(
	pool* p, char* d)
133 {
134 	/* Set the defaults */
137 	cntr_config_rec * rec =
138 		(cntr_config_rec*)pcalloc
		  (p, sizeof(cntr_config_rec));
139 	rec->cntr_type = DEFAULT_CNTR_TYPE;
140 	rec->cntr_auto_add = 0;
141 	rec->cntr_db = DEFAULT_DIRCNTR_DB 
	  ? pstrdup(p, DEFAULT_DIRCNTR_DB) : NULL;
142 	rec->cntr_table = 
	  DEFAULT_DIRCNTR_TABLE ? 
	  pstrdup(p, DEFAULT_DIRCNTR_TABLE) : NULL;
143 	rec->cntr_default = DEF_ALL;
145 	return(rec);
146 }
148 void* create_cntr_srv_config_rec( 
	 pool* p, server_rec* d )
149 {
150 	/* Set the defaults */
153 	cntr_config_rec * rec =
154 	  (cntr_config_rec*) 
	  pcalloc(p, sizeof(cntr_config_rec));
155 	rec->cntr_type = DEFAULT_CNTR_TYPE;
156 	rec->cntr_auto_add = 0;
157 	rec->cntr_file = 
	  DEFAULT_SVRCNTR_DB ? 
	  pstrdup(p, DEFAULT_SVRCNTR_DB) : NULL;
158 	rec->cntr_file=DEFAULT_SVRCNTR_TABLE ?
	  pstrdup(p, DEFAULT_SVRCNTR_TABLE) : NULL;
159 	rec->cntr_default = DEF_ALL;
161 	return(rec);
162 }
164 void*   merge_config_rec( pool* p, 
	 void* parent, void* sub )
165 {
166 	cntr_config_rec * par = 
	  (cntr_config_rec *)parent;
167 	cntr_config_rec * chld = 
	  (cntr_config_rec *)sub;
168 	cntr_config_rec * mrg = 
	  (cntr_config_rec *)palloc(p, sizeof(*mrg));
169 	if (chld->cntr_default & DEF_CNTRTYPE)
170 		mrg->cntr_type = 
		  par->cntr_type;
171 	else
172 		mrg->cntr_type = 
		  chld->cntr_type;
173 	if (chld->cntr_default & DEF_CNTRAA)
174 		mrg->cntr_auto_add = 
		  par->cntr_auto_add;
175 	else
176 		mrg->cntr_auto_add = 
		  chld->cntr_auto_add;
177 	if (chld->cntr_default & DEF_CNTRDB) {
178 		mrg->cntr_db = 
		  par->cntr_db;
179 		mrg->cntr_table = 
	 	  par->cntr_table;
180 	} else {
181 		mrg->cntr_db = 
		  chld->cntr_db;
182 		mrg->cntr_table = 
		  chld->cntr_table;
183 	}
184 	mrg->cntr_default = 0;
185 	return(mrg);
186 }
188 const char* set_cntr_type( 
	 cmd_parms* cmd, void* ct, char* arg )
189 {
190 	void* ret = NULL;
191 	cntr_config_rec* conf = (cntr_config_rec*)ct;
193 	if (!strcasecmp(arg, "msql"))
194 		conf->cntr_type = CntrMsql;
195 	else
196 		ret = "CounterType must be Msql";
197 	conf->cntr_default &= ~DEF_CNTRTYPE;
199 	return(ret);
200 }
202 const char* set_cntr_autoadd( 
	 cmd_parms* cmd, void* ct, int arg )
203 {
204 	cntr_config_rec* conf = (cntr_config_rec*)ct;
205 	conf->cntr_auto_add = arg;
206 	conf->cntr_default &= ~DEF_CNTRAA;
207 	return(NULL);
208 }
210 const char* set_cntr_db( cmd_parms* cmd, 
	 void* ct, char* arg1, char* arg2 )
211 {
212 	void* ret = NULL;
213 	cntr_config_rec* conf = 
	  (cntr_config_rec*)ct;
215 	conf->cntr_db = arg1;
216 	conf->cntr_table = arg2;
217 	conf->cntr_default &= ~DEF_CNTRFILE;
219 	return(ret);
220 }
222 const char* set_svr_cntr_type( 
	 cmd_parms* cmd, void* ct, char* arg )
223 {
224 	return(set_cntr_type(cmd, get_module_config(
 	  cmd->server->module_config, 
	  &cntr_module), arg));
225 }
226 
227 const char* set_svr_cntr_autoadd( 
	 cmd_parms* cmd, void* ct, int arg )
228 {
229 	return(set_cntr_autoadd(cmd,
230 		get_module_config(
	 cmd->server->module_config,
	 &cntr_module), arg));
231 }
233 const char* set_svr_cntr_db(cmd_parms* cmd, 
	void* ct, char* arg1, char* arg2 )
234 {
235 	return(set_cntr_db(cmd,
236 		get_module_config(
	   cmd->server->module_config, 
	   &cntr_module), arg1, arg2));
237 }
239 command_rec cntr_cmds[] = {
240 { "CounterType", set_cntr_type, NULL, 
	 ACCESS_CONF, TAKE1, NULL },
241 { "CounterAutoAdd", set_cntr_autoadd, 
	 NULL, ACCESS_CONF, FLAG, NULL },
242 { "CounterDB", set_cntr_db, NULL, 
	 ACCESS_CONF, TAKE2,
243     "Name of counter Msql database 
	 followed by the name of the table" },
245 { "ServerCounterType", set_svr_cntr_type, 
	 NULL, RSRC_CONF, TAKE1, NULL },
246 { "ServerCounterAutoAdd", 
	 set_svr_cntr_autoadd, NULL, RSRC_CONF, 
 	 FLAG, NULL },
247 { "ServerCounterDB", set_svr_cntr_db, 
	 NULL, RSRC_CONF, TAKE2,
248     "Name of counter Msql database 
	 followed by the name of the table" },
250 { NULL }
251 };
253 char*	cntr_incmsql( pool* p, 
	 cntr_results* results,
254  cntr_config_rec* r, char* uri )
255 {
256 	int dbh = 0;
257 	int msql_result = 0;
258 	char in_query[HUGE_STRING_LEN];
259 	char out_query[HUGE_STRING_LEN];
260 	m_result *msql_out;
261 	m_row msql_data;
262 
263 	/* Connect to local Msql server */
264 	dbh = msqlConnect(NULL);
265 	if (dbh == -1)
266 		return(pstrcat(p, 
 "Failed to connect to local Msql server: ",
  msqlErrMsg, NULL));
267 
268 	/* Select database given to us */
269 	msql_result = msqlSelectDB(dbh, 
	  r->cntr_db);
270 	if (msql_result == -1) {
271 		msqlClose(dbh);
272 		return(pstrcat(p, 
	  "Failed to connect to database ", 
	  r->cntr_db, ": ", msqlErrMsg, NULL));
273 	}
274 	sprintf(in_query,
	  "SELECT cntr_count, cntr_date FROM %s 
	 WHERE uri='%s'", r->cntr_table, uri);
275 	msql_result = msqlQuery(dbh, in_query);
276 	if (msql_result == -1) {
277 		msqlClose(dbh);
278 		return(pstrcat(p,
  "SELECT Query Failed: ", msqlErrMsg, NULL));
279 	}
280 	msql_out = msqlStoreResult();
281 	msql_result = msqlNumRows(msql_out);
282 	if (msql_result) {
283 		msql_data = msqlFetchRow(msql_out);
284 		results->count = atoi(
		  msql_data[0]) + 1;
285 		results->date = msql_data[1];
286 		sprintf(out_query,
 "UPDATE %s SET cntr_count=%lu WHERE 
 uri='%s'", r->cntr_table, results->count, uri);
287 		msql_result = 
		  msqlQuery(dbh,out_query);
288 		if (msql_result == -1) {
289 			msqlFreeResult(msql_out);
290 			msqlClose(dbh);
291 			return(pstrcat(p, 
  "UPDATE Query Failed: ", msqlErrMsg, NULL));
292 		}
293 	} else if (r->cntr_auto_add) {
294 		results->count = 1;
295 		results->date = 
 ht_time(p, time(0L), DEFAULT_TIME_FORMAT, 0);
296 		sprintf(out_query,
 "INSERT INTO %s (uri, cntr_count, 
 cntr_date) VALUES ('%s', %lu, '%s')",
297 r->cntr_table, uri, results->count, 
 results->date);
298 		msql_result = msqlQuery(
		  dbh,out_query);
299 		if (msql_result = -1) {
300 			msqlFreeResult(msql_out);
301 			msqlClose(dbh);
302 			return(pstrcat(p, 
 "INSERT Query Failed: ", msqlErrMsg, 
 " : ", out_query, NULL));
303 		}
304 	}
305 	msqlFreeResult(msql_out);
306 	msqlClose(dbh);
307 	return(OK);
308       }
310 char*	cntr_inc( pool* p, cntr_results* 
	 results,
311 cntr_config_rec* r, char* uri )
312 {
313   /* Normalize the URI stripping out 
	 double "//" */
314   char* puri = pstrdup(p, uri);
315   char* ptr = puri;
316   while (ptr && *ptr) {
317     if (*ptr == '/' && *(ptr+1) == '/') {
318       char* q = ptr + 1;
319       while (*q = *(q+1))
320 	q++;
321     } else
322       ptr++;
323   }
325   if (r->cntr_type == CntrMsql)
326     return cntr_incmsql(p, results, r, 
	  puri);
327   else
328     return NULL;
329 }
331 int	cntr_update( request_rec* r )
332 {
333   char* buf;
334   char* dbfile;
335   int ret = OK;
336   cntr_results * res;
337   cntr_config_rec *svr, *dir;
338   cntr_results *sres, *dres;
339 
340   /* Get actual file, if locally redirected */
343   while (r->next)
344     r = r->next;
346   / * Skip if missing URI or this is an 
    	* included request */
348   if (!r->uri || !strcmp(r->protocol, 
	  "INCLUDED"))
349     return(DECLINED);
350   if (!S_ISREG(r->finfo.st_mode))
351     return(DECLINED);
352 
353   /* Get each of the counter files */
356   svr = get_module_config(
	 r->server->module_config, &cntr_module);
357   dir = get_module_config(
	 r->per_dir_config, &cntr_module);
358 
359   /* Return if no counter database */
362   if (!*svr->cntr_db && !*dir->cntr_db)
363     return(DECLINED);
364 
365   /* Allocate result structures */
368   sres = (cntr_results*)pcalloc(r->pool, 
	  sizeof(cntr_results));
369   dres = (cntr_results*)pcalloc(r->pool, 
	  sizeof(cntr_results));
370 
371   /* Bump up server configured counter */
374   if (*svr->cntr_db)
375     if (buf = cntr_inc(r->pool, sres, svr,
	   r->uri))
376       log_error(buf, r->server);
377 
378 /* Increment the directory counter file using
380  * the full file name instead of the URL */
382   if (*dir->cntr_db)
383     if (buf = cntr_inc(r->pool, dres, dir,
	    r->filename))
384       log_error(buf, r->server);
386 
388/* Now set the environment variables, take the
389 * server config as preference over the directory 
    * directory config. */
391   res = (sres->count) ? sres : dres;
392   dbfile = "Msql";
393   buf = pcalloc(r->pool, 16);
394   sprintf(buf, "%lu", res->count);
395   table_set(r->subprocess_env, 
	 "URL_COUNT", buf);
396   table_set(r->subprocess_env, 
	"URL_COUNT_RESET", res->date);
397   table_set(r->subprocess_env, 
	 "URL_COUNT_DB", dbfile);
399   return ret;
400 }
402 
403 module cntr_module = {
404   STANDARD_MODULE_STUFF,
405   NULL,	 /* initializer */
406   create_cntr_dir_config_rec, 
		 /* dir config creater */
407   NULL, 			
 /* dir merger --- default is to override */
408   create_cntr_srv_config_rec, 
 /* server config */
409   NULL, 	 /* merge server config */
410   cntr_cmds, /* command table */
411   NULL,	 /* handlers */
412   NULL, 	 /* filename translation */
413   NULL,	 /* check_user_id */
414   NULL,	 /* check auth */
415   NULL,	 /* check access */
416   NULL,	 /* type_checker */
417   cntr_update,  /* fixups */
418   NULL	 /* logger */
419 };