config.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:31k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: config.c,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 20:34:34  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.5
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
  10.  * Copyright (C) 1998-1999  Brian Bruns
  11.  *
  12.  * This library is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Library General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Library General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Library General Public
  23.  * License along with this library; if not, write to the
  24.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25.  * Boston, MA 02111-1307, USA.
  26.  */
  27. #include <tds_config.h>
  28. #include <stdio.h>
  29. #include <stdlib.h>
  30. #include <stdarg.h>
  31. #include <time.h>
  32. #include <limits.h>
  33. #include <assert.h>
  34. #include <ctype.h>
  35. #ifdef __DGUX__
  36. #include <paths.h>
  37. #endif
  38. #ifdef __FreeBSD__
  39. #include <sys/time.h>
  40. #endif
  41. #ifdef WIN32
  42. #include <windows.h>
  43. #include <stdio.h>
  44. #define PATH_MAX 255
  45. #endif
  46. #ifndef WIN32
  47. #include <netdb.h>
  48. #include <sys/types.h>
  49. #include <netinet/in.h>
  50. #include <arpa/inet.h>
  51. #endif
  52. #include "tds.h"
  53. #include "tdsutil.h"
  54. #ifdef DMALLOC
  55. #include <dmalloc.h>
  56. #endif
  57. static char  software_version[]   = "$Id: config.c,v 1000.0 2003/10/29 20:34:34 gouriano Exp $";
  58. static void *no_unused_var_warn[] = {software_version,
  59.                                      no_unused_var_warn};
  60. static void tds_config_login(TDSCONFIGINFO *config, TDSLOGIN *login);
  61. static void tds_config_env_dsquery(TDSCONFIGINFO *config);
  62. static void tds_config_env_tdsdump(TDSCONFIGINFO *config);
  63. static void tds_config_env_tdsver(TDSCONFIGINFO *config);
  64. static void tds_config_env_tdsport(TDSCONFIGINFO *config);
  65. static void tds_config_env_tdshost(TDSCONFIGINFO *config);
  66. static int tds_read_conf_file(char *server, TDSCONFIGINFO *config);
  67. static int tds_read_conf_sections(FILE *in, char *server, TDSCONFIGINFO *config);
  68. static int tds_read_conf_section(FILE *in, char *section, TDSCONFIGINFO *config);
  69. static void tds_read_interfaces(char *server, TDSCONFIGINFO *config);
  70. static void tds_config_verstr(char *tdsver, TDSCONFIGINFO *config);
  71. static int tds_config_boolean(char *value);
  72. static void lookup_host(const char *servername, const char *portname, char *ip, char *port);
  73. static int parse_server_name_for_port( TDSCONFIGINFO *config, TDSLOGIN *login );
  74. extern int g_append_mode;
  75. static char interf_file[MAXPATH];
  76. /*
  77. ** tds_get_config() will fill the tds config structure based on configuration 
  78. ** information gathered in the following order:
  79. ** 1) Program specified in TDSLOGIN structure
  80. ** 2) The environment variables TDSVER, TDSDUMP, TDSPORT, TDSQUERY, TDSHOST
  81. ** 3) A config file with the following search order:
  82. **    a) a readable file specified by environment variable FREETDSCONF
  83. **    b) a readable file in ~/.freetds.conf
  84. **    c) a readable file in $prefix/etc/freetds.conf
  85. ** 3) ~/.interfaces if exists
  86. ** 4) $SYBASE/interfaces if exists
  87. ** 5) TDS_DEF_* default values
  88. **
  89. ** .tdsrc and freetds.conf have been added to make the package easier to 
  90. ** integration with various Linux and *BSD distributions.
  91. */ 
  92. TDSCONFIGINFO *tds_get_config(TDSSOCKET *tds, TDSLOGIN *login, TDSLOCINFO *locale)
  93. {
  94. TDSCONFIGINFO *config;
  95. char *s;
  96. char path[MAXPATH];
  97. pid_t pid;
  98. /* allocate a new structure with hard coded and build-time defaults */
  99. config = tds_alloc_config(locale);
  100.         s=getenv("TDSDUMPCONFIG");
  101.         if (s)
  102.         {
  103.             if ( !*s)
  104.             {
  105.                 pid = getpid();
  106.                 sprintf(path,"/tmp/tdsconfig.log.%d",pid);
  107.                 s = path;
  108.             }
  109.             tdsdump_open(s);
  110.         }
  111. tdsdump_log(TDS_DBG_INFO1, "%L Attempting to read conf files.n");
  112. if (! tds_read_conf_file(login->server_name, config)) {
  113. /* fallback to interfaces file */
  114. tdsdump_log(TDS_DBG_INFO1, "%L Failed in reading conf file.  Trying interface files.n");
  115. tds_read_interfaces(login->server_name, config);
  116. }
  117. if( parse_server_name_for_port( config, login ) ) {
  118. tdsdump_log(TDS_DBG_INFO1, "Parsed servername, now %s on %d.n", config->server_name, login->port);
  119. }
  120. /* Now check the environment variables */
  121. tds_config_env_tdsver(config);
  122. tds_config_env_tdsdump(config);
  123. tds_config_env_tdsport(config);
  124. tds_config_env_dsquery(config);
  125. tds_config_env_tdshost(config);
  126. /* And finally the login structure */
  127. tds_config_login(config, login);
  128.         if ( s && *s) tdsdump_close();
  129. return config;
  130. }        
  131. static int tds_try_conf_file(char *path, char *how, char *server, TDSCONFIGINFO *config)
  132. {
  133. int found = 0;
  134. FILE *in;
  135. if ((in = fopen (path, "r")) != NULL) {
  136. tdsdump_log(TDS_DBG_INFO1, 
  137. "%L Found conf file in %s %s. Reading section %s.n",interf_file,how, server);
  138. found = tds_read_conf_sections (in, server, config);
  139.                        if(found) tdsdump_log(TDS_DBG_INFO1, "%L ...Success.n");
  140. fclose (in);
  141. }
  142. return found;
  143. }
  144. static int tds_read_conf_file(char *server, TDSCONFIGINFO *config)
  145. {
  146. #ifndef NCBI_FTDS
  147. FILE *in;
  148. #endif
  149. char  *home, *path;
  150. int found = 0; 
  151. if (interf_file[0]!='') {
  152. found = tds_try_conf_file(interf_file,"set programmatically", server, config);
  153. }
  154. /* FREETDSCONF env var, pkleef@openlinksw.com 01/21/02 */
  155. if (!found) {
  156. path = getenv ("FREETDSCONF");
  157. if (path) {
  158. found = tds_try_conf_file(path, "(from $FREETDSCONF)", server, config);
  159. }
  160. }
  161. if (!found) {
  162. /* FIXME use getpwent for security */
  163. home = getenv("HOME");
  164. if (home!=NULL && home[0]!='') {
  165. /* FIXME check buffer */
  166. path = malloc(strlen(home) + 14 + 1); /* strlen("/.freetds.conf")=14 */
  167. sprintf(path,"%s/.freetds.conf",home);
  168. found = tds_try_conf_file(path, "(.freetds.conf)", server, config);
  169. free(path);
  170. }
  171. }
  172. if (!found) {
  173. found = tds_try_conf_file(FREETDS_SYSCONFFILE, "(default)", server, config);
  174. }
  175. return found;
  176. }
  177. static int tds_read_conf_sections(FILE *in, char *server, TDSCONFIGINFO *config)
  178. {
  179. char *section;
  180. int i, found = 0;
  181. tds_read_conf_section(in, "global", config);
  182. rewind(in);
  183. section = strdup(server);
  184. for (i=0;i<strlen(section);i++) section[i]=tolower(section[i]);
  185. found = tds_read_conf_section(in, section, config);
  186. free(section);
  187. return found;
  188. }
  189. static int tds_config_boolean(char *value) 
  190. {
  191. if (!strcmp(value, "yes") ||
  192. !strcmp(value, "on") ||
  193. !strcmp(value, "true") ||
  194. !strcmp(value, "1")) {
  195.                 tdsdump_log(TDS_DBG_INFO1, "%L %s is a 'yes/on/true'.n",value);
  196.                 return 1;
  197. } else {
  198.                 tdsdump_log(TDS_DBG_INFO1, "%L %s is a 'no/off/false'.n",value);
  199.                 return 0;
  200. }
  201. }
  202. static int tds_read_conf_section(FILE *in, char *section, TDSCONFIGINFO *config)
  203. {
  204. char line[256], option[256], value[256], *s;
  205. int i;
  206. char p;
  207. int insection = 0;
  208. char tmp[256];
  209. int found = 0;
  210.         tdsdump_log(TDS_DBG_INFO1, "%L Looking for section %s.n", section);
  211. while (fgets(line, 256, in)) {
  212. s = line;
  213. /* skip leading whitespace */
  214. while (*s && isspace(*s)) s++;
  215. /* skip it if it's a comment line */
  216. if (*s==';' || *s=='#') continue;
  217. /* read up to the = ignoring duplicate spaces */
  218. p = 0; i = 0;
  219. while (*s && *s!='=') {
  220. if (!isspace(*s) && isspace(p)) 
  221. option[i++]=' ';
  222. if (!isspace(*s)) 
  223. option[i++]=tolower(*s);
  224. p = *s;
  225. s++;
  226. }
  227. option[i]='';
  228. /* skip the = */
  229. if(*s) s++;
  230. /* skip leading whitespace */
  231. while (*s && isspace(*s)) s++;
  232. /* read up to a # ; or null ignoring duplicate spaces */
  233. p = 0; i = 0;
  234. while (*s && *s!=';' && *s!='#') {
  235. if (!isspace(*s) && isspace(p)) 
  236. value[i++]=' ';
  237. if (!isspace(*s)) 
  238. value[i++]=*s;
  239. p = *s;
  240. s++;
  241. }
  242. value[i]='';
  243. if (!strlen(option)) 
  244. continue;
  245. if (option[0]=='[') {
  246. s = &option[1];
  247. while (*s) {
  248.                                 if (*s==']') *s='';
  249.                                 *s = tolower(*s);
  250. s++;
  251. }
  252.                         tdsdump_log(TDS_DBG_INFO1, "%L ... Found section %s.n", &option[1]);
  253. if (!strcmp(section, &option[1])) {
  254. tdsdump_log(TDS_DBG_INFO1, "%L Got a match.n");
  255. insection=1;
  256. found=1;
  257. } else {
  258. insection=0;
  259. }
  260. } else if (insection) {
  261.                     /* fprintf(stderr,"option = '%s' value = '%s'n", option, value); */
  262.                         tdsdump_log(TDS_DBG_INFO1, "%L option = '%s' value = '%s'.n", option, value);
  263. if (!strcmp(option,TDS_STR_VERSION)) {
  264. tds_config_verstr(value, config);
  265. } else if (!strcmp(option,TDS_STR_BLKSZ)) {
  266. if (atoi(value)) 
  267. config->block_size = atoi(value);
  268. } else if (!strcmp(option,TDS_STR_SWAPDT)) {
  269. config->broken_dates = tds_config_boolean(value);
  270. } else if (!strcmp(option,TDS_STR_SWAPMNY)) {
  271. config->broken_money = tds_config_boolean(value);
  272. } else if (!strcmp(option,TDS_STR_TRYSVR)) {
  273. config->try_server_login = tds_config_boolean(value);
  274. } else if (!strcmp(option,TDS_STR_TRYDOM)) {
  275. config->try_domain_login = tds_config_boolean(value);
  276. } else if (!strcmp(option,TDS_STR_DOMAIN)) {
  277. if (config->default_domain) free(config->default_domain);
  278. config->default_domain = strdup(value);
  279. } else if (!strcmp(option,TDS_STR_XDOMAUTH)) {
  280. config->xdomain_auth = tds_config_boolean(value);
  281. } else if (!strcmp(option,TDS_STR_DUMPFILE)) {
  282. if (config->dump_file) free(config->dump_file);
  283. config->dump_file = strdup(value);
  284. } else if (!strcmp(option,TDS_STR_DEBUGLVL)) {
  285. if (atoi(value)) 
  286. config->debug_level = atoi(value);
  287. } else if (!strcmp(option,TDS_STR_TIMEOUT )) {
  288. if (atoi(value)) 
  289. config->timeout = atoi(value);
  290. } else if (!strcmp(option,TDS_STR_CONNTMOUT)) {
  291. if (atoi(value)) 
  292. config->connect_timeout = atoi(value);
  293. } else if (!strcmp(option,TDS_STR_HOST)) {
  294. tdsdump_log(TDS_DBG_INFO1, "%L Found host entry %s.n",value);
  295.     lookup_host(value, NULL, tmp, NULL);
  296. #ifdef NCBI_FTDS
  297. if (config->ip_addr[0]) free(config->ip_addr[0]);
  298. config->ip_addr[0] = strdup(tmp);
  299. tdsdump_log(TDS_DBG_INFO1, "%L IP addr is %s.n",config->ip_addr[0]);
  300. #else
  301. if (config->ip_addr) free(config->ip_addr);
  302. config->ip_addr = strdup(tmp);
  303. tdsdump_log(TDS_DBG_INFO1, "%L IP addr is %s.n",config->ip_addr);
  304. #endif
  305. } else if (!strcmp(option,TDS_STR_PORT)) {
  306. if (atoi(value)) 
  307. #ifdef NCBI_FTDS
  308. config->port[0] = atoi(value);
  309. #else
  310. config->port = atoi(value);
  311. #endif
  312. } else if (!strcmp(option,TDS_STR_EMUL_LE)) {
  313. config->emul_little_endian = tds_config_boolean(value);
  314. } else if (!strcmp(option,TDS_STR_TEXTSZ)) {
  315. if (atoi(value)) 
  316. config->text_size = atoi(value);
  317. } else if (!strcmp(option,TDS_STR_CHARSET)) {
  318. if (config->char_set) free(config->char_set);
  319. config->char_set = strdup(value);
  320. } else if (!strcmp(option,TDS_STR_CLCHARSET)) {
  321. if (config->client_charset) free(config->client_charset);
  322. config->client_charset = strdup(value);
  323. } else if (!strcmp(option,TDS_STR_LANGUAGE)) {
  324. if (config->language) free(config->language);
  325. config->language = strdup(value);
  326. } else if (!strcmp(option,TDS_STR_APPENDMODE)) {
  327. g_append_mode = tds_config_boolean(value);
  328. }
  329.                         else tdsdump_log(TDS_DBG_INFO1, "%L UNRECOGNIZED option '%s'...ignoring.n", option);
  330. }
  331. }
  332. return found;
  333. }
  334. #ifdef NCBI_FTDS
  335. static int get_server_info(char *server, int entry_num, char *ip_addr, char *ip_port,  
  336. char *tds_ver);
  337. #endif
  338. static void tds_read_interfaces(char *server, TDSCONFIGINFO *config)
  339. {
  340. char ip_addr[255], ip_port[255], tds_ver[255];
  341. /* read $SYBASE/interfaces */
  342. /* This needs to be cleaned up */
  343. #ifdef NCBI_FTDS
  344.     int entry_num;
  345. for(entry_num= 0; entry_num < NCBI_NUM_SERVERS; entry_num++) {
  346.     get_server_info(server, entry_num+1, ip_addr, ip_port, tds_ver);
  347. if (strlen(ip_addr) == 0) break;
  348. if (config->ip_addr[entry_num]) free(config->ip_addr[entry_num]);
  349. /* FIXME check result, use strdup */
  350. config->ip_addr[entry_num] = (char *) malloc(strlen(ip_addr)+1);
  351. strcpy(config->ip_addr[entry_num], ip_addr);
  352. if (atoi(ip_port)) {
  353.     config->port[entry_num] = atoi(ip_port);
  354. }
  355. if (strlen(tds_ver)) {
  356.     tds_config_verstr(tds_ver, config);
  357. /* if it doesn't match a known version do nothing with it */
  358. }
  359. }
  360. while(entry_num < NCBI_NUM_SERVERS) {
  361. if (config->ip_addr[entry_num]) free(config->ip_addr[entry_num]);
  362. config->ip_addr[entry_num++]= NULL;
  363. }
  364. #else
  365. get_server_info(server, ip_addr, ip_port, tds_ver);
  366. if (strlen(ip_addr)) {
  367. if (config->ip_addr) free(config->ip_addr);
  368. /* FIXME check result, use strdup */
  369. config->ip_addr = (char *) malloc(strlen(ip_addr)+1);
  370. strcpy(config->ip_addr, ip_addr);
  371. }
  372. if (atoi(ip_port)) {
  373. config->port = atoi(ip_port);
  374. }
  375. if (strlen(tds_ver)) {
  376. tds_config_verstr(tds_ver, config);
  377. /* if it doesn't match a known version do nothing with it */
  378. }
  379. #endif
  380. }
  381. static void tds_config_login(TDSCONFIGINFO *config, TDSLOGIN *login)
  382. {
  383. if (login->server_name && strlen(login->server_name)) {
  384. if (config->server_name) free(config->server_name);
  385. config->server_name = strdup(login->server_name);
  386. }
  387. if (login->major_version || login->minor_version) {
  388. config->major_version = login->major_version;
  389. config->minor_version = login->minor_version;
  390. }
  391.         if (login->language && strlen(login->language)) {
  392. if (config->language) free(config->language);
  393. config->language = strdup(login->language);
  394. }
  395.         if (login->char_set && strlen(login->char_set)) {
  396. if (config->char_set) free(config->char_set);
  397. config->char_set = strdup(login->char_set);
  398. }
  399.         if (login->host_name && strlen(login->host_name)) {
  400. if (config->host_name) free(config->host_name);
  401. config->host_name = strdup(login->host_name);
  402. /* DBSETLHOST and it's equivilants are commentary fields
  403. ** they don't affect config->ip_addr (the server) but they show
  404. ** up in an sp_who as the *clients* hostname.  (bsb, 11/10) 
  405. */
  406. /* should work with IP (mlilback, 11/7/01) */
  407. /*
  408. if (config->ip_addr) free(config->ip_addr);
  409. config->ip_addr = calloc(sizeof(char),18);
  410. lookup_host(config->host_name, NULL, config->ip_addr, NULL);
  411. */
  412. }
  413.         if (login->app_name && strlen(login->app_name)) {
  414. if (config->app_name) free(config->app_name);
  415. config->app_name = strdup(login->app_name);
  416. }
  417.         if (login->user_name && strlen(login->user_name)) {
  418. if (config->user_name) free(config->user_name);
  419. config->user_name = strdup(login->user_name);
  420. }
  421.         if (login->password && strlen(login->password)) {
  422. if (config->password) {
  423. /* for security reason clear memory */
  424. memset(config->password,0,strlen(config->password));
  425. free(config->password);
  426. }
  427. config->password = strdup(login->password);
  428. }
  429.         if (login->library && strlen(login->library)) {
  430. if (config->library) free(config->library);
  431. config->library = strdup(login->library);
  432. }
  433.         if (login->encrypted) {
  434. config->encrypted = 1;
  435. }
  436.         if (login->suppress_language) {
  437. config->suppress_language = 1;
  438. }
  439.         if (login->bulk_copy) {
  440. config->bulk_copy = 1;
  441. }
  442.         if (login->block_size) {
  443. config->block_size = login->block_size;
  444. }
  445. #ifdef NCBI_FTDS
  446. else if(config->major_version >= 7) {
  447.         config->block_size= 6*1024;
  448. }
  449. #endif
  450.         if (login->port) {
  451. #ifdef NCBI_FTDS
  452. config->port[0] = login->port;
  453. #else
  454. config->port = login->port;
  455. #endif
  456. }
  457. }
  458. static void tds_config_env_dsquery(TDSCONFIGINFO *config)
  459. {
  460. char *s;
  461. if ((s=getenv("TDSQUERY"))) {
  462. if (s && strlen(s)) {
  463. if (config->server_name) free(config->server_name);
  464. config->server_name = strdup(s);
  465. tdsdump_log(TDS_DBG_INFO1, "%L Setting 'server_name' to '%s' from $TDSQUERY.n",s);
  466. return;
  467. }
  468. if ((s=getenv("DSQUERY"))) {
  469. if (s && strlen(s)) {
  470. if (config->server_name) free(config->server_name);
  471. config->server_name = strdup(s);
  472. tdsdump_log(TDS_DBG_INFO1, "%L Setting 'server_name' to '%s' from $DSQUERY.n",s);
  473. }
  474. }
  475. static void tds_config_env_tdsdump(TDSCONFIGINFO *config)
  476. {
  477. char *s;
  478. char path[255];
  479. pid_t pid=0;
  480.         if ((s=getenv("TDSDUMP"))) {
  481.                 if (!strlen(s)) {
  482.                         pid = getpid();
  483.                         sprintf(path,"/tmp/freetds.log.%d",pid);
  484. if (config->dump_file) free(config->dump_file);
  485. config->dump_file = strdup(path);
  486.                 } else {
  487. if (config->dump_file) free(config->dump_file);
  488. config->dump_file = strdup(s);
  489.                 }
  490.                 tdsdump_log(TDS_DBG_INFO1, "%L Setting 'dump_file' to '%s' from $TDSDUMP.n",config->dump_file);
  491.         }
  492. }
  493. static void tds_config_env_tdsport(TDSCONFIGINFO *config)
  494. {
  495. char *s;
  496. if ((s=getenv("TDSPORT"))) {
  497. #ifdef NCBI_FTDS
  498.             config->port[0]=atoi(s);
  499. #else
  500.             config->port=atoi(s);
  501. #endif
  502.             tdsdump_log(TDS_DBG_INFO1, "%L Setting 'port' to %s from $TDSPORT.n",s);
  503. }
  504. return;
  505. }
  506. static void tds_config_env_tdsver(TDSCONFIGINFO *config)
  507. {
  508. char *tdsver;
  509. if ((tdsver=getenv("TDSVER"))) {
  510.             tds_config_verstr(tdsver, config);
  511.             tdsdump_log(TDS_DBG_INFO1, "%L Setting 'tdsver' to %s from $TDSVER.n",tdsver);
  512. }
  513. return;
  514. }
  515. /* TDSHOST env var, pkleef@openlinksw.com 01/21/02 */
  516. static void tds_config_env_tdshost(TDSCONFIGINFO *config)
  517. {
  518. char *tdshost;
  519. char tmp[256];
  520. if ((tdshost=getenv("TDSHOST"))) {
  521. lookup_host (tdshost, NULL, tmp, NULL);
  522. #ifdef NCBI_FTDS
  523. if (config->ip_addr[0])
  524. free (config->ip_addr[0]);
  525. config->ip_addr[0] = strdup (tmp);
  526. #else
  527. if (config->ip_addr)
  528. free (config->ip_addr);
  529. config->ip_addr = strdup (tmp);
  530. #endif
  531.                 tdsdump_log(TDS_DBG_INFO1, "%L Setting 'ip_addr' to %s (%s) from $TDSHOST.n",tmp, tdshost);
  532. }
  533. return;
  534. }
  535. static void tds_config_verstr(char *tdsver, TDSCONFIGINFO *config)
  536. {
  537. if (!strcmp(tdsver,"42") || !strcmp(tdsver,"4.2")) {
  538. config->major_version=4;
  539. config->minor_version=2;
  540. return;
  541. } else if (!strcmp(tdsver,"46") || !strcmp(tdsver,"4.6")) {
  542. config->major_version=4;
  543. config->minor_version=6;
  544. return;
  545. } else if (!strcmp(tdsver,"50") || !strcmp(tdsver,"5.0")) {
  546. config->major_version=5;
  547. config->minor_version=0;
  548. return;
  549. } else if (!strcmp(tdsver,"70") || !strcmp(tdsver,"7.0")) {
  550. config->major_version=7;
  551. config->minor_version=0;
  552. return;
  553. } else if (!strcmp(tdsver,"80") || !strcmp(tdsver,"8.0")) {
  554. config->major_version=8;
  555. config->minor_version=0;
  556. return;
  557. }
  558. }
  559. int set_interfaces_file_loc(char *interf)
  560. {
  561. if (strlen(interf)>=MAXPATH) return 0;
  562. strcpy(interf_file,interf);
  563. return 1; /* SUCCEED */
  564. }
  565. /* ============================== lookup_host() ==============================
  566.  *
  567.  * Def:  Given a servername and port name or number, lookup the
  568.  *       hostname and service.  The server ip will be stored in the
  569.  *       string 'servername' in dotted-decimal notation.  The service port
  570.  *       number will be stored in string form in the 'port' parameter.
  571.  *
  572.  *       If we can't determine both the IP address and port number then
  573.  *       'ip' and 'port' will be set to empty strings.
  574.  *
  575.  * Ret:  void
  576.  *
  577.  * ===========================================================================
  578.  */
  579. static void lookup_host(
  580.    const char  *servername,  /* (I) name of the server                  */
  581.    const char  *portname,    /* (I) name or number of the port          */
  582.    char        *ip,          /* (O) dotted-decimal ip address of server */
  583.    char        *port)        /* (O) port number of the service          */
  584. {
  585.    struct hostent   *host    = NULL;
  586.    struct servent   *service = NULL;
  587.    int               num     = 0;
  588.    unsigned int ip_addr=0;
  589.    /* Storage for reentrant getaddrby* calls */
  590.    struct hostent result;
  591.    char buffer[4096];
  592.    int h_errnop;
  593.    /* Storage for reentrant getservbyname */
  594.    struct servent serv_result;
  595.    /* Only call gethostbyname if servername is not an ip address. 
  596.       This call take a while and is useless for an ip address.
  597.       mlilback 3/2/02 */
  598.    ip_addr = inet_addr(servername);
  599.    if (ip_addr == INADDR_NONE)
  600.       host = tds_gethostbyname_r(servername, &result, buffer, sizeof(buffer), &h_errnop);
  601. #ifndef NOREVERSELOOKUPS
  602. /* froy@singleentry.com 12/21/2000 */
  603. if (host==NULL) {
  604. char addr [4];
  605. int a0, a1, a2, a3;
  606. sscanf (servername, "%d.%d.%d.%d", &a0, &a1, &a2, &a3);
  607. addr [0] = a0;
  608. addr [1] = a1;
  609. addr [2] = a2;
  610. addr [3] = a3;
  611. host    = tds_gethostbyaddr_r (addr, 4, AF_INET, &result, buffer, sizeof(buffer), &h_errnop);
  612. }
  613. /* end froy */ 
  614. #endif
  615.    if (!host) {
  616.       /* if servername is ip, copy to ip. */
  617.       if (INADDR_NONE != ip_addr)
  618.          strncpy(ip, servername, 17); 
  619.       else
  620.          ip[0]   = '';
  621.    } else {
  622.       struct in_addr *ptr = (struct in_addr *) host->h_addr;
  623.       strncpy(ip, inet_ntoa(*ptr), 17);
  624.    }
  625.    if (portname) {
  626. #ifdef NCBI_FTDS
  627.  char* tail;
  628.  num= (int)strtol(portname, &tail, 10);
  629.  if((num == 0) || (tail != NULL && *tail != '')) {
  630.    service = tds_getservbyname_r(portname, "tcp", &serv_result, buffer, sizeof(buffer));
  631.    if(service) 
  632.  num= ntohs(service->s_port);
  633.  }
  634. #else
  635.      service = tds_getservbyname_r(portname, "tcp", &serv_result, buffer, sizeof(buffer));
  636.       if (service==NULL) {
  637.          num = atoi(portname);
  638.       } else {
  639.          num = ntohs(service->s_port);
  640.       }
  641. #endif
  642.    }
  643.    if (num==0) {
  644. if (port) port[0] = '';
  645.    } else {
  646. sprintf(port, "%d", num);
  647.    }
  648. } /* lookup_host()  */
  649. static int hexdigit(char c)
  650. {
  651. if (c>='a' && c<='f') {
  652. return c - 'a' + 10;
  653. } else if (c>='A' && c<='F') {
  654. return c - 'A' + 10;
  655. } else if (c>='0' && c<='9') {
  656. return c - '0';
  657. } else {
  658. return 0; /* bad hex digit */
  659. }
  660. }
  661. static int hex2num(char *hex)
  662. {
  663. return hexdigit(hex[0])*16 + hexdigit(hex[1]);
  664. }
  665. /* ========================= search_interface_file() =========================
  666.  *
  667.  * Def:  Open and read the file 'file' searching for a logical server
  668.  *       by the name of 'host'.  If one is found then lookup
  669.  *       the IP address and port number and store them in 'ip_addr', and
  670.  *       'ip_port'.
  671.  *
  672.  * Ret:  void
  673.  *
  674.  * ===========================================================================
  675.  */
  676. static void search_interface_file(
  677.    const char *dir,     /* (I) Name of base directory for interface file */
  678.    const char *file,    /* (I) Name of the interface file                */
  679.    const char *host,    /* (I) Logical host to search for                */
  680. #ifdef NCBI_FTDS
  681.    int       entry_num, /* (I) entry number for host in interface file   */
  682. #endif
  683.    char       *ip_addr, /* (O) dotted-decimal IP address                 */
  684.    char       *ip_port, /* (O) Port number for database server           */
  685.    char       *tds_ver) /* (O) Protocol version to use when connecting   */
  686. {
  687. char  *pathname;
  688. char  line[255];
  689. char  tmp_ip[sizeof(line)];
  690. char  tmp_port[sizeof(line)];
  691. char  tmp_ver[sizeof(line)];
  692. FILE *in;
  693. char *field;
  694. int   found=0;
  695. char *lasts;
  696. ip_addr[0]  = '';
  697. ip_port[0]  = '';
  698. line[0]     = '';
  699. tmp_ip[0]   = '';
  700. tmp_port[0] = '';
  701. tmp_ver[0]  = '';
  702. tdsdump_log(TDS_DBG_INFO1, "%L Searching interfaces file %s/%s.n",dir,file);
  703. /* FIXME check result or use open fchdir fopen ... */
  704. pathname = (char *) malloc(strlen(dir) + strlen(file) + 10);
  705.    
  706. /*
  707. * create the full pathname to the interface file
  708. */
  709. /* FIXME file and dir can't be NULL, used before in strlen */
  710. if (file==NULL || file[0]=='') {
  711. pathname[0] = '';
  712. } else {
  713. if (dir==NULL || dir[0]=='') {
  714. pathname[0] = '';
  715. } else {
  716. strcpy(pathname, dir);
  717. strcat(pathname, "/");
  718. }
  719. strcat(pathname, file);
  720. }
  721. /*
  722. *  parse the interfaces file and find the server and port
  723. */
  724. if ((in = fopen(pathname,"r"))==NULL) {
  725.                 tdsdump_log(TDS_DBG_INFO1, "%L Couldn't open %s.n", pathname);
  726.                 free(pathname);
  727. return;
  728. }
  729. tdsdump_log(TDS_DBG_INFO1, "%L Interfaces file %s opened.n", pathname);
  730. while (fgets(line,sizeof(line)-1,in)) {
  731. if (line[0]=='#') continue; /* comment */
  732. if (!isspace(line[0])) {
  733. field = tds_strtok_r(line,"nt ", &lasts);
  734. if (!strcmp(field,host)) {
  735. found=1;
  736. tdsdump_log(TDS_DBG_INFO1, "%L Found matching entry for host %s.n,host");
  737. }
  738. else found=0;
  739. } else if (found && isspace(line[0])) {
  740. field = tds_strtok_r(line,"nt ", &lasts);
  741. if (field!=NULL && !strcmp(field,"query")) {
  742. #ifdef NCBI_FTDS
  743.   if(--entry_num > 0) continue;
  744. #endif
  745. field = tds_strtok_r(NULL,"nt ", &lasts); /* tcp or tli */
  746. if (!strcmp(field,"tli")) {
  747. tdsdump_log(TDS_DBG_INFO1, "%L TLI service.n");
  748. field = tds_strtok_r(NULL,"nt ", &lasts); /* tcp */
  749. field = tds_strtok_r(NULL,"nt ", &lasts); /* device */
  750. field = tds_strtok_r(NULL,"nt ", &lasts); /* host/port */
  751. if (strlen(field)>=18) {
  752. sprintf(tmp_port,"%d", hex2num(&field[6])*256 + 
  753. hex2num(&field[8]));
  754. sprintf(tmp_ip,"%d.%d.%d.%d", hex2num(&field[10]),
  755. hex2num(&field[12]), hex2num(&field[14]),
  756. hex2num(&field[16]));
  757.         tdsdump_log(TDS_DBG_INFO1, "%L tmp_port = %d.mtp_ip = %s.n", tmp_port, tmp_ip);
  758. }
  759. } else {
  760. field = tds_strtok_r(NULL,"nt ", &lasts); /* ether */
  761. strcpy(tmp_ver,field);
  762. field = tds_strtok_r(NULL,"nt ", &lasts); /* host */
  763. strcpy(tmp_ip,field);
  764. tdsdump_log(TDS_DBG_INFO1, "%L host field %s.n",tmp_ip);
  765. field = tds_strtok_r(NULL,"nt ", &lasts); /* port */
  766. strcpy(tmp_port,field);
  767. } /* else */
  768. #ifdef NCBI_FTDS
  769. break;
  770. #endif
  771. } /* if */
  772. } /* else if */
  773. } /* while */
  774. fclose(in);
  775. free(pathname);
  776.    /*
  777.     * Look up the host and service
  778.     */
  779. #ifdef NCBI_FTDS
  780.    if(*tmp_ip != '') 
  781. #endif
  782.    lookup_host(tmp_ip, tmp_port, ip_addr, ip_port);
  783.    tdsdump_log(TDS_DBG_INFO1, "%L Resolved IP as '%s'.n",ip_addr);
  784.    strcpy(tds_ver,tmp_ver);
  785. } /* search_interface_file()  */
  786. /* ============================ get_server_info() ============================
  787.  *
  788.  * Def:  Try to find the IP number and port for a (possibly) logical server
  789.  *       name.
  790.  *
  791.  * Note: It is the callers responsibility to supply large enough buffers
  792.  *       to hold the ip and port numbers.  ip_addr should be at least 17
  793.  *       bytes long and ip_port should be at least 6 bytes long.
  794.  *
  795.  * Note: This function uses only the interfaces file and is deprecated.
  796.  *
  797.  * Ret:  True if it found the server, false otherwise.
  798.  *
  799.  * ===========================================================================
  800.  */
  801. #ifdef NCBI_FTDS
  802. static
  803. #endif
  804. int get_server_info(
  805.    char *server,   /* (I) logical or physical server name      */
  806. #ifdef NCBI_FTDS
  807.    int entry_num,  /* (I) entry number in interface file */
  808. #endif
  809.    char *ip_addr,  /* (O) string representation of IP address  */
  810.    char *ip_port,  /* (O) string representation of port number */
  811.    char *tds_ver)  /* (O) string value specifying which protocol version */
  812. {
  813. ip_addr[0] = '';
  814. ip_port[0] = '';
  815. tds_ver[0] = '';
  816.         tdsdump_log(TDS_DBG_INFO1, "%L Looking for server....n");
  817. if (!server || strlen(server) == 0) {
  818. server = getenv("TDSQUERY");
  819. if(!server || strlen(server) == 0) {
  820. server = "SYBASE";
  821. }
  822.                 tdsdump_log(TDS_DBG_INFO1, "%L Setting server to %s from $TDSQUERY.n",server);
  823. }
  824. /*
  825. * Look for the server in the interf_file iff interf_file has been set.
  826. */
  827. if (ip_addr[0]=='' && interf_file[0]!='') {
  828.                 tdsdump_log(TDS_DBG_INFO1, "%L Looking for server in interf_file %s.n",interf_file);
  829. #ifdef NCBI_FTDS
  830.                 search_interface_file("", interf_file, server, entry_num, ip_addr,
  831. #else
  832.                 search_interface_file("", interf_file, server, ip_addr,
  833. #endif
  834.                 ip_port, tds_ver);
  835. }
  836. /*
  837. * if we haven't found the server yet then look for a $HOME/.interfaces file
  838. */
  839. if (ip_addr[0]=='') {
  840. /* FIXME use getpwent, see above */
  841. char  *home = getenv("HOME");
  842. if (home!=NULL && home[0]!='') {
  843.                         tdsdump_log(TDS_DBG_INFO1, "%L Looking for server in %s/.interfaces.n", home);
  844. #ifdef NCBI_FTDS
  845. search_interface_file(home, ".interfaces", server, entry_num, ip_addr,
  846. #else
  847. search_interface_file(home, ".interfaces", server, ip_addr,
  848. #endif
  849. ip_port, tds_ver);
  850. }
  851. }
  852. /*
  853. * if we haven't found the server yet then look in $SYBBASE/interfaces file
  854. */
  855. if (ip_addr[0]=='') {
  856. char  *sybase = getenv("SYBASE");
  857. if (sybase!=NULL && sybase[0]!='') {
  858.                         tdsdump_log(TDS_DBG_INFO1, "%L Looking for server in %s/interfaces.n", sybase);
  859. #ifdef NCBI_FTDS
  860. search_interface_file(sybase, "interfaces", server, entry_num, ip_addr,
  861. #else
  862. search_interface_file(sybase, "interfaces", server, ip_addr,
  863. #endif
  864. ip_port, tds_ver);
  865. } else {
  866.                         tdsdump_log(TDS_DBG_INFO1, "%L Looking for server in /etc/freetds/interfaces.n");
  867. search_interface_file("/etc/freetds", "interfaces", server,
  868. #ifdef NCBI_FTDS
  869.   entry_num,
  870. #endif
  871. ip_addr, ip_port, tds_ver);
  872. }
  873. }
  874.   /*
  875.   * If we still don't have the server and port then assume the user
  876.   * typed an actual server name.
  877.   */
  878. #ifdef NCBI_FTDS
  879.   if (ip_addr[0]=='' && entry_num < 2) {
  880. #else
  881.   if (ip_addr[0]=='') {
  882. #endif
  883.   char  *tmp_port;
  884. /*
  885. * Make a guess about the port number
  886. */
  887. #ifdef TDS50
  888. tmp_port = "4000";
  889. #else
  890. tmp_port = "1433";
  891. #endif
  892. /* FIX ME -- Need a symbolic constant for the environment variable */
  893. if (getenv("TDSPORT")!=NULL) {
  894. tmp_port = getenv("TDSPORT");
  895.                         tdsdump_log(TDS_DBG_INFO1, "%L Setting 'tmp_port' to %s from $TDSPORT.n",tmp_port);
  896. }
  897.                 else tdsdump_log(TDS_DBG_INFO1, "%L Setting 'tmp_port' to %s as a guess.n",tmp_port);
  898. /*
  899. * lookup the host and service
  900. */
  901. lookup_host(server, tmp_port, ip_addr, ip_port);
  902. }
  903. return ip_addr[0]!='' && ip_port[0]!='';
  904. } /* get_server_info()  */
  905. /**
  906.  * Check the server name to find port info first
  907.  * return 1 when found, else 0
  908.  * Warning: config-> & login-> are all modified when needed
  909.  */
  910. static int parse_server_name_for_port( TDSCONFIGINFO *config, TDSLOGIN *login )
  911. {
  912.     char *pSep, *pEnd;
  913.         
  914.     if( ! login->server_name )
  915.         return 0;/* FALSE */
  916.     
  917.     /* seek the ':' in login server_name */
  918.     pEnd = login->server_name + strlen( login->server_name );
  919.     for( pSep = login->server_name; pSep < pEnd; pSep ++ )
  920.         if( *pSep == ':' ) break;
  921.     
  922.     if(( pSep < pEnd )&&( pSep != login->server_name ))/* yes, i found it! */
  923.     {
  924.         if( config->server_name ) free( config->server_name );
  925.         config->server_name = strdup( login->server_name );
  926.         
  927.         /* modify config-> && login->server_name & ->port */
  928. #ifdef NCBI_FTDS
  929.         login->port = config->port[0] = atoi( pSep + 1 );
  930. #else
  931.         login->port = config->port = atoi( pSep + 1 );
  932. #endif
  933.         config->server_name[pSep - login->server_name] = 0;/* end the server_name before the ':' */
  934.         *pSep = 0;
  935.         /* config->ip_addr needed */
  936.         {
  937.             char tmp[256];
  938.             lookup_host (config->server_name, NULL, tmp, NULL);
  939. #ifdef NCBI_FTDS
  940.             if (config->ip_addr[0])
  941.                     free (config->ip_addr[0]);
  942.             config->ip_addr[0] = strdup (tmp);
  943. #else
  944.             if (config->ip_addr)
  945.                     free (config->ip_addr);
  946.             config->ip_addr = strdup (tmp);
  947. #endif
  948.         }
  949.         return 1;/* TRUE */
  950.     }
  951.     else
  952.         return 0;/* FALSE */
  953. }