]> granicus.if.org Git - postgresql/blob - src/interfaces/odbc/misc.c
87a4ee01ff501d2dd989dfc748ca85365dc1733d
[postgresql] / src / interfaces / odbc / misc.c
1 /*-------
2  * Module:                      misc.c
3  *
4  * Description:         This module contains miscellaneous routines
5  *                                      such as for debugging/logging and string functions.
6  *
7  * Classes:                     n/a
8  *
9  * API functions:       none
10  *
11  * Comments:            See "notice.txt" for copyright and license information.
12  *-------
13  */
14
15 #include "psqlodbc.h"
16
17 #include <stdio.h>
18 #include <stdarg.h>
19 #include <string.h>
20
21 #ifndef WIN32
22 #if HAVE_PWD_H
23 #include <pwd.h>
24 #endif
25 #include <sys/types.h>
26 #include <unistd.h>
27 #else
28 #include <process.h>                    /* Byron: is this where Windows keeps def.
29                                                                  * of getpid ? */
30 #endif
31
32 extern GLOBAL_VALUES globals;
33 void    generate_filename(const char *, const char *, char *);
34
35
36 void
37 generate_filename(const char *dirname, const char *prefix, char *filename)
38 {
39         int                     pid = 0;
40
41 #ifndef WIN32
42         struct passwd *ptr = 0;
43
44         ptr = getpwuid(getuid());
45 #endif
46         pid = getpid();
47         if (dirname == 0 || filename == 0)
48                 return;
49
50         strcpy(filename, dirname);
51         strcat(filename, DIRSEPARATOR);
52         if (prefix != 0)
53                 strcat(filename, prefix);
54 #ifndef WIN32
55         strcat(filename, ptr->pw_name);
56 #endif
57         sprintf(filename, "%s%u%s", filename, pid, ".log");
58         return;
59 }
60
61 static  int     mylog_on = 0, qlog_on = 0;
62 void logs_on_off(int cnopen, int mylog_onoff, int qlog_onoff)
63 {
64         static  int     mylog_on_count = 0, mylog_off_count = 0,
65                         qlog_on_count = 0, qlog_off_count = 0;
66
67         if (mylog_onoff)
68                 mylog_on_count += cnopen;
69         else 
70                 mylog_off_count += cnopen;
71         if (mylog_on_count > 0)
72                 mylog_on = 1;
73         else if (mylog_off_count > 0)
74                 mylog_on = 0;
75         else
76                 mylog_on = globals.debug;
77         if (qlog_onoff)
78                 qlog_on_count += cnopen;
79         else 
80                 qlog_off_count += cnopen;
81         if (qlog_on_count > 0)
82                 qlog_on = 1;
83         else if (qlog_off_count > 0)
84                 qlog_on = 0;
85         else
86                 qlog_on = globals.commlog;
87 }
88
89 #ifdef MY_LOG
90 void
91 mylog(char *fmt,...)
92 {
93         va_list         args;
94         char            filebuf[80];
95         static FILE     *LOGFP = NULL;
96
97         if (mylog_on)
98         {
99                 va_start(args, fmt);
100
101                 if (!LOGFP)
102                 {
103                         generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
104                         LOGFP = fopen(filebuf, PG_BINARY_W);
105                         setbuf(LOGFP, NULL);
106                 }
107
108                 if (LOGFP)
109                         vfprintf(LOGFP, fmt, args);
110
111                 va_end(args);
112         }
113 }
114
115 #endif
116
117
118 #ifdef Q_LOG
119 void
120 qlog(char *fmt,...)
121 {
122         va_list         args;
123         char            filebuf[80];
124         static FILE   *LOGFP = NULL;
125
126         if (qlog_on)
127         {
128                 va_start(args, fmt);
129
130                 if (!LOGFP)
131                 {
132                         generate_filename(QLOGDIR, QLOGFILE, filebuf);
133                         LOGFP = fopen(filebuf, PG_BINARY_W);
134                         setbuf(LOGFP, NULL);
135                 }
136
137                 if (LOGFP)
138                         vfprintf(LOGFP, fmt, args);
139
140                 va_end(args);
141         }
142 }
143
144 #endif
145
146 /*      Undefine these because windows.h will redefine and cause a warning */
147
148 #ifdef WIN32
149 #undef va_start
150 #undef va_end
151 #endif
152
153 #ifndef WIN32
154 #include "iodbc.h"
155 #include "isql.h"
156 #else
157 #include <windows.h>
158 #include <sql.h>
159 #endif
160
161
162 /*
163  *      returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
164  *      (not including null term)
165  */
166 int
167 my_strcpy(char *dst, int dst_len, const char *src, int src_len)
168 {
169         if (dst_len <= 0)
170                 return STRCPY_FAIL;
171
172         if (src_len == SQL_NULL_DATA)
173         {
174                 dst[0] = '\0';
175                 return STRCPY_NULL;
176         }
177         else if (src_len == SQL_NTS)
178                 src_len = strlen(src);
179
180         if (src_len <= 0)
181                 return STRCPY_FAIL;
182         else
183         {
184                 if (src_len < dst_len)
185                 {
186                         memcpy(dst, src, src_len);
187                         dst[src_len] = '\0';
188                 }
189                 else
190                 {
191                         memcpy(dst, src, dst_len - 1);
192                         dst[dst_len - 1] = '\0';        /* truncated */
193                         return STRCPY_TRUNCATED;
194                 }
195         }
196
197         return strlen(dst);
198 }
199
200
201 /*
202  * strncpy copies up to len characters, and doesn't terminate
203  * the destination string if src has len characters or more.
204  * instead, I want it to copy up to len-1 characters and always
205  * terminate the destination string.
206  */
207 char *
208 strncpy_null(char *dst, const char *src, int len)
209 {
210         int                     i;
211
212
213         if (NULL != dst)
214         {
215                 /* Just in case, check for special lengths */
216                 if (len == SQL_NULL_DATA)
217                 {
218                         dst[0] = '\0';
219                         return NULL;
220                 }
221                 else if (len == SQL_NTS)
222                         len = strlen(src) + 1;
223
224                 for (i = 0; src[i] && i < len - 1; i++)
225                         dst[i] = src[i];
226
227                 if (len > 0)
228                         dst[i] = '\0';
229         }
230         return dst;
231 }
232
233
234 /*------
235  *      Create a null terminated string (handling the SQL_NTS thing):
236  *              1. If buf is supplied, place the string in there
237  *                 (assumes enough space) and return buf.
238  *              2. If buf is not supplied, malloc space and return this string
239  *------
240  */
241 char *
242 make_string(const char *s, int len, char *buf)
243 {
244         int                     length;
245         char       *str;
246
247         if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
248         {
249                 length = (len > 0) ? len : strlen(s);
250
251                 if (buf)
252                 {
253                         strncpy_null(buf, s, length + 1);
254                         return buf;
255                 }
256
257                 str = malloc(length + 1);
258                 if (!str)
259                         return NULL;
260
261                 strncpy_null(str, s, length + 1);
262                 return str;
263         }
264
265         return NULL;
266 }
267
268
269 /*
270  *      Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing.
271  *      "fmt" must contain somewhere in it the single form '%.*s'.
272  *      This is heavily used in creating queries for info routines (SQLTables, SQLColumns).
273  *      This routine could be modified to use vsprintf() to handle multiple arguments.
274  */
275 char *
276 my_strcat(char *buf, const char *fmt, const char *s, int len)
277 {
278         if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
279         {
280                 int                     length = (len > 0) ? len : strlen(s);
281
282                 int                     pos = strlen(buf);
283
284                 sprintf(&buf[pos], fmt, length, s);
285                 return buf;
286         }
287         return NULL;
288 }
289
290
291 void
292 remove_newlines(char *string)
293 {
294         unsigned int i;
295
296         for (i = 0; i < strlen(string); i++)
297         {
298                 if ((string[i] == '\n') ||
299                         (string[i] == '\r'))
300                         string[i] = ' ';
301         }
302 }
303
304
305 char *
306 trim(char *s)
307 {
308         int                     i;
309
310         for (i = strlen(s) - 1; i >= 0; i--)
311         {
312                 if (s[i] == ' ')
313                         s[i] = '\0';
314                 else
315                         break;
316         }
317
318         return s;
319 }