1/*********************************************************************
2 *   Copyright 2010, UCAR/Unidata
3 *   See netcdf/COPYRIGHT file for copying and redistribution conditions.
4 *   $Header$
5 *********************************************************************/
6
7#include "config.h"
8#include <stdlib.h>
9#ifdef HAVE_UNISTD_H
10#include <unistd.h>
11#endif
12#include <stdio.h>
13#include <string.h>
14#ifdef HAVE_STDARG_H
15#include <stdarg.h>
16#endif
17#ifdef HAVE_FCNTL_H
18#include <fcntl.h>
19#endif
20
21#include "oclog.h"
22
23#define PREFIXLEN 8
24#define MAXTAGS 256
25#define OCTAGDFALT "Log";
26
27static int oclogginginitialized = 0;
28static int oclogging = 0;
29static int ocsystemfile = 0; /* 1 => we are logging to file we did not open */
30static char* oclogfile = NULL;
31static FILEoclogstream = NULL;
32
33static int octagsize = 0;
34static char** octagset = NULL;
35static char* octagdfalt = NULL;
36static char* octagsetdfalt[] = {"Warning","Error","Note","Debug"};
37static char* octagname(int tag);
38
39/*!\defgroup OClog OClog Management
40@{*/
41
42/*!\internal
43*/
44
45void
46ocloginit(void)
47{
48    const char* file;
49    if(oclogginginitialized)
50 return;
51    oclogginginitialized = 1;
52    file = getenv(OCENVFLAG);
53    ocsetlogging(0);
54    oclogfile = NULL;
55    oclogstream = NULL;
56    /* Use environment variables to preset oclogging state*/
57    /* I hope this is portable*/
58    if(file != NULL && strlen(file) > 0) {
59        if(oclogopen(file)) {
60     ocsetlogging(1);
61 }
62    }
63    octagdfalt = OCTAGDFALT;
64    octagset = octagsetdfalt;
65}
66
67/*!
68Enable/Disable logging.
69
70\param[in] tf If 1, then turn on logging, if 0, then turn off logging.
71
72\return The previous value of the logging flag.
73*/
74
75int
76ocsetlogging(int tf)
77{
78    int was;
79    if(!oclogginginitializedocloginit();
80    was = oclogging;
81    oclogging = tf;
82    return was;
83}
84
85/*!
86Specify a file into which to place logging output.
87
88\param[in] file The name of the file into which to place logging output.
89If the file has the value NULL, then send logging output to
90stderr.
91
92\return zero if the open failed, one otherwise.
93*/
94
95int
96oclogopen(const char* file)
97{
98    if(!oclogginginitializedocloginit();
99    oclogclose();
100    if(file == NULL || strlen(file) == 0) {
101 /* use stderr*/
102 oclogstream = stderr;
103 oclogfile = NULL;
104 ocsystemfile = 1;
105    } else if(strcmp(file,"stdout") == 0) {
106 /* use stdout*/
107 oclogstream = stdout;
108 oclogfile = NULL;
109 ocsystemfile = 1;
110    } else if(strcmp(file,"stderr") == 0) {
111 /* use stderr*/
112 oclogstream = stderr;
113 oclogfile = NULL;
114 ocsystemfile = 1;
115    } else {
116 int fd;
117 oclogfile = strdup(file);
118 oclogstream = NULL;
119 /* We need to deal with this file carefully
120    to avoid unauthorized access*/
121 fd = open(oclogfile,O_WRONLY|O_APPEND|O_CREAT,0600);
122 if(fd >= 0) {
123     oclogstream = fdopen(fd,"a");
124 } else {
125     free(oclogfile);
126     oclogfile = NULL;
127     oclogstream = NULL;
128     ocsetlogging(0);
129     return 0;
130 }
131 ocsystemfile = 0;
132    }
133    return 1;
134}
135
136void
137oclogclose(void)
138{
139    if(!oclogginginitializedocloginit();
140    if(oclogstream != NULL && !ocsystemfile) {
141 fclose(oclogstream);
142    }
143    if(oclogfile != NULL) free(oclogfile);
144    oclogstream = NULL;
145    oclogfile = NULL;
146    ocsystemfile = 0;
147}
148
149/*!
150Send logging messages. This uses a variable
151number of arguments and operates like the stdio
152printf function.
153
154\param[in] tag Indicate the kind of this log message.
155\param[in] fmt Format specification as with printf.
156*/
157
158void
159oclog(int tag, const char* fmt, ...)
160{
161    va_list args;
162    char* prefix;
163
164    if(!oclogginginitializedocloginit();
165
166    if(!oclogging || oclogstream == NULL) return;
167
168    prefix = octagname(tag);
169    fprintf(oclogstream,"%s:",prefix);
170
171    if(fmt != NULL) {
172      va_start(argsfmt);
173      vfprintf(oclogstreamfmtargs);
174      va_end( args );
175    }
176    fprintf(oclogstream, "\n" );
177    fflush(oclogstream);
178}
179
180void
181oclogtext(int tag, const char* text)
182{
183    oclogtextn(tag,text,strlen(text));
184}
185
186/*!
187Send arbitrarily long text as a logging message.
188Each line will be sent using oclog with the specified tag.
189
190\param[in] tag Indicate the kind of this log message.
191\param[in] text Arbitrary text to send as a logging message.
192\param[in] count Maximum ength of the text to write.
193*/
194
195void
196oclogtextn(int tag, const char* text, size_t count)
197{
198    if(!oclogging || oclogstream == NULL) return;
199    fwrite(text,1,count,oclogstream);
200    fflush(oclogstream);
201}
202
203/* The tagset is null terminated */
204void
205oclogsettags(char** tagset, char* dfalt)
206{
207    octagdfalt = dfalt;
208    if(tagset == NULL) {
209 octagsize = 0;
210    } else {
211        int i;
212 /* Find end of the tagset */
213 for(i=0;i<MAXTAGS;i++) {if(tagset[i]==NULL) break;}
214 octagsize = i;
215    }
216    octagset = tagset;
217}
218
219static char*
220octagname(int tag)
221{
222    if(tag < 0 || tag >= octagsize) {
223 return octagdfalt;
224    } else {
225 return octagset[tag];
226    }
227}
228
229/**@}*/


HyperKWIC - Version 7.20DA executed at 11:37 on 27 Oct 2017 | Polyhedron Solutions - INTERNAL USE | COMMERCIAL (Any O/S) SN 4AKIed