~ubuntu-branches/ubuntu/lucid/psqlodbc/lucid

« back to all changes in this revision

Viewing changes to misc.c

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2004-05-13 10:47:36 UTC
  • Revision ID: james.westby@ubuntu.com-20040513104736-a530gmn0p3knep89
Tags: upstream-07.03.0200
ImportĀ upstreamĀ versionĀ 07.03.0200

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
#include <pwd.h>
 
23
#include <sys/types.h>
 
24
#include <unistd.h>
 
25
#else
 
26
#include <process.h>                    /* Byron: is this where Windows keeps def.
 
27
                                                                 * of getpid ? */
 
28
#endif
 
29
#include "connection.h"
 
30
#include "multibyte.h"
 
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
#if defined(WIN_MULTITHREAD_SUPPORT)
 
62
CRITICAL_SECTION        qlog_cs, mylog_cs;
 
63
#elif defined(POSIX_MULTITHREAD_SUPPORT)
 
64
pthread_mutex_t qlog_cs, mylog_cs;
 
65
#endif /* WIN_MULTITHREAD_SUPPORT */
 
66
static int      mylog_on = 0,
 
67
                        qlog_on = 0;
 
68
 
 
69
int     get_mylog(void)
 
70
{
 
71
        return mylog_on;
 
72
}
 
73
int     get_qlog(void)
 
74
{
 
75
        return qlog_on;
 
76
}
 
77
 
 
78
void
 
79
logs_on_off(int cnopen, int mylog_onoff, int qlog_onoff)
 
80
{
 
81
        static int      mylog_on_count = 0,
 
82
                                mylog_off_count = 0,
 
83
                                qlog_on_count = 0,
 
84
                                qlog_off_count = 0;
 
85
 
 
86
        ENTER_MYLOG_CS;
 
87
        ENTER_QLOG_CS;
 
88
        if (mylog_onoff)
 
89
                mylog_on_count += cnopen;
 
90
        else
 
91
                mylog_off_count += cnopen;
 
92
        if (mylog_on_count > 0)
 
93
                mylog_on = 1;
 
94
        else if (mylog_off_count > 0)
 
95
                mylog_on = 0;
 
96
        else
 
97
                mylog_on = globals.debug;
 
98
        if (qlog_onoff)
 
99
                qlog_on_count += cnopen;
 
100
        else
 
101
                qlog_off_count += cnopen;
 
102
        if (qlog_on_count > 0)
 
103
                qlog_on = 1;
 
104
        else if (qlog_off_count > 0)
 
105
                qlog_on = 0;
 
106
        else
 
107
                qlog_on = globals.commlog;
 
108
        LEAVE_QLOG_CS;
 
109
        LEAVE_MYLOG_CS;
 
110
}
 
111
 
 
112
#ifdef MY_LOG
 
113
void
 
114
mylog(char *fmt,...)
 
115
{
 
116
        va_list         args;
 
117
        char            filebuf[80];
 
118
        static FILE *LOGFP = NULL;
 
119
 
 
120
        ENTER_MYLOG_CS;
 
121
        if (mylog_on)
 
122
        {
 
123
                va_start(args, fmt);
 
124
 
 
125
                if (!LOGFP)
 
126
                {
 
127
                        generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
 
128
                        LOGFP = fopen(filebuf, PG_BINARY_A);
 
129
                        setbuf(LOGFP, NULL);
 
130
                }
 
131
 
 
132
#ifdef  WIN_MULTITHREAD_SUPPORT
 
133
#ifdef  WIN32
 
134
                if (LOGFP)
 
135
                        fprintf(LOGFP, "[%d]", GetCurrentThreadId());
 
136
#endif /* WIN32 */
 
137
#endif /* WIN_MULTITHREAD_SUPPORT */
 
138
#if defined(POSIX_MULTITHREAD_SUPPORT)
 
139
        if (LOGFP)
 
140
            fprintf(LOGFP, "[%d]", pthread_self());
 
141
#endif /* POSIX_MULTITHREAD_SUPPORT */
 
142
                if (LOGFP)
 
143
                        vfprintf(LOGFP, fmt, args);
 
144
 
 
145
                va_end(args);
 
146
        }
 
147
        LEAVE_MYLOG_CS;
 
148
}
 
149
#else
 
150
void
 
151
MyLog(char *fmt,...)
 
152
{
 
153
}
 
154
#endif
 
155
 
 
156
 
 
157
#ifdef Q_LOG
 
158
void
 
159
qlog(char *fmt,...)
 
160
{
 
161
        va_list         args;
 
162
        char            filebuf[80];
 
163
        static FILE *LOGFP = NULL;
 
164
 
 
165
        ENTER_QLOG_CS;
 
166
        if (qlog_on)
 
167
        {
 
168
                va_start(args, fmt);
 
169
 
 
170
                if (!LOGFP)
 
171
                {
 
172
                        generate_filename(QLOGDIR, QLOGFILE, filebuf);
 
173
                        LOGFP = fopen(filebuf, PG_BINARY_A);
 
174
                        setbuf(LOGFP, NULL);
 
175
                }
 
176
 
 
177
                if (LOGFP)
 
178
                        vfprintf(LOGFP, fmt, args);
 
179
 
 
180
                va_end(args);
 
181
        }
 
182
        LEAVE_QLOG_CS;
 
183
}
 
184
#endif
 
185
 
 
186
 
 
187
/*
 
188
 *      returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
 
189
 *      (not including null term)
 
190
 */
 
191
int
 
192
my_strcpy(char *dst, int dst_len, const char *src, int src_len)
 
193
{
 
194
        if (dst_len <= 0)
 
195
                return STRCPY_FAIL;
 
196
 
 
197
        if (src_len == SQL_NULL_DATA)
 
198
        {
 
199
                dst[0] = '\0';
 
200
                return STRCPY_NULL;
 
201
        }
 
202
        else if (src_len == SQL_NTS)
 
203
                src_len = strlen(src);
 
204
 
 
205
        if (src_len <= 0)
 
206
                return STRCPY_FAIL;
 
207
        else
 
208
        {
 
209
                if (src_len < dst_len)
 
210
                {
 
211
                        memcpy(dst, src, src_len);
 
212
                        dst[src_len] = '\0';
 
213
                }
 
214
                else
 
215
                {
 
216
                        memcpy(dst, src, dst_len - 1);
 
217
                        dst[dst_len - 1] = '\0';        /* truncated */
 
218
                        return STRCPY_TRUNCATED;
 
219
                }
 
220
        }
 
221
 
 
222
        return strlen(dst);
 
223
}
 
224
 
 
225
 
 
226
/*
 
227
 * strncpy copies up to len characters, and doesn't terminate
 
228
 * the destination string if src has len characters or more.
 
229
 * instead, I want it to copy up to len-1 characters and always
 
230
 * terminate the destination string.
 
231
 */
 
232
char *
 
233
strncpy_null(char *dst, const char *src, int len)
 
234
{
 
235
        int                     i;
 
236
 
 
237
 
 
238
        if (NULL != dst)
 
239
        {
 
240
                /* Just in case, check for special lengths */
 
241
                if (len == SQL_NULL_DATA)
 
242
                {
 
243
                        dst[0] = '\0';
 
244
                        return NULL;
 
245
                }
 
246
                else if (len == SQL_NTS)
 
247
                        len = strlen(src) + 1;
 
248
 
 
249
                for (i = 0; src[i] && i < len - 1; i++)
 
250
                        dst[i] = src[i];
 
251
 
 
252
                if (len > 0)
 
253
                        dst[i] = '\0';
 
254
        }
 
255
        return dst;
 
256
}
 
257
 
 
258
 
 
259
/*------
 
260
 *      Create a null terminated string (handling the SQL_NTS thing):
 
261
 *              1. If buf is supplied, place the string in there
 
262
 *                 (assumes enough space) and return buf.
 
263
 *              2. If buf is not supplied, malloc space and return this string
 
264
 *------
 
265
 */
 
266
char *
 
267
make_string(const char *s, int len, char *buf)
 
268
{
 
269
        int                     length;
 
270
        char       *str;
 
271
 
 
272
        if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
 
273
        {
 
274
                length = (len > 0) ? len : strlen(s);
 
275
 
 
276
                if (buf)
 
277
                {
 
278
                        strncpy_null(buf, s, length + 1);
 
279
                        return buf;
 
280
                }
 
281
 
 
282
                str = malloc(length + 1);
 
283
                if (!str)
 
284
                        return NULL;
 
285
 
 
286
                strncpy_null(str, s, length + 1);
 
287
                return str;
 
288
        }
 
289
 
 
290
        return NULL;
 
291
}
 
292
 
 
293
/*------
 
294
 *      Create a null terminated lower-case string if the
 
295
 *      original string contains upper-case characters.
 
296
 *      The SQL_NTS length is considered.
 
297
 *------
 
298
 */
 
299
char *
 
300
make_lstring_ifneeded(ConnectionClass *conn, const char *s, int len, BOOL ifallupper)
 
301
{
 
302
        int     length = len;
 
303
        char       *str = NULL;
 
304
 
 
305
        if (s && (len > 0 || (len == SQL_NTS && (length = strlen(s)) > 0)))
 
306
        {
 
307
                int     i;
 
308
                const char *ptr;
 
309
                encoded_str encstr;
 
310
 
 
311
                make_encoded_str(&encstr, conn, s);
 
312
                for (i = 0, ptr = s; i < length; i++, ptr++)
 
313
                {
 
314
                        encoded_nextchar(&encstr);
 
315
                        if (ENCODE_STATUS(encstr) != 0)
 
316
                                continue;
 
317
                        if (ifallupper && islower(*ptr))
 
318
                        {
 
319
                                if (str)
 
320
                                {
 
321
                                        free(str);
 
322
                                        str = NULL;
 
323
                                }
 
324
                                break;
 
325
                        } 
 
326
                        if (tolower(*ptr) != *ptr)
 
327
                        {
 
328
                                if (!str)
 
329
                                {
 
330
                                        str = malloc(length + 1);
 
331
                                        memcpy(str, s, length);
 
332
                                        str[length] = '\0';
 
333
                                }
 
334
                                str[i] = tolower(*ptr);
 
335
                        }
 
336
                }
 
337
        }
 
338
 
 
339
        return str;
 
340
}
 
341
 
 
342
 
 
343
/*
 
344
 *      Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing.
 
345
 *      "fmt" must contain somewhere in it the single form '%.*s'.
 
346
 *      This is heavily used in creating queries for info routines (SQLTables, SQLColumns).
 
347
 *      This routine could be modified to use vsprintf() to handle multiple arguments.
 
348
 */
 
349
char *
 
350
my_strcat(char *buf, const char *fmt, const char *s, int len)
 
351
{
 
352
        if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
 
353
        {
 
354
                int                     length = (len > 0) ? len : strlen(s);
 
355
 
 
356
                int                     pos = strlen(buf);
 
357
 
 
358
                sprintf(&buf[pos], fmt, length, s);
 
359
                return buf;
 
360
        }
 
361
        return NULL;
 
362
}
 
363
 
 
364
char *
 
365
schema_strcat(char *buf, const char *fmt, const char *s, int len, const char *tbname, int tbnmlen, ConnectionClass *conn)
 
366
{
 
367
        if (!s || 0 == len)
 
368
        {
 
369
                /*
 
370
                 * Note that this driver assumes the implicit schema is
 
371
                 * the CURRENT_SCHEMA() though it doesn't worth the
 
372
                 * naming.
 
373
                 */
 
374
                if (conn->schema_support && tbname && (tbnmlen > 0 || tbnmlen == SQL_NTS))
 
375
                        return my_strcat(buf, fmt, CC_get_current_schema(conn), SQL_NTS);
 
376
                return NULL;
 
377
        }
 
378
        return my_strcat(buf, fmt, s, len);
 
379
}
 
380
 
 
381
 
 
382
void
 
383
remove_newlines(char *string)
 
384
{
 
385
        unsigned int i;
 
386
 
 
387
        for (i = 0; i < strlen(string); i++)
 
388
        {
 
389
                if ((string[i] == '\n') ||
 
390
                        (string[i] == '\r'))
 
391
                        string[i] = ' ';
 
392
        }
 
393
}
 
394
 
 
395
 
 
396
char *
 
397
trim(char *s)
 
398
{
 
399
        int                     i;
 
400
 
 
401
        for (i = strlen(s) - 1; i >= 0; i--)
 
402
        {
 
403
                if (s[i] == ' ')
 
404
                        s[i] = '\0';
 
405
                else
 
406
                        break;
 
407
        }
 
408
 
 
409
        return s;
 
410
}
 
411
 
 
412
char *
 
413
my_strcat1(char *buf, const char *fmt, const char *s1, const char *s, int len)
 
414
{
 
415
        int     length = len;
 
416
 
 
417
        if (s && (len > 0 || (len == SQL_NTS && (length = strlen(s)) > 0)))
 
418
        {
 
419
                int     pos = strlen(buf);
 
420
 
 
421
                if (s1)
 
422
                        sprintf(&buf[pos], fmt, s1, length, s);
 
423
                else
 
424
                        sprintf(&buf[pos], fmt, length, s);
 
425
                return buf;
 
426
        }
 
427
        return NULL;
 
428
}
 
429
 
 
430
char *
 
431
schema_strcat1(char *buf, const char *fmt, const char *s1, const char *s, int len, const char *tbname, int tbnmlen, ConnectionClass *conn)
 
432
{
 
433
        if (!s || 0 == len)
 
434
        {
 
435
                if (conn->schema_support && tbname && (tbnmlen > 0 || tbnmlen == SQL_NTS))
 
436
                        return my_strcat1(buf, fmt, s1, CC_get_current_schema(conn), SQL_NTS);
 
437
                return NULL;
 
438
        }
 
439
        return my_strcat1(buf, fmt, s1, s, len);
 
440
}