1 : /*
2 : * This file is part of MIN Test Framework. Copyright © 2008 Nokia Corporation
3 : * and/or its subsidiary(-ies).
4 : * Contact: Konrad Marek Zapalowicz
5 : * Contact e-mail: DG.MIN-Support@nokia.com
6 : *
7 : * This program is free software: you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the Free
9 : * Software Foundation, version 2 of the License.
10 : *
11 : * This program is distributed in the hope that it will be useful, but WITHOUT
12 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 : * more details. You should have received a copy of the GNU General Public
15 : * License along with this program. If not, see
16 : * <http://www.gnu.org/licenses/>.
17 : */
18 :
19 :
20 : /**
21 : * @file min_logger_output.c
22 : * @version 0.1
23 : * @brief This file contains implementation of MIN Logger output plugins
24 : */
25 :
26 : /* ------------------------------------------------------------------------- */
27 : /* INCLUDE FILES */
28 : #include <min_system_logger.h>
29 : #include <min_logger_output.h>
30 : #include <min_logger.h>
31 : #include <sys/time.h>
32 : #include <syslog.h>
33 : /* ------------------------------------------------------------------------- */
34 : /* EXTERNAL DATA STRUCTURES */
35 : /* None */
36 :
37 : /* ------------------------------------------------------------------------- */
38 : /* EXTERNAL GLOBAL VARIABLES */
39 :
40 : /* ------------------------------------------------------------------------- */
41 : /* EXTERNAL FUNCTION PROTOTYPES */
42 : /* None */
43 :
44 : /* ------------------------------------------------------------------------- */
45 : /* GLOBAL VARIABLES */
46 : /* None */
47 :
48 : /* ------------------------------------------------------------------------- */
49 : /* CONSTANTS */
50 : /* None */
51 :
52 : /* ------------------------------------------------------------------------- */
53 : /* MACROS */
54 : /* None */
55 :
56 : /* ------------------------------------------------------------------------- */
57 : /* LOCAL GLOBAL VARIABLES */
58 : /* None */
59 :
60 : /* ------------------------------------------------------------------------- */
61 : /* LOCAL CONSTANTS AND MACROS */
62 : /* None */
63 :
64 : /* ------------------------------------------------------------------------- */
65 : /* MODULE DATA STRUCTURES */
66 : /* None */
67 :
68 : /* ------------------------------------------------------------------------- */
69 : /* LOCAL FUNCTION PROTOTYPES */
70 : /* ------------------------------------------------------------------------- */
71 : /** Writes message through the file output.
72 : * @param fo [in] file output plugin used for writing.
73 : * @param with_timestamp [in] flag indicates presence of timestamp.
74 : * @param with_linebreak [in] flag indicating presence of linebreak.
75 : * @param with_eventrank [in] on/off for event ranking feature.
76 : * @param data [in] the data to be written. */
77 : LOCAL void fo_write (struct output_typeinfo_t *fo,
78 : TSBool with_timestamp,
79 : TSBool with_linebreak,
80 : TSBool with_eventrank, const TSChar * data);
81 : /* ------------------------------------------------------------------------- */
82 : /** Creates new directory.
83 : * @param fo [in] file output plugin used for this operation.
84 : * @param path [in] new directory to be created.
85 : */
86 : LOCAL void fo_create_directory (struct min_logger_file_output_t *fo,
87 : const TSChar * path);
88 : /* ------------------------------------------------------------------------- */
89 : /** Opens existing file.
90 : * @param fo [in] file output plugin used for this operation.
91 : * @param path [in] path to the file we want to open.
92 : * @param file [in] file name we want to open.
93 : */
94 : LOCAL void fo_open_existing_file (struct min_logger_file_output_t *fo,
95 : const TSChar * path,
96 : const TSChar * file);
97 : /* ------------------------------------------------------------------------- */
98 : /** Creates new file.
99 : * @param fo [in] file output plugin used for this operation.
100 : * @param path [in] path under which we want file to be created.
101 : * @param file [in] name of the file we want to create.
102 : */
103 : LOCAL void fo_create_new_file (struct min_logger_file_output_t *fo,
104 : const TSChar * path, const TSChar * file);
105 : /* ------------------------------------------------------------------------- */
106 : /** Adds event ranking to the data.
107 : * @param data [in:out] data to which event ranking is appended.
108 : */
109 : LOCAL void fo_event_ranking (TSChar * data);
110 : /* ------------------------------------------------------------------------- */
111 : /** Adds timestamp tp data.
112 : * @param data [in:out] data to which timestamp is appended.
113 : */
114 : LOCAL void fo_add_timestamp_to_data (TSChar * data);
115 : /* ------------------------------------------------------------------------- */
116 : /** Gest the type of the file.
117 : * @param fo [in] file output plugin used for this operation.
118 : * @param filename [in] the name of the file to be checked.
119 : * @param filetype [out] the type of checked file.
120 : *
121 : * NOTE: filetype is malloced inside of this function.
122 : */
123 : LOCAL void fo_file_type (struct min_logger_file_output_t *fo,
124 : const TSChar * filename, TSChar ** filetype);
125 : /* ------------------------------------------------------------------------- */
126 : /** Generate pricess id to test file name.
127 : * @param file [in] old file name.
128 : * @param newfile [out] file name with pid.
129 : *
130 : */
131 : LOCAL void fo_test_file_with_pid (const TSChar * file, TSChar * newfile);
132 : /* ------------------------------------------------------------------------- */
133 : /** Writes message through the null output.
134 : * @param fo [in] file output plugin used for writing.
135 : * @param with_timestamp [in] flag indicates presence of timestamp.
136 : * @param with_linebreak [in] flag indicating presence of linebreak.
137 : * @param with_eventrank [in] on/off for event ranking feature.
138 : * @param data [in] the data to be written. */
139 : LOCAL inline void no_write (struct output_typeinfo_t *fo,
140 : TSBool with_timestamp,
141 : TSBool with_linebreak,
142 : TSBool with_eventrank, const TSChar * data);
143 : /* ------------------------------------------------------------------------- */
144 : /** Writes message through the syslog output.
145 : * @param so [in] syslog output plugin used for writing.
146 : * @param with_timestamp [in] flag indicates presence of timestamp.
147 : * @param with_linebreak [in] flag indicating presence of linebreak.
148 : * @param with_eventrank [in] on/off for event ranking feature.
149 : * @param data [in] the data to be written. */
150 : LOCAL void so_write (struct output_typeinfo_t *so,
151 : TSBool with_timestamp,
152 : TSBool with_linebreak,
153 : TSBool with_eventrank, const TSChar * data);
154 : /* ------------------------------------------------------------------------- */
155 : /* FORWARD DECLARATIONS */
156 : /* None */
157 :
158 : /* ------------------------------------------------------------------------- */
159 : /* ==================== LOCAL FUNCTIONS ==================================== */
160 : /* ------------------------------------------------------------------------- */
161 : LOCAL void fo_write (struct output_typeinfo_t *fo,
162 : TSBool with_timestamp,
163 : TSBool with_linebreak,
164 : TSBool with_eventrank, const TSChar * data)
165 2833 : {
166 2833 : MinLoggerFileOutput *sxfo = INITPTR;
167 2833 : unsigned int extralength = 0;
168 2833 : unsigned int datalen = 0;
169 2833 : unsigned int currlen = 0;
170 2833 : int ret = 0;
171 2833 : TSChar *buffer = INITPTR;
172 :
173 2833 : if (fo == INITPTR) {
174 0 : goto EXIT;
175 : }
176 2833 : if (data == INITPTR) {
177 0 : goto EXIT;
178 : }
179 :
180 2833 : sxfo = (MinLoggerFileOutput *) fo;
181 2833 : if (!sxfo->isfileopen_) { goto EXIT; }
182 2833 : datalen = strlen (data);
183 :
184 : /* Extra space calculation */
185 2833 : if (sxfo->witheventranking_ && with_eventrank) {
186 2627 : extralength = MaxEventRanking;
187 : }
188 :
189 2833 : if ((sxfo->loggertype_ == ESHtml) && sxfo->withlinebreak_
190 : && with_linebreak) {
191 : /* <br /> = 6 */
192 5 : extralength += MaxHtmlLineBreak;
193 : }
194 :
195 2833 : if (sxfo->withlinebreak_ && with_linebreak) {
196 : /* \n\0 */
197 5 : extralength += 1 + 1;
198 : }
199 :
200 2833 : if (sxfo->withtimestamp_ && with_timestamp) {
201 2628 : extralength += MaxTimeString;
202 : }
203 :
204 : /* Data straight to the file */
205 2833 : if ((extralength == 0) && (sxfo->unicode_ == ESFalse)) {
206 200 : ret = fwrite (data, sizeof (TSChar), datalen, sxfo->file_);
207 200 : if (ret != datalen) {
208 0 : MIN_WARN ("Error in writing to the file");
209 : }
210 200 : goto EXIT;
211 : }
212 :
213 : /* Output buffer creation */
214 2633 : if (sxfo->databuf_ != INITPTR) {
215 : /* will use buffer created in fo_create */
216 0 : if ((datalen + extralength) >= sxfo->buffersize_) {
217 0 : MIN_WARN ("Buffersize too small [%d]>=[%d]",
218 : datalen + extralength,
219 : sxfo->buffersize_);
220 0 : goto EXIT;
221 : } else {
222 0 : buffer = &sxfo->databuf_[0];
223 : }
224 : } else {
225 : /* will use locally created buffer */
226 2633 : buffer = NEW2 (TSChar, datalen + extralength + 1);
227 2633 : if (buffer == NULL) {
228 0 : MIN_WARN ("Buffer size to big [%d]",
229 : datalen + extralength + 1);
230 0 : goto EXIT;
231 : }
232 2633 : memset (buffer, '\0', datalen + extralength + 1);
233 : }
234 :
235 : /* Prefix: eventranking, timestamp */
236 5260 : if (sxfo->witheventranking_ && with_eventrank && sxfo->withtimestamp_) {
237 2627 : fo_event_ranking (buffer);
238 2627 : currlen = strlen (buffer);
239 6 : } else if (sxfo->withtimestamp_ && with_timestamp) {
240 1 : if (sxfo->witheventranking_ && with_eventrank) {
241 0 : fo_event_ranking (buffer);
242 0 : currlen = strlen (buffer);
243 : }
244 1 : fo_add_timestamp_to_data (&buffer[currlen]);
245 1 : currlen = strlen (buffer);
246 : }
247 :
248 : /* The real message: copy data */
249 2633 : STRCPY (&buffer[currlen], data, datalen);
250 2633 : currlen = strlen (buffer);
251 :
252 : /* Postfix: line ending */
253 2633 : if ((sxfo->loggertype_ == ESHtml) && sxfo->withlinebreak_
254 : && with_linebreak) {
255 5 : STRCPY (&buffer[currlen], "<br />", 6);
256 5 : currlen += 6;
257 : }
258 :
259 2633 : if (sxfo->withlinebreak_ && with_linebreak) {
260 5 : STRCPY (&buffer[currlen], "\n", 2);
261 5 : currlen += 1;
262 : }
263 :
264 : /* Write data to the file */
265 2633 : if (sxfo->unicode_ == ESTrue) {
266 : /* Not supported yet */
267 :
268 : } else {
269 : /* Normal writing */
270 2633 : ret = fwrite (buffer, sizeof (TSChar), currlen, sxfo->file_);
271 2633 : fflush(sxfo->file_);
272 2633 : if (ret != currlen) {
273 0 : MIN_WARN ("Error in writing to the file");
274 : }
275 : }
276 :
277 : /* Clean-up */
278 2633 : if (sxfo->buffersize_ == 0) {
279 2633 : DELETE (buffer);
280 : }
281 : else {
282 0 : memset (sxfo->databuf_, '\0', sxfo->buffersize_);
283 : }
284 :
285 2833 : EXIT:
286 : return;
287 : }
288 :
289 : /* ------------------------------------------------------------------------- */
290 : LOCAL void fo_open_existing_file (struct min_logger_file_output_t *fo,
291 : const TSChar * path, const TSChar * file)
292 349 : {
293 349 : TSChar *fname = INITPTR;
294 349 : TSChar *file_ext = INITPTR;
295 349 : TSChar *file_new = INITPTR;
296 349 : TSChar *c = INITPTR;
297 : TSChar file_tmp[MaxFileName];
298 349 : int len = 0;
299 :
300 349 : if (fo == INITPTR) {
301 0 : goto EXIT;
302 : }
303 349 : if (path == INITPTR) {
304 0 : goto EXIT;
305 : }
306 349 : if (file == INITPTR) {
307 0 : goto EXIT;
308 : }
309 :
310 : /* Filename string must be valid for open existing file */
311 349 : if (strlen (file) > 0) {
312 : /* If existing file is open, then close this file first */
313 349 : if (fo->isfileopen_) {
314 8 : fclose (fo->file_);
315 8 : if (fo->fileanddirname_) {
316 8 : DELETE (fo->fileanddirname_);
317 8 : fo->isfileopen_ = ESFalse;
318 : }
319 : }
320 :
321 349 : fo_file_type (fo, file, &file_ext);
322 349 : c = strrchr (file, '.');
323 :
324 350 : if ((c != NULL) && (fo->pididtologfile_)) {
325 1 : fo_test_file_with_pid (file, file_tmp);
326 1 : file_new = NEW2 (TSChar, MaxFileName);
327 1 : len = c - file;
328 1 : STRCPY (file_new, file, len);
329 1 : STRCPY (file_new + len, file_tmp,
330 : strlen (file_tmp) + 1);
331 : } else {
332 348 : file_new =
333 : NEW2 (TSChar,
334 : strlen (file) + strlen (file_ext) + 1);
335 348 : sprintf (file_new, "%s%s", file, file_ext);
336 : }
337 :
338 349 : DELETE (file_ext);
339 :
340 349 : fname = NEW2 (TSChar, strlen (path) + strlen (file_new) + 2);
341 :
342 349 : if (path[strlen (path) - 1] == '/') {
343 7 : sprintf (fname, "%s%s", path, file_new);
344 : } else {
345 342 : sprintf (fname, "%s/%s", path, file_new);
346 : }
347 :
348 349 : fo->file_ = fopen (fname, "a");
349 :
350 349 : if (fo->file_) {
351 349 : fo->fileanddirname_ = fname;
352 349 : fo->isfileopen_ = ESTrue;
353 : } else {
354 0 : fo->file_ = INITPTR;
355 0 : fo->isfileopen_ = ESFalse;
356 0 : DELETE (fname);
357 : }
358 : }
359 349 : EXIT:
360 : return;
361 : }
362 :
363 : /* ------------------------------------------------------------------------- */
364 : LOCAL void fo_create_new_file (struct min_logger_file_output_t *fo,
365 : const TSChar * path, const TSChar * file)
366 68 : {
367 68 : TSChar *fname = INITPTR;
368 68 : TSChar *file_ext = INITPTR;
369 68 : TSChar *file_new = INITPTR;
370 68 : TSChar *c = INITPTR;
371 : TSChar file_tmp[MaxFileName];
372 68 : int len = 0;
373 :
374 68 : if (fo == INITPTR) {
375 0 : goto EXIT;
376 : }
377 68 : if (path == INITPTR) {
378 0 : goto EXIT;
379 : }
380 68 : if (file == INITPTR) {
381 0 : goto EXIT;
382 : }
383 :
384 : /* Filename string must be exist for new file creation */
385 68 : if (strlen (file) > 0) {
386 : /* If existing file is open, then close this file first */
387 68 : if (fo->isfileopen_) {
388 0 : fclose (fo->file_);
389 0 : if (fo->fileanddirname_) {
390 0 : DELETE (fo->fileanddirname_);
391 0 : fo->isfileopen_ = ESFalse;
392 : }
393 : }
394 68 : fo_file_type (fo, file, &file_ext);
395 68 : c = strrchr (file, '.');
396 :
397 95 : if ((c != NULL) && (fo->pididtologfile_)) {
398 27 : fo_test_file_with_pid (file, file_tmp);
399 27 : file_new = NEW2 (TSChar, MaxFileName);
400 27 : len = c - file;
401 27 : STRCPY (file_new, file, len);
402 27 : STRCPY (file_new + len, file_tmp,
403 : strlen (file_tmp) + 1);
404 : } else {
405 41 : file_new =
406 : NEW2 (TSChar,
407 : strlen (file) + strlen (file_ext) + 1);
408 41 : sprintf (file_new, "%s%s", file, file_ext);
409 : }
410 :
411 68 : DELETE (file_ext);
412 :
413 68 : fname = NEW2 (TSChar, strlen (path) + strlen (file_new) + 2);
414 :
415 68 : if (path[strlen (path) - 1] == '/') {
416 38 : sprintf (fname, "%s%s", path, file_new);
417 : } else {
418 30 : sprintf (fname, "%s/%s", path, file_new);
419 : }
420 68 : DELETE (file_new);
421 :
422 68 : fo->file_ = fopen (fname, "a");
423 :
424 68 : if (fo->file_) {
425 66 : fo->fileanddirname_ = fname;
426 66 : fo->isfileopen_ = ESTrue;
427 : } else {
428 2 : fo->file_ = INITPTR;
429 2 : fo->isfileopen_ = ESFalse;
430 2 : DELETE (fname);
431 : }
432 : }
433 68 : EXIT:
434 : return;
435 : }
436 :
437 : /* ------------------------------------------------------------------------- */
438 : LOCAL void fo_create_directory (struct min_logger_file_output_t *fo,
439 : const TSChar * path)
440 365 : {
441 365 : int retval = ENOERR;
442 365 : if (fo == INITPTR) {
443 0 : goto EXIT;
444 : }
445 365 : if (path == INITPTR) {
446 0 : goto EXIT;
447 : }
448 365 : retval = mkdir (path, S_IRWXU | S_IRWXG | S_IRWXO);
449 365 : if (retval == -1) {
450 365 : MIN_WARN ("Cannot create a directory: [%s], because: %s",
451 : path, strerror (errno));
452 : }
453 365 : EXIT:
454 : return;
455 : }
456 :
457 : /* ------------------------------------------------------------------------- */
458 : LOCAL void fo_event_ranking (TSChar * data)
459 2630 : {
460 : time_t ticks;
461 :
462 2630 : if (data == INITPTR) {
463 1 : min_err ("%s:%s:%d - data string equal to INITPTR", __FILE__,
464 : __FUNCTION__, __LINE__);
465 1 : goto EXIT;
466 : }
467 :
468 2629 : ticks = time (NULL) / (long int)64;
469 2629 : ticks &= 0xffff;
470 :
471 : /* Output it */
472 2629 : sprintf (data, "%5ld ", (long int)ticks);
473 2630 : EXIT:
474 : return;
475 : }
476 :
477 : /* ------------------------------------------------------------------------- */
478 : LOCAL void fo_file_type (struct min_logger_file_output_t *fo,
479 : const TSChar * filename, TSChar ** filetype)
480 441 : {
481 441 : TSBool filetypeisset = ESFalse;
482 441 : TSChar *c = INITPTR;
483 : char tmp[16];
484 441 : tmp[0] = '\0';
485 :
486 441 : if (fo == INITPTR) {
487 0 : goto EXIT;
488 : }
489 441 : if (filename == INITPTR) {
490 0 : goto EXIT;
491 : }
492 :
493 : /* Check if extension is set for file. If not then add process ID - if
494 : * it is allowed. */
495 441 : c = strrchr (filename, '.');
496 441 : if (c != NULL) {
497 45 : filetypeisset = ESTrue;
498 396 : } else if (fo->pididtologfile_ == ESTrue) {
499 18 : sprintf (tmp, "_%x", getpid ());
500 : }
501 :
502 : /* Add file type after process id. */
503 802 : if (fo->loggertype_ == ESTxt && !filetypeisset) {
504 361 : c = strchr (tmp, '\0');
505 361 : sprintf (c, ".txt");
506 80 : } else if (fo->loggertype_ == ESHtml && !filetypeisset) {
507 30 : c = strchr (tmp, '\0');
508 30 : sprintf (c, ".html");
509 : }
510 :
511 441 : *filetype = NEW2 (char, strlen (tmp) + 1);
512 441 : STRCPY (*filetype, tmp, strlen (tmp) + 1);
513 441 : EXIT:
514 : return;
515 : }
516 :
517 : /* ------------------------------------------------------------------------- */
518 : LOCAL void fo_test_file_with_pid (const TSChar * file, TSChar * newfile)
519 35 : {
520 35 : char *c = INITPTR;
521 :
522 35 : if (file == INITPTR) {
523 1 : goto EXIT;
524 : }
525 34 : if (newfile == INITPTR) {
526 1 : goto EXIT;
527 : }
528 33 : if (strlen (file) == 0) {
529 1 : goto EXIT;
530 : }
531 :
532 : /* Look for dot */
533 32 : c = strrchr (file, '.');
534 :
535 32 : if (c != NULL) {
536 30 : sprintf (newfile, "_%x%s", getpid (), c);
537 : } else {
538 2 : sprintf (newfile, "%s", file);
539 : }
540 35 : EXIT:
541 : return;
542 : }
543 :
544 : /* ------------------------------------------------------------------------- */
545 : LOCAL void fo_add_timestamp_to_data (TSChar * data)
546 2 : {
547 : struct timeval tv;
548 : struct timezone tz;
549 2 : struct tm *time_data = INITPTR;
550 :
551 2 : if (data == INITPTR) {
552 0 : goto EXIT;
553 : }
554 :
555 2 : gettimeofday (&tv, &tz);
556 2 : time_data = localtime (&tv.tv_sec);
557 :
558 : /*
559 : Timestamp string format: "DD.MON.YEAR HH:MM:SS.MSC"
560 : DD = Day number (01-31)
561 : MON = Month number (01-12)
562 : YEAR = Year number (19xx)
563 : HH = Hours (00-11)
564 : MM = Minutes (00-59)
565 : SS = Seconds (00-59)
566 : MSC = Microseconds (000-999)
567 : */
568 2 : strftime (data, MaxTimeString, "%d.%b.%Y %X.", time_data);
569 2 : sprintf (data + (MaxTimeString - 7), "%3ld ", tv.tv_usec / 1000);
570 2 : EXIT:
571 : return;
572 : }
573 :
574 : /* ------------------------------------------------------------------------- */
575 : LOCAL inline void no_write (struct output_typeinfo_t *fo,
576 : TSBool with_timestamp,
577 : TSBool with_linebreak,
578 : TSBool with_eventrank, const TSChar * data)
579 2627 : {
580 : return;
581 : }
582 :
583 : /* ------------------------------------------------------------------------- */
584 : /* ======================== FUNCTIONS ====================================== */
585 : /* ------------------------------------------------------------------------- */
586 : MinLoggerFileOutput *fo_create (const TSChar * path,
587 : const TSChar * file,
588 : TSLoggerType loggertype,
589 : TSBool overwrite,
590 : TSBool withtimestamp,
591 : TSBool withlinebreak,
592 : TSBool witheventranking,
593 : TSBool pididtologfile,
594 : TSBool createlogdir,
595 : unsigned int buffersize, TSBool unicode)
596 393 : {
597 393 : MinLoggerFileOutput *retval = INITPTR;
598 393 : unsigned int flen = 0;
599 :
600 : /* Some errorchecking */
601 393 : if (path == INITPTR) {
602 1 : goto EXIT;
603 : }
604 392 : if (file == INITPTR) {
605 1 : goto EXIT;
606 : }
607 391 : flen = strlen (file);
608 391 : if (flen == 0) {
609 1 : goto EXIT;
610 : }
611 :
612 : /* Attach pointers */
613 390 : retval = NEW (MinLoggerFileOutput);
614 390 : retval->write_ = fo_write;
615 390 : retval->destroy_ = fo_destroy;
616 :
617 : /* Initialize variables */
618 390 : retval->loggertype_ = loggertype;
619 390 : retval->overwrite_ = overwrite;
620 390 : retval->withtimestamp_ = withtimestamp;
621 390 : retval->withlinebreak_ = withlinebreak;
622 390 : retval->witheventranking_ = witheventranking;
623 390 : retval->pididtologfile_ = pididtologfile;
624 390 : retval->createlogdir_ = createlogdir;
625 390 : retval->buffersize_ = buffersize;
626 390 : retval->unicode_ = unicode;
627 390 : retval->isfileopen_ = 0;
628 390 : retval->databuf_ = INITPTR;
629 :
630 : /** Perform the init phase */
631 390 : if (retval->createlogdir_)
632 365 : fo_create_directory (retval, path);
633 :
634 390 : if (retval->overwrite_)
635 49 : fo_create_new_file (retval, path, file);
636 : else
637 341 : fo_open_existing_file (retval, path, file);
638 :
639 390 : if (retval->buffersize_ > 0)
640 1 : retval->databuf_ = NEW2 (TSChar, retval->buffersize_);
641 393 : EXIT:
642 393 : return retval;
643 : }
644 :
645 : /* ------------------------------------------------------------------------- */
646 : void fo_destroy (struct output_typeinfo_t **o)
647 246 : {
648 246 : struct min_logger_file_output_t *sfo = INITPTR;
649 :
650 246 : if (*o == INITPTR) {
651 1 : goto EXIT;
652 : }
653 :
654 245 : sfo = (struct min_logger_file_output_t *)(*o);
655 :
656 245 : if (sfo->buffersize_ > 0) {
657 0 : DELETE (sfo->databuf_);
658 : }
659 245 : DELETE (sfo->fileanddirname_);
660 245 : DELETE (*o);
661 245 : *o = INITPTR;
662 246 : EXIT:
663 : return;
664 : }
665 :
666 : /* ------------------------------------------------------------------------- */
667 : MinLoggerNullOutput *no_create (const TSChar * path,
668 : const TSChar * file,
669 : TSLoggerType loggertype,
670 : TSBool overwrite,
671 : TSBool withtimestamp,
672 : TSBool withlinebreak,
673 : TSBool witheventranking,
674 : TSBool pididtologfile,
675 : TSBool createlogdir,
676 : unsigned int buffersize, TSBool unicode)
677 340 : {
678 340 : MinLoggerNullOutput *retval = INITPTR;
679 :
680 : /* No errorchecking because there is no need for that,
681 : * NullOutput is not doing anything. */
682 :
683 : /* Attach pointers */
684 340 : retval = NEW (MinLoggerNullOutput);
685 340 : retval->write_ = no_write;
686 340 : retval->destroy_ = no_destroy;
687 :
688 340 : return retval;
689 : }
690 :
691 : /* ------------------------------------------------------------------------- */
692 : void no_destroy (struct output_typeinfo_t **o)
693 223 : {
694 223 : if (*o == INITPTR) {
695 0 : goto EXIT;
696 : }
697 223 : DELETE (*o);
698 223 : *o = INITPTR;
699 223 : EXIT:
700 : return;
701 : }
702 :
703 : /* ------------------------------------------------------------------------- */
704 : MinLoggerSyslogOutput *so_create (const TSChar * path,
705 : const TSChar * file,
706 : TSLoggerType loggertype,
707 : TSBool overwrite,
708 : TSBool withtimestamp,
709 : TSBool withlinebreak,
710 : TSBool witheventranking,
711 : TSBool pididtologfile,
712 : TSBool createlogdir,
713 : unsigned int buffersize, TSBool unicode)
714 343 : {
715 343 : MinLoggerSyslogOutput *retval = INITPTR;
716 :
717 343 : if (file == INITPTR) {
718 0 : goto EXIT;
719 : }
720 :
721 : /* Attach pointers */
722 343 : retval = NEW (MinLoggerSyslogOutput);
723 343 : retval->write_ = so_write;
724 343 : retval->destroy_ = so_destroy;
725 :
726 : /* Initialize variables */
727 343 : retval->unicode_ = unicode;
728 :
729 : /** Perform the init phase */
730 343 : openlog (file, LOG_PID | LOG_CONS, LOG_LOCAL0);
731 343 : EXIT:
732 343 : return retval;
733 : }
734 :
735 : /* ------------------------------------------------------------------------- */
736 : LOCAL void so_write (struct output_typeinfo_t *so,
737 : TSBool with_timestamp,
738 : TSBool with_linebreak,
739 : TSBool with_eventrank, const TSChar * data)
740 2628 : {
741 2628 : MinLoggerSyslogOutput *sxso = INITPTR;
742 :
743 2628 : if (so == INITPTR) {
744 0 : goto EXIT;
745 : }
746 2628 : if (data == INITPTR) {
747 0 : goto EXIT;
748 : }
749 :
750 2628 : sxso = (MinLoggerSyslogOutput *) so;
751 :
752 : /* Write data to the file */
753 2628 : if (sxso->unicode_ == ESTrue) {
754 : /* Not supported yet */
755 : } else {
756 : /* Normal syslog writing */
757 2628 : syslog (LOG_INFO,"%s", data);
758 : }
759 2628 : EXIT:
760 : return;
761 : }
762 :
763 : /* ------------------------------------------------------------------------- */
764 : void so_destroy (struct output_typeinfo_t **o)
765 225 : {
766 225 : if (*o == INITPTR) {
767 1 : goto EXIT;
768 : }
769 :
770 224 : closelog ();
771 224 : DELETE (*o);
772 224 : *o = INITPTR;
773 225 : EXIT:
774 : return;
775 : }
776 :
777 : /* ------------------------------------------------------------------------- */
778 : /* ================= OTHER EXPORTED FUNCTIONS ============================== */
779 : /* None */
780 :
781 : /* ------------------------------------------------------------------------- */
782 : /* ================= TESTS FOR LOCAL FUNCTIONS ============================= */
783 : #ifdef MIN_UNIT_TEST
784 : #include "min_logger_output.tests"
785 : #endif /* MIN_UNIT_TEST */
786 : /* End of file */
|