mirror of
https://github.com/postgres/postgres.git
synced 2025-05-14 00:03:46 -04:00
295 lines
4.8 KiB
C
295 lines
4.8 KiB
C
/*-------
|
|
* Module: misc.c
|
|
*
|
|
* Description: This module contains miscellaneous routines
|
|
* such as for debugging/logging and string functions.
|
|
*
|
|
* Classes: n/a
|
|
*
|
|
* API functions: none
|
|
*
|
|
* Comments: See "notice.txt" for copyright and license information.
|
|
*-------
|
|
*/
|
|
|
|
#include "psqlodbc.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdarg.h>
|
|
#include <string.h>
|
|
|
|
#ifndef WIN32
|
|
#if HAVE_PWD_H
|
|
#include <pwd.h>
|
|
#endif
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#else
|
|
#include <process.h> /* Byron: is this where Windows keeps def.
|
|
* of getpid ? */
|
|
#endif
|
|
|
|
extern GLOBAL_VALUES globals;
|
|
void generate_filename(char *, char *, char *);
|
|
|
|
|
|
void
|
|
generate_filename(char *dirname, char *prefix, char *filename)
|
|
{
|
|
int pid = 0;
|
|
|
|
#ifndef WIN32
|
|
struct passwd *ptr = 0;
|
|
|
|
ptr = getpwuid(getuid());
|
|
#endif
|
|
pid = getpid();
|
|
if (dirname == 0 || filename == 0)
|
|
return;
|
|
|
|
strcpy(filename, dirname);
|
|
strcat(filename, DIRSEPARATOR);
|
|
if (prefix != 0)
|
|
strcat(filename, prefix);
|
|
#ifndef WIN32
|
|
strcat(filename, ptr->pw_name);
|
|
#endif
|
|
sprintf(filename, "%s%u%s", filename, pid, ".log");
|
|
return;
|
|
}
|
|
|
|
|
|
#ifdef MY_LOG
|
|
void
|
|
mylog(char *fmt,...)
|
|
{
|
|
va_list args;
|
|
char filebuf[80];
|
|
FILE *LOGFP = globals.mylogFP;
|
|
|
|
if (globals.debug)
|
|
{
|
|
va_start(args, fmt);
|
|
|
|
if (!LOGFP)
|
|
{
|
|
generate_filename(MYLOGDIR, MYLOGFILE, filebuf);
|
|
LOGFP = fopen(filebuf, PG_BINARY_W);
|
|
globals.mylogFP = LOGFP;
|
|
setbuf(LOGFP, NULL);
|
|
}
|
|
|
|
if (LOGFP)
|
|
vfprintf(LOGFP, fmt, args);
|
|
|
|
va_end(args);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
#ifdef Q_LOG
|
|
void
|
|
qlog(char *fmt,...)
|
|
{
|
|
va_list args;
|
|
char filebuf[80];
|
|
FILE *LOGFP = globals.qlogFP;
|
|
|
|
if (globals.commlog)
|
|
{
|
|
va_start(args, fmt);
|
|
|
|
if (!LOGFP)
|
|
{
|
|
generate_filename(QLOGDIR, QLOGFILE, filebuf);
|
|
LOGFP = fopen(filebuf, PG_BINARY_W);
|
|
globals.qlogFP = LOGFP;
|
|
setbuf(LOGFP, NULL);
|
|
}
|
|
|
|
if (LOGFP)
|
|
vfprintf(LOGFP, fmt, args);
|
|
|
|
va_end(args);
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
/* Undefine these because windows.h will redefine and cause a warning */
|
|
|
|
#ifdef WIN32
|
|
#undef va_start
|
|
#undef va_end
|
|
#endif
|
|
|
|
#ifndef WIN32
|
|
#include "iodbc.h"
|
|
#include "isql.h"
|
|
#else
|
|
#include <windows.h>
|
|
#include <sql.h>
|
|
#endif
|
|
|
|
|
|
/*
|
|
* returns STRCPY_FAIL, STRCPY_TRUNCATED, or #bytes copied
|
|
* (not including null term)
|
|
*/
|
|
int
|
|
my_strcpy(char *dst, int dst_len, char *src, int src_len)
|
|
{
|
|
if (dst_len <= 0)
|
|
return STRCPY_FAIL;
|
|
|
|
if (src_len == SQL_NULL_DATA)
|
|
{
|
|
dst[0] = '\0';
|
|
return STRCPY_NULL;
|
|
}
|
|
else if (src_len == SQL_NTS)
|
|
src_len = strlen(src);
|
|
|
|
if (src_len <= 0)
|
|
return STRCPY_FAIL;
|
|
else
|
|
{
|
|
if (src_len < dst_len)
|
|
{
|
|
memcpy(dst, src, src_len);
|
|
dst[src_len] = '\0';
|
|
}
|
|
else
|
|
{
|
|
memcpy(dst, src, dst_len - 1);
|
|
dst[dst_len - 1] = '\0'; /* truncated */
|
|
return STRCPY_TRUNCATED;
|
|
}
|
|
}
|
|
|
|
return strlen(dst);
|
|
}
|
|
|
|
|
|
/*
|
|
* strncpy copies up to len characters, and doesn't terminate
|
|
* the destination string if src has len characters or more.
|
|
* instead, I want it to copy up to len-1 characters and always
|
|
* terminate the destination string.
|
|
*/
|
|
char *
|
|
strncpy_null(char *dst, const char *src, int len)
|
|
{
|
|
int i;
|
|
|
|
|
|
if (NULL != dst)
|
|
{
|
|
/* Just in case, check for special lengths */
|
|
if (len == SQL_NULL_DATA)
|
|
{
|
|
dst[0] = '\0';
|
|
return NULL;
|
|
}
|
|
else if (len == SQL_NTS)
|
|
len = strlen(src) + 1;
|
|
|
|
for (i = 0; src[i] && i < len - 1; i++)
|
|
dst[i] = src[i];
|
|
|
|
if (len > 0)
|
|
dst[i] = '\0';
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
|
|
/*------
|
|
* Create a null terminated string (handling the SQL_NTS thing):
|
|
* 1. If buf is supplied, place the string in there
|
|
* (assumes enough space) and return buf.
|
|
* 2. If buf is not supplied, malloc space and return this string
|
|
*------
|
|
*/
|
|
char *
|
|
make_string(char *s, int len, char *buf)
|
|
{
|
|
int length;
|
|
char *str;
|
|
|
|
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
|
|
{
|
|
length = (len > 0) ? len : strlen(s);
|
|
|
|
if (buf)
|
|
{
|
|
strncpy_null(buf, s, length + 1);
|
|
return buf;
|
|
}
|
|
|
|
str = malloc(length + 1);
|
|
if (!str)
|
|
return NULL;
|
|
|
|
strncpy_null(str, s, length + 1);
|
|
return str;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
/*
|
|
* Concatenate a single formatted argument to a given buffer handling the SQL_NTS thing.
|
|
* "fmt" must contain somewhere in it the single form '%.*s'.
|
|
* This is heavily used in creating queries for info routines (SQLTables, SQLColumns).
|
|
* This routine could be modified to use vsprintf() to handle multiple arguments.
|
|
*/
|
|
char *
|
|
my_strcat(char *buf, char *fmt, char *s, int len)
|
|
{
|
|
if (s && (len > 0 || (len == SQL_NTS && strlen(s) > 0)))
|
|
{
|
|
int length = (len > 0) ? len : strlen(s);
|
|
|
|
int pos = strlen(buf);
|
|
|
|
sprintf(&buf[pos], fmt, length, s);
|
|
return buf;
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
void
|
|
remove_newlines(char *string)
|
|
{
|
|
unsigned int i;
|
|
|
|
for (i = 0; i < strlen(string); i++)
|
|
{
|
|
if ((string[i] == '\n') ||
|
|
(string[i] == '\r'))
|
|
string[i] = ' ';
|
|
}
|
|
}
|
|
|
|
|
|
char *
|
|
trim(char *s)
|
|
{
|
|
int i;
|
|
|
|
for (i = strlen(s) - 1; i >= 0; i--)
|
|
{
|
|
if (s[i] == ' ')
|
|
s[i] = '\0';
|
|
else
|
|
break;
|
|
}
|
|
|
|
return s;
|
|
}
|