4
* Description: This module contains miscellaneous routines
5
* such as for debugging/logging and string functions.
11
* Comments: See "notice.txt" for copyright and license information.
23
#include <sys/types.h>
26
#include <process.h> /* Byron: is this where Windows keeps def.
29
#include "connection.h"
30
#include "multibyte.h"
32
extern GLOBAL_VALUES globals;
33
void generate_filename(const char *, const char *, char *);
37
generate_filename(const char *dirname, const char *prefix, char *filename)
42
struct passwd *ptr = 0;
44
ptr = getpwuid(getuid());
47
if (dirname == 0 || filename == 0)
50
strcpy(filename, dirname);
51
strcat(filename, DIRSEPARATOR);
53
strcat(filename, prefix);
55
strcat(filename, ptr->pw_name);
57
sprintf(filename, "%s%u%s", filename, pid, ".log");
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,
79
logs_on_off(int cnopen, int mylog_onoff, int qlog_onoff)
81
static int mylog_on_count = 0,
89
mylog_on_count += cnopen;
91
mylog_off_count += cnopen;
92
if (mylog_on_count > 0)
94
else if (mylog_off_count > 0)
97
mylog_on = globals.debug;
99
qlog_on_count += cnopen;
101
qlog_off_count += cnopen;
102
if (qlog_on_count > 0)
104
else if (qlog_off_count > 0)
107
qlog_on = globals.commlog;
118
static FILE *LOGFP = NULL;
127
generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
128
LOGFP = fopen(filebuf, PG_BINARY_A);
132
#ifdef WIN_MULTITHREAD_SUPPORT
135
fprintf(LOGFP, "[%d]", GetCurrentThreadId());
137
#endif /* WIN_MULTITHREAD_SUPPORT */
138
#if defined(POSIX_MULTITHREAD_SUPPORT)
140
fprintf(LOGFP, "[%d]", pthread_self());
141
#endif /* POSIX_MULTITHREAD_SUPPORT */
143
vfprintf(LOGFP, fmt, args);
163
static FILE *LOGFP = NULL;
172
generate_filename(QLOGDIR, QLOGFILE, filebuf);
173
LOGFP = fopen(filebuf, PG_BINARY_A);
178
vfprintf(LOGFP, fmt, args);
188
* returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
189
* (not including null term)
192
my_strcpy(char *dst, int dst_len, const char *src, int src_len)
197
if (src_len == SQL_NULL_DATA)
202
else if (src_len == SQL_NTS)
203
src_len = strlen(src);
209
if (src_len < dst_len)
211
memcpy(dst, src, src_len);
216
memcpy(dst, src, dst_len - 1);
217
dst[dst_len - 1] = '\0'; /* truncated */
218
return STRCPY_TRUNCATED;
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.
233
strncpy_null(char *dst, const char *src, int len)
240
/* Just in case, check for special lengths */
241
if (len == SQL_NULL_DATA)
246
else if (len == SQL_NTS)
247
len = strlen(src) + 1;
249
for (i = 0; src[i] && i < len - 1; i++)
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
267
make_string(const char *s, int len, char *buf)
272
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
274
length = (len > 0) ? len : strlen(s);
278
strncpy_null(buf, s, length + 1);
282
str = malloc(length + 1);
286
strncpy_null(str, s, length + 1);
294
* Create a null terminated lower-case string if the
295
* original string contains upper-case characters.
296
* The SQL_NTS length is considered.
300
make_lstring_ifneeded(ConnectionClass *conn, const char *s, int len, BOOL ifallupper)
305
if (s && (len > 0 || (len == SQL_NTS && (length = strlen(s)) > 0)))
311
make_encoded_str(&encstr, conn, s);
312
for (i = 0, ptr = s; i < length; i++, ptr++)
314
encoded_nextchar(&encstr);
315
if (ENCODE_STATUS(encstr) != 0)
317
if (ifallupper && islower(*ptr))
326
if (tolower(*ptr) != *ptr)
330
str = malloc(length + 1);
331
memcpy(str, s, length);
334
str[i] = tolower(*ptr);
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.
350
my_strcat(char *buf, const char *fmt, const char *s, int len)
352
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
354
int length = (len > 0) ? len : strlen(s);
356
int pos = strlen(buf);
358
sprintf(&buf[pos], fmt, length, s);
365
schema_strcat(char *buf, const char *fmt, const char *s, int len, const char *tbname, int tbnmlen, ConnectionClass *conn)
370
* Note that this driver assumes the implicit schema is
371
* the CURRENT_SCHEMA() though it doesn't worth the
374
if (conn->schema_support && tbname && (tbnmlen > 0 || tbnmlen == SQL_NTS))
375
return my_strcat(buf, fmt, CC_get_current_schema(conn), SQL_NTS);
378
return my_strcat(buf, fmt, s, len);
383
remove_newlines(char *string)
387
for (i = 0; i < strlen(string); i++)
389
if ((string[i] == '\n') ||
401
for (i = strlen(s) - 1; i >= 0; i--)
413
my_strcat1(char *buf, const char *fmt, const char *s1, const char *s, int len)
417
if (s && (len > 0 || (len == SQL_NTS && (length = strlen(s)) > 0)))
419
int pos = strlen(buf);
422
sprintf(&buf[pos], fmt, s1, length, s);
424
sprintf(&buf[pos], fmt, length, s);
431
schema_strcat1(char *buf, const char *fmt, const char *s1, const char *s, int len, const char *tbname, int tbnmlen, ConnectionClass *conn)
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);
439
return my_strcat1(buf, fmt, s1, s, len);