1 static const char version[] = "$Id: appender_type_stream2.c,v 1.6 2013/09/29 17:39:27 valtri Exp $";
2 
3 /*
4  * appender_stream2.c
5  *
6  * Copyright 2001-2003, Meiosys (www.meiosys.com). All rights reserved.
7  *
8  * See the COPYING file for the terms of usage and distribution.
9  */
10 #include <stdio.h>
11 #include <string.h>
12 
13 #include <sd/malloc.h>
14 
15 #include <log4c/appender.h>
16 #include <log4c/appender_type_stream2.h>
17 
18 typedef struct stream2_udata {
19     FILE * s2u_fp;
20     int  s2u_flags;
21 #define STREAM2_MY_FP 0x01
22     int s2u_state;
23 } log4c_stream2_udata_t;
24 
25 /* xxx would be nice to run-time check the type here */
26 #define stream2_get_udata(this) \
27  (log4c_stream2_udata_t *)log4c_appender_get_udata(this)
28 
29 /*******************************************************************************/
30 static log4c_stream2_udata_t* stream2_make_udata(void);
31 static void stream2_free_udata(log4c_stream2_udata_t* s2up);
32 static log4c_stream2_udata_t * stream2_get_or_make_udata(log4c_appender_t* this);
33 static int stream2_init(log4c_appender_t* this);
34 
35 /*******************************************************************************/
stream2_init(log4c_appender_t * this)36 static int stream2_init(log4c_appender_t* this){
37     log4c_stream2_udata_t *s2up = stream2_make_udata();
38 
39     log4c_appender_set_udata(this, s2up);
40 
41     return(0);
42 }
43 
44 /*******************************************************************************/
stream2_open(log4c_appender_t * this)45 static int stream2_open(log4c_appender_t* this)
46 {
47     log4c_stream2_udata_t *s2up = NULL;
48     FILE * fp = NULL;
49     int flags = 0;
50 
51     if ( !this){
52 	return(-1);
53     }
54     s2up = stream2_get_or_make_udata(this);
55     /* s2up = stream2_get_udata(this); */
56 
57     fp = s2up->s2u_fp;
58     flags = s2up->s2u_flags;
59 
60     if ( !fp ) {
61 	if ( (fp = fopen(log4c_appender_get_name(this), "w+")) == NULL){
62 	    fp = stderr;
63 	} else {
64 	    s2up->s2u_state |= STREAM2_MY_FP;
65 	}
66 	s2up->s2u_fp = fp;
67     }
68 
69     if ( flags &  LOG4C_STREAM2_UNBUFFERED){/* unbuffered mode by default */
70 	setbuf(fp, NULL);
71     }
72 
73     return 0;
74 }
75 
76 /*******************************************************************************/
stream2_append(log4c_appender_t * this,const log4c_logging_event_t * a_event)77 static int stream2_append(log4c_appender_t* this,
78 			 const log4c_logging_event_t* a_event)
79 {
80     log4c_stream2_udata_t *s2up = log4c_appender_get_udata(this);
81 
82     if ( !s2up ) {
83 	return(-1);
84     }
85 
86     return fprintf(s2up->s2u_fp, "[%s] %s", log4c_appender_get_name(this),
87 		   a_event->evt_rendered_msg);
88 }
89 
90 /*******************************************************************************/
stream2_close(log4c_appender_t * this)91 static int stream2_close(log4c_appender_t* this)
92 {
93     log4c_stream2_udata_t *s2up = log4c_appender_get_udata(this);
94     int rc = -1;
95 
96     if ( !this){
97 	return rc;
98     }
99     s2up = stream2_get_udata(this);
100     if ( !s2up){
101 	return(rc);
102     }
103 
104     if ( s2up->s2u_fp && (s2up->s2u_state & STREAM2_MY_FP) ){
105 	rc = fclose(s2up->s2u_fp);
106     } else {
107 	rc = 0;
108     }
109     /* Free up and reset any data associated with this stream2 appender */
110     stream2_free_udata(s2up);
111     log4c_appender_set_udata(this, NULL);
112 
113     return (rc);
114 }
115 
116 /*******************************************************************************/
117 
stream2_make_udata()118 static log4c_stream2_udata_t* stream2_make_udata(){
119 
120     log4c_stream2_udata_t* s2up =
121 	(log4c_stream2_udata_t*) sd_calloc(1, sizeof(log4c_stream2_udata_t));
122     return(s2up);
123 }
124 
125 /*******************************************************************************/
126 
stream2_free_udata(log4c_stream2_udata_t * s2up)127 static void stream2_free_udata(log4c_stream2_udata_t* s2up){
128 
129     free(s2up);
130 }
131 
132 /*******************************************************************************/
133 
stream2_get_or_make_udata(log4c_appender_t * this)134 static log4c_stream2_udata_t * stream2_get_or_make_udata(log4c_appender_t* this){
135     log4c_stream2_udata_t *s2up;
136 
137     s2up = log4c_appender_get_udata(this);
138 
139     if ( !s2up) {
140 	stream2_init(this);
141     }
142 
143     return(stream2_get_udata(this));
144 }
145 
146 /*******************************************************************************/
log4c_stream2_set_fp(log4c_appender_t * this,FILE * fp)147 extern void log4c_stream2_set_fp(log4c_appender_t* this, FILE *fp){
148     log4c_stream2_udata_t *s2up;
149 
150     if ( !this){
151 	return;
152     }
153     s2up = stream2_get_or_make_udata(this);
154 
155     s2up->s2u_fp = fp;
156     s2up->s2u_state &= !(STREAM2_MY_FP);
157 }
158 /*******************************************************************************/
log4c_stream2_get_fp(log4c_appender_t * this)159 extern FILE* log4c_stream2_get_fp(log4c_appender_t* this){
160     log4c_stream2_udata_t *s2up;
161 
162     if ( !this){
163 	return NULL;
164     }
165     s2up = stream2_get_udata(this);
166     if ( s2up){
167 	return s2up->s2u_fp;
168     } else {
169 	return NULL;
170     }
171 }
172 /*******************************************************************************/
log4c_stream2_get_flags(log4c_appender_t * this)173 extern int log4c_stream2_get_flags(log4c_appender_t* this){
174     log4c_stream2_udata_t *s2up;
175 
176     if ( !this){
177 	return -1;
178     }
179     s2up = stream2_get_udata(this);
180     if ( s2up){
181 	return s2up->s2u_flags;
182     } else {
183 	return -1;
184     }
185 }
186 /*******************************************************************************/
log4c_stream2_set_flags(log4c_appender_t * this,int flags)187 extern void log4c_stream2_set_flags(log4c_appender_t* this, int flags){
188     log4c_stream2_udata_t *s2up;
189 
190     if ( !this){
191 	return;
192     }
193     s2up = stream2_get_or_make_udata(this);
194     if ( !s2up){
195 	return;
196     }
197     s2up->s2u_flags = flags;
198 }
199 
200 /*******************************************************************************/
201 const log4c_appender_type_t log4c_appender_type_stream2 = {
202     "stream2",
203     stream2_open,
204     stream2_append,
205     stream2_close,
206 };
207 
208