1 : #if HAVE_CONFIG_H
2 : #include <config.h>
3 : #endif /* HAVE_CONFIG_H */
4 :
5 : #include <stdio.h>
6 :
7 : #if HAVE_STDLIB_H
8 : #include <stdlib.h>
9 : #endif /* HAVE_STDLIB_H */
10 :
11 : #if HAVE_UNISTD_H
12 : #include <unistd.h>
13 : #endif
14 :
15 : #if HAVE_STRING_H
16 : #include <string.h>
17 : #endif /* HAVE_STRING_H */
18 :
19 : #if HAVE_LIBGEN_H
20 : #include <libgen.h>
21 : #endif /* HAVE_LIBGEN_H */
22 :
23 : #if HAVE_SYS_PARAM_H
24 : #include <sys/param.h>
25 : #endif /* HAVE_SYS_PARAM_H */
26 :
27 : #include <sqlfront.h>
28 : #include <sqldb.h>
29 :
30 : #include "replacements.h"
31 : #include "common.h"
32 :
33 : static char software_version[] = "$Id: common.c,v 1.15 2005/07/04 09:16:39 freddy77 Exp $";
34 : static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
35 :
36 : typedef struct _tag_memcheck_t
37 : {
38 : int item_number;
39 : int special;
40 : struct _tag_memcheck_t *next;
41 : }
42 : memcheck_t;
43 :
44 :
45 : static memcheck_t *breadcrumbs = NULL;
46 : static int num_breadcrumbs = 0;
47 : static const int BREADCRUMB = 0xABCD7890;
48 :
49 : char USER[512];
50 : char SERVER[512];
51 : char PASSWORD[512];
52 : char DATABASE[512];
53 : static char *DIRNAME = NULL;
54 : static char *BASENAME = NULL;
55 :
56 : #if HAVE_MALLOC_OPTIONS
57 : extern const char *malloc_options;
58 : #endif /* HAVE_MALLOC_OPTIONS */
59 :
60 : void
61 : set_malloc_options(void)
62 48 : {
63 :
64 : #if HAVE_MALLOC_OPTIONS
65 : /*
66 : * Options for malloc
67 : * A- all warnings are fatal
68 : * J- init memory to 0xD0
69 : * R- always move memory block on a realloc
70 : */
71 : malloc_options = "AJR";
72 : #endif /* HAVE_MALLOC_OPTIONS */
73 48 : }
74 :
75 : int
76 : read_login_info(int argc, char **argv)
77 53 : {
78 : extern char *optarg;
79 : extern int optind;
80 :
81 : FILE *in;
82 : int ch;
83 : char line[512];
84 : char *s1, *s2;
85 : char filename[MAXPATHLEN];
86 : static const char *PWD = "../../../PWD";
87 : struct { char *username, *password, *servername, *database; char fverbose; } options;
88 :
89 53 : DIRNAME = dirname((char *)argv[0]);
90 53 : BASENAME = tds_basename((char *)argv[0]);
91 :
92 53 : memset(&options, 0, sizeof(options));
93 :
94 : /* process command line options (handy for manual testing) */
95 53 : while ((ch = getopt(argc, (char**)argv, "U:P:S:D:f:v")) != -1) {
96 0 : switch (ch) {
97 : case 'U':
98 0 : options.username = strdup(optarg);
99 0 : break;
100 : case 'P':
101 0 : options.password = strdup(optarg);
102 0 : break;
103 : case 'S':
104 0 : options.servername = strdup(optarg);
105 0 : break;
106 : case 'D':
107 0 : options.database = strdup(optarg);
108 0 : break;
109 : case 'f': /* override default PWD file */
110 0 : PWD = strdup(optarg);
111 0 : break;
112 : case 'v':
113 0 : options.fverbose = 1; /* doesn't normally do anything */
114 0 : break;
115 : case '?':
116 : default:
117 0 : fprintf(stderr, "usage: %s \n"
118 : " [-U username] [-P password]\n"
119 : " [-S servername] [-D database]\n"
120 : " [-i input filename] [-o output filename] [-e error filename]\n"
121 : , BASENAME);
122 0 : exit(1);
123 : }
124 : }
125 :
126 :
127 53 : strcpy(filename, PWD);
128 53 : in = fopen(filename, "r");
129 53 : if (!in) {
130 0 : sprintf(filename, "%s/%s", (DIRNAME) ? DIRNAME : ".", PWD);
131 :
132 0 : in = fopen(filename, "r");
133 0 : if (!in) {
134 0 : fprintf(stderr, "Can not open %s file\n\n", filename);
135 0 : return 1;
136 : }
137 : }
138 :
139 1272 : while (fgets(line, 512, in)) {
140 1166 : s1 = strtok(line, "=");
141 1166 : s2 = strtok(NULL, "\n");
142 1166 : if (!s1 || !s2)
143 : continue;
144 424 : if (!strcmp(s1, "UID")) {
145 53 : strcpy(USER, s2);
146 371 : } else if (!strcmp(s1, "SRV")) {
147 53 : strcpy(SERVER, s2);
148 318 : } else if (!strcmp(s1, "PWD")) {
149 53 : strcpy(PASSWORD, s2);
150 265 : } else if (!strcmp(s1, "DB")) {
151 53 : strcpy(DATABASE, s2);
152 : }
153 : }
154 53 : fclose(in);
155 :
156 : /* apply command-line overrides */
157 53 : if (options.username) {
158 0 : strcpy(USER, options.username);
159 0 : free(options.username);
160 : }
161 53 : if (options.password) {
162 0 : strcpy(PASSWORD, options.password);
163 0 : free(options.password);
164 : }
165 53 : if (options.servername) {
166 0 : strcpy(SERVER, options.servername);
167 0 : free(options.servername);
168 : }
169 53 : if (options.database) {
170 0 : strcpy(DATABASE, options.database);
171 0 : free(options.database);
172 : }
173 :
174 53 : printf("found %s.%s for %s in \"%s\"\n", SERVER, DATABASE, USER, filename);
175 53 : return 0;
176 : }
177 :
178 : void
179 : check_crumbs(void)
180 2622 : {
181 : int i;
182 2622 : memcheck_t *ptr = breadcrumbs;
183 :
184 2622 : i = num_breadcrumbs;
185 170843 : while (ptr != NULL) {
186 165599 : if (ptr->special != BREADCRUMB || ptr->item_number != i) {
187 0 : fprintf(stderr, "Somebody overwrote one of the bread crumbs!!!\n");
188 0 : abort();
189 : }
190 :
191 165599 : i--;
192 165599 : ptr = ptr->next;
193 : }
194 2622 : }
195 :
196 :
197 :
198 : void
199 : add_bread_crumb(void)
200 2584 : {
201 : memcheck_t *tmp;
202 :
203 2584 : check_crumbs();
204 :
205 2584 : tmp = (memcheck_t *) calloc(sizeof(memcheck_t), 1);
206 2584 : if (tmp == NULL) {
207 0 : fprintf(stderr, "Out of memory");
208 0 : abort();
209 : exit(1);
210 : }
211 :
212 2584 : num_breadcrumbs++;
213 :
214 2584 : tmp->item_number = num_breadcrumbs;
215 2584 : tmp->special = BREADCRUMB;
216 2584 : tmp->next = breadcrumbs;
217 :
218 2584 : breadcrumbs = tmp;
219 2584 : }
220 :
221 : void
222 : free_bread_crumb(void)
223 38 : {
224 38 : memcheck_t *tmp, *ptr = breadcrumbs;
225 :
226 38 : check_crumbs();
227 :
228 2660 : while (ptr) {
229 2584 : tmp = ptr->next;
230 2584 : free(ptr);
231 2584 : ptr = tmp;
232 : }
233 38 : num_breadcrumbs = 0;
234 38 : }
235 :
236 : int
237 : syb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line)
238 221 : {
239 : char var_value[31];
240 : int i;
241 : char *c;
242 :
243 : /*
244 : * Check for "database changed", or "language changed" messages from
245 : * the client. If we get one of these, then we need to pull the
246 : * name of the database or charset from the message and set the
247 : * appropriate variable.
248 : */
249 221 : if (msgno == 5701 || /* database context change */
250 : msgno == 5703 || /* language changed */
251 : msgno == 5704) { /* charset changed */
252 :
253 : /* fprintf( stderr, "msgno = %d: %s\n", msgno, msgtext ) ; */
254 :
255 182 : if (msgtext != NULL && (c = strchr(msgtext, '\'')) != NULL) {
256 146 : i = 0;
257 952 : for (++c; i <= 30 && *c != '\0' && *c != '\''; ++c)
258 806 : var_value[i++] = *c;
259 146 : var_value[i] = '\0';
260 :
261 : #if 0
262 : switch (msgno) {
263 : case 5701:
264 : env_set(g_env, "database", var_value);
265 : break;
266 : case 5703:
267 : env_set(g_env, "language", var_value);
268 : break;
269 : case 5704:
270 : env_set(g_env, "charset", var_value);
271 : -break;
272 : default:
273 : break;
274 : }
275 : #endif
276 : }
277 182 : return 0;
278 : }
279 :
280 : /*
281 : * If the severity is something other than 0 or the msg number is
282 : * 0 (user informational messages).
283 : */
284 39 : if (severity >= 0 || msgno == 0) {
285 : /*
286 : * If the message was something other than informational, and
287 : * the severity was greater than 0, then print information to
288 : * stderr with a little pre-amble information.
289 : */
290 78 : if (msgno > 0 && severity > 0) {
291 39 : fprintf(stderr, "Msg %d, Level %d, State %d\n", (int) msgno, (int) severity, (int) msgstate);
292 39 : fprintf(stderr, "Server '%s'", srvname);
293 39 : if (procname != NULL && *procname != '\0')
294 0 : fprintf(stderr, ", Procedure '%s'", procname);
295 39 : if (line > 0)
296 39 : fprintf(stderr, ", Line %d", line);
297 39 : fprintf(stderr, "\n");
298 39 : fprintf(stderr, "%s\n", msgtext);
299 39 : fflush(stderr);
300 : } else {
301 : /*
302 : * Otherwise, it is just an informational (e.g. print) message
303 : * from the server, so send it to stdout.
304 : */
305 0 : fprintf(stdout, "%s\n", msgtext);
306 0 : fflush(stdout);
307 : }
308 : }
309 :
310 39 : return 0;
311 : }
312 :
313 : int
314 : syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
315 49 : {
316 :
317 : /*
318 : * For server messages, cancel the query and rely on the
319 : * message handler to spew the appropriate error messages out.
320 : */
321 49 : if (dberr == SYBESMSG)
322 39 : return INT_CANCEL;
323 :
324 : #if 0
325 : /*
326 : * For any other type of severity (that is not a server
327 : * message), we increment the batch_failcount.
328 : */
329 : env_set(g_env, "batch_failcount", "1");
330 : #endif
331 :
332 10 : fprintf(stderr,
333 : "DB-LIBRARY error (severity %d, dberr %d, oserr %d, dberrstr %s, oserrstr %s):\n",
334 : severity, dberr, oserr, dberrstr ? dberrstr : "(null)", oserrstr ? oserrstr : "(null)");
335 10 : fflush(stderr);
336 :
337 : /*
338 : * If the dbprocess is dead or the dbproc is a NULL pointer and
339 : * we are not in the middle of logging in, then we need to exit.
340 : * We can't do anything from here on out anyway.
341 : * It's OK to end up here in response to a dbconvert() that
342 : * resulted in overflow, so don't exit in that case.
343 : */
344 10 : if ((dbproc == NULL) || DBDEAD(dbproc)) {
345 4 : if (dberr != SYBECOFL) {
346 0 : exit(255);
347 : }
348 : }
349 :
350 10 : return INT_CANCEL;
351 : }
|