NCBI C++ ToolKit
common.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 #include "common.h"
2 
3 #if HAVE_UNISTD_H
4 #include <unistd.h>
5 #endif
6 
7 #if HAVE_LIBGEN_H
8 #include <libgen.h>
9 #endif /* HAVE_LIBGEN_H */
10 
11 #if HAVE_SYS_PARAM_H
12 #include <sys/param.h>
13 #endif /* HAVE_SYS_PARAM_H */
14 
15 #include <freetds/time.h>
16 
17 #if HAVE_SYS_RESOURCE_H
18 #include <sys/resource.h>
19 #endif /* HAVE_SYS_RESOURCE_H */
20 
21 #include "replacements.h"
22 
23 #include <common/test_assert.h>
24 
25 #if !defined(PATH_MAX)
26 #define PATH_MAX 256
27 #endif
28 
29 char USER[512];
30 char SERVER[512];
31 char PASSWORD[512];
32 char DATABASE[512];
33 
34 static char sql_file[PATH_MAX];
35 static FILE* input_file = NULL;
36 
37 static char *ARGV0 = NULL;
38 static char *ARGV0B = NULL;
39 static char *DIRNAME = NULL;
40 static const char *BASENAME = NULL;
41 
42 #if HAVE_MALLOC_OPTIONS
43 extern const char *malloc_options;
44 #endif /* HAVE_MALLOC_OPTIONS */
45 
46 void
48 {
49 
50 #if HAVE_MALLOC_OPTIONS
51  /*
52  * Options for malloc
53  * A- all warnings are fatal
54  * J- init memory to 0xD0
55  * R- always move memory block on a realloc
56  */
57  malloc_options = "AJR";
58 #endif /* HAVE_MALLOC_OPTIONS */
59 }
60 
61 #if defined(__MINGW32__) || defined(_MSC_VER)
62 static char *
63 tds_dirname(char* path)
64 {
65  char *p, *p2;
66 
67  for (p = path + strlen(path); --p > path && (*p == '/' || *p == '\\');)
68  *p = '\0';
69 
70  p = strrchr(path, '/');
71  if (!p)
72  p = path;
73  p2 = strrchr(p, '\\');
74  if (p2)
75  p = p2;
76  if (p == path) {
77  if (*p == '/' || *p == '\\')
78  return "\\";
79  return ".";
80  }
81  *p = 0;
82  return path;
83 }
84 #define dirname tds_dirname
85 
86 #endif
87 
89 static void
90 free_file(void)
91 {
92  if (input_file) {
93  fclose(input_file);
94  input_file = NULL;
95  }
96  if (ARGV0) {
97  DIRNAME = NULL;
98  BASENAME = NULL;
99  free(ARGV0);
100  ARGV0 = NULL;
101  free(ARGV0B);
102  ARGV0B = NULL;
103  }
104 }
105 
106 int
107 read_login_info(int argc, char **argv)
108 {
109  int len;
110  FILE *in = NULL;
111 #if !defined(__MINGW32__) && !defined(_MSC_VER)
112  int ch;
113 #endif
114  char line[512];
115  char *s1, *s2;
116  char filename[PATH_MAX];
117  static const char *PWD = "../../../PWD";
118  struct { char *username, *password, *servername, *database; char fverbose; } options;
119 
120 #if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
121 #define MAX_STACK (8*1024*1024)
122 
123  struct rlimit rlim;
124 
125  if (!getrlimit(RLIMIT_STACK, &rlim) && (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > MAX_STACK)) {
126  rlim.rlim_cur = MAX_STACK;
127  setrlimit(RLIMIT_STACK, &rlim);
128  }
129 #endif
130 
131  setbuf(stdout, NULL);
132  setbuf(stderr, NULL);
133 
134  free(ARGV0);
135  free(ARGV0B);
136 #ifdef __VMS
137  {
138  /* basename expects unix format */
139  s1 = strrchr(argv[0], ';'); /* trim version; extension trimmed later */
140  if (s1) *s1 = 0;
141  const char *unixspec = decc$translate_vms(argv[0]);
142  ARGV0 = strdup(unixspec);
143  }
144 #else
145  ARGV0 = strdup(argv[0]);
146 #endif
147  ARGV0B = strdup(ARGV0);
148 
150 #if defined(_WIN32) || defined(__VMS)
151  s1 = strrchr(BASENAME, '.');
152  if (s1) *s1 = 0;
153 #endif
154  DIRNAME = dirname(ARGV0);
155 
156  memset(&options, 0, sizeof(options));
157 
158 #if !defined(__MINGW32__) && !defined(_MSC_VER)
159  /* process command line options (handy for manual testing) */
160  while ((ch = getopt(argc, (char**)argv, "U:P:S:D:f:v")) != -1) {
161  switch (ch) {
162  case 'U':
163  options.username = strdup(optarg);
164  break;
165  case 'P':
166  options.password = strdup(optarg);
167  break;
168  case 'S':
169  options.servername = strdup(optarg);
170  break;
171  case 'D':
172  options.database = strdup(optarg);
173  break;
174  case 'f': /* override default PWD file */
175  PWD = strdup(optarg);
176  break;
177  case 'v':
178  options.fverbose = 1; /* doesn't normally do anything */
179  break;
180  case '?':
181  default:
182  fprintf(stderr, "usage: %s \n"
183  " [-U username] [-P password]\n"
184  " [-S servername] [-D database]\n"
185  " [-i input filename] [-o output filename] "
186  "[-e error filename]\n"
187  , BASENAME);
188  exit(1);
189  }
190  }
191 #endif
192  strcpy(filename, PWD);
193 
194  s1 = getenv("TDSPWDFILE");
195  if (s1 && s1[0])
196  in = fopen(s1, "r");
197  if (!in)
198  in = fopen(filename, "r");
199  if (!in)
200  in = fopen("PWD", "r");
201  if (!in) {
202  sprintf(filename, "%s/%s", (DIRNAME) ? DIRNAME : ".", PWD);
203 
204  in = fopen(filename, "r");
205  if (!in) {
206  fprintf(stderr, "Can not open %s file\n\n", filename);
207  goto Override;
208  }
209  }
210 
211  while (fgets(line, 512, in)) {
212  s1 = strtok(line, "=");
213  s2 = strtok(NULL, "\n");
214  if (!s1 || !s2)
215  continue;
216  if (!strcmp(s1, "UID")) {
217  strcpy(USER, s2);
218  } else if (!strcmp(s1, "SRV")) {
219  strcpy(SERVER, s2);
220  } else if (!strcmp(s1, "PWD")) {
221  strcpy(PASSWORD, s2);
222  } else if (!strcmp(s1, "DB")) {
223  strcpy(DATABASE, s2);
224  }
225  }
226  fclose(in);
227 
228  Override:
229  /* apply command-line overrides */
230  if (options.username) {
231  strcpy(USER, options.username);
232  free(options.username);
233  }
234  if (options.password) {
235  strcpy(PASSWORD, options.password);
236  free(options.password);
237  }
238  if (options.servername) {
239  strcpy(SERVER, options.servername);
240  free(options.servername);
241  }
242  if (options.database) {
243  strcpy(DATABASE, options.database);
244  free(options.database);
245  }
246 
247  if (!*SERVER) {
248  fprintf(stderr, "no servername provided, quitting.\n");
249  exit(1);
250  }
251 
252  printf("found %s.%s for %s in \"%s\"\n", SERVER, DATABASE, USER, filename);
253 
254 #if 0
256 #endif
257  len = snprintf(sql_file, sizeof(sql_file), "%s/%s.sql", FREETDS_SRCDIR, BASENAME);
258  assert(len >= 0 && len <= sizeof(sql_file));
259 
260  if (input_file)
261  fclose(input_file);
262  if ((input_file = fopen(sql_file, "r")) == NULL) {
263  fflush(stdout);
264  fprintf(stderr, "could not open SQL input file \"%s\"\n", sql_file);
265  }
266 
268  atexit(free_file);
270 
271  printf("SQL text will be read from %s\n", sql_file);
272 
273  return 0;
274 }
275 
276 /*
277  * Fill the command buffer from a file while echoing it to standard output.
278  */
279 RETCODE
281 {
282  char line[2048], *p = line;
283  int i = 0;
284  RETCODE erc=SUCCEED;
285 
286  if (!input_file) {
287  fprintf(stderr, "%s: error: SQL input file \"%s\" not opened\n", BASENAME, sql_file);
288  exit(1);
289  }
290 
291  while ((p = fgets(line, (int)sizeof(line), input_file)) != NULL && strcasecmp("go\n", p) != 0) {
292  printf("\t%3d: %s", ++i, p);
293  if ((erc = dbcmd(dbproc, p)) != SUCCEED) {
294  fprintf(stderr, "%s: error: could write \"%s\" to dbcmd()\n", BASENAME, p);
295  exit(1);
296  }
297  }
298 
299  if (ferror(input_file)) {
300  fprintf(stderr, "%s: error: could not read SQL input file \"%s\"\n", BASENAME, sql_file);
301  exit(1);
302  }
303 
304  return erc;
305 }
306 
307 RETCODE
309 {
310  if (!input_file)
311  return FAIL;
312  rewind(input_file);
313  return SUCCEED;
314 }
315 
316 RETCODE
317 sql_reopen(const char *fn)
318 {
319  int len = snprintf(sql_file, sizeof(sql_file), "%s/%s.sql", FREETDS_SRCDIR, fn);
320  assert(len >= 0 && len <= sizeof(sql_file));
321 
322  if (input_file)
323  fclose(input_file);
324  if ((input_file = fopen(sql_file, "r")) == NULL) {
325  fflush(stdout);
326  fprintf(stderr, "could not open SQL input file \"%s\"\n", sql_file);
327  sql_file[0] = 0;
328  return FAIL;
329  }
330  return SUCCEED;
331 }
332 
333 int
334 syb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line)
335 {
336  int *pexpected_msgno;
337 
338  /*
339  * Check for "database changed", or "language changed" messages from
340  * the client. If we get one of these, then we need to pull the
341  * name of the database or charset from the message and set the
342  * appropriate variable.
343  */
344  if (msgno == 5701 || /* database context change */
345  msgno == 5703 || /* language changed */
346  msgno == 5704) { /* charset changed */
347 
348  /* fprintf( stderr, "msgno = %d: %s\n", msgno, msgtext ) ; */
349  return 0;
350  }
351 
352  /*
353  * If the user data indicates this is an expected error message (because we're testing the
354  * error propogation, say) then indicate this message was anticipated.
355  */
356  if (dbproc != NULL) {
357  pexpected_msgno = (int *) dbgetuserdata(dbproc);
358  if (pexpected_msgno && *pexpected_msgno == msgno) {
359  fprintf(stdout, "OK: anticipated message arrived: %d %s\n", (int) msgno, msgtext);
360  *pexpected_msgno = 0;
361  return 0;
362  }
363  }
364  /*
365  * If the severity is something other than 0 or the msg number is
366  * 0 (user informational messages).
367  */
368  fflush(stdout);
369  if (severity >= 0 || msgno == 0) {
370  /*
371  * If the message was something other than informational, and
372  * the severity was greater than 0, then print information to
373  * stderr with a little pre-amble information.
374  */
375  if (msgno > 0 && severity > 0) {
376  fprintf(stderr, "Msg %d, Level %d, State %d\n", (int) msgno, (int) severity, (int) msgstate);
377  fprintf(stderr, "Server '%s'", srvname);
378  if (procname != NULL && *procname != '\0')
379  fprintf(stderr, ", Procedure '%s'", procname);
380  if (line > 0)
381  fprintf(stderr, ", Line %d", line);
382  fprintf(stderr, "\n");
383  fprintf(stderr, "%s\n", msgtext);
384  fflush(stderr);
385  } else {
386  /*
387  * Otherwise, it is just an informational (e.g. print) message
388  * from the server, so send it to stdout.
389  */
390  fprintf(stdout, "%s\n", msgtext);
391  fflush(stdout);
392  severity = 0;
393  }
394  }
395 
396  if (severity) {
397  fprintf(stderr, "exit: no unanticipated messages allowed in unit tests\n");
399  }
400  return 0;
401 }
402 
403 int
404 syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
405 {
406  int *pexpected_dberr;
407 
408  /*
409  * For server messages, cancel the query and rely on the
410  * message handler to spew the appropriate error messages out.
411  */
412  if (dberr == SYBESMSG)
413  return INT_CANCEL;
414 
415  /*
416  * If the user data indicates this is an expected error message (because we're testing the
417  * error propogation, say) then indicate this message was anticipated.
418  */
419  if (dbproc != NULL) {
420  pexpected_dberr = (int *) dbgetuserdata(dbproc);
421  if (pexpected_dberr && *pexpected_dberr == dberr) {
422  fprintf(stdout, "OK: anticipated error %d (%s) arrived\n", dberr, dberrstr);
423  *pexpected_dberr = 0;
424  return INT_CANCEL;
425  }
426  }
427 
428  fflush(stdout);
429  fprintf(stderr,
430  "DB-LIBRARY error (dberr %d (severity %d): \"%s\"; oserr %d: \"%s\")\n",
431  dberr, severity, dberrstr ? dberrstr : "(null)", oserr, oserrstr ? oserrstr : "(null)");
432  fflush(stderr);
433 
434  /*
435  * If the dbprocess is dead or the dbproc is a NULL pointer and
436  * we are not in the middle of logging in, then we need to exit.
437  * We can't do anything from here on out anyway.
438  * It's OK to end up here in response to a dbconvert() that
439  * resulted in overflow, so don't exit in that case.
440  */
441  if ((dbproc == NULL) || DBDEAD(dbproc)) {
442  if (dberr != SYBECOFL) {
443  exit(255);
444  }
445  }
446 
447  if (severity) {
448  fprintf(stderr, "error: no unanticipated errors allowed in unit tests\n");
450  }
451 
452  return INT_CANCEL;
453 }
#define FREETDS_SRCDIR
Definition: common.h:43
#define EXIT_FAILURE
Definition: fastme.h:73
char PASSWORD[512]
Definition: common.c:31
char DATABASE[512]
Definition: common.c:32
char USER[512]
Definition: common.c:29
CS_RETCODE read_login_info(void)
Definition: common.c:71
static const char * PWD
Definition: common.c:39
char SERVER[512]
Definition: common.c:30
int syb_err_handler(DBPROCESS *dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
Definition: common.c:404
static const char * BASENAME
Definition: common.c:40
RETCODE sql_cmd(DBPROCESS *dbproc)
Definition: common.c:280
char free_file_registered
Definition: common.c:88
int syb_msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line)
Definition: common.c:334
static char * ARGV0
Definition: common.c:37
RETCODE sql_reopen(const char *fn)
Definition: common.c:317
static char * DIRNAME
Definition: common.c:39
void set_malloc_options(void)
Definition: common.c:47
static FILE * input_file
Definition: common.c:35
static char * ARGV0B
Definition: common.c:38
RETCODE sql_rewind(void)
Definition: common.c:308
#define PATH_MAX
Definition: common.c:26
static char sql_file[256]
Definition: common.c:34
static void free_file(void)
Definition: common.c:90
static DBPROCESS * dbproc
Definition: done_handling.c:29
#define getopt
Definition: replacements.h:157
#define basename(path)
Definition: replacements.h:116
int RETCODE
Definition: sybdb.h:121
#define SYBECOFL
Definition: sybdb.h:977
#define SUCCEED
Definition: sybdb.h:585
#define SYBESMSG
Definition: sybdb.h:946
#define FAIL
Definition: sybdb.h:586
Int4 DBINT
Definition: sybdb.h:255
#define INT_CANCEL
Definition: sybdb.h:62
#define optarg
#define NULL
Definition: ncbistd.hpp:225
#define DBDEAD(x)
Sybase macro mapping to the Microsoft (lower-case) function.
Definition: sybdb.h:762
RETCODE dbcmd(DBPROCESS *dbproc, const char cmdstring[])
Append SQL to the command buffer.
Definition: dblib.c:1377
void dbrecftos(const char filename[])
Record to a file all SQL commands sent to the server.
Definition: dblib.c:6689
BYTE * dbgetuserdata(DBPROCESS *dbproc)
Get address of user-allocated data from a DBPROCESS.
Definition: dblib.c:5867
use only n Cassandra database for the lookups</td > n</tr > n< tr > n< td > yes</td > n< td > do not use tables BIOSEQ_INFO and BLOB_PROP in the Cassandra database
exit(2)
int i
int len
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
#define strdup
Definition: ncbi_ansi_ext.h:70
#define strcasecmp
std::istream & in(std::istream &in_, double &x_)
#define assert(x)
Definition: srv_diag.hpp:58
void free(voidpf ptr)
Modified on Thu May 02 14:27:05 2024 by modify_doxy.py rev. 669887