BOOL INSTAPI SQLRemoveDriver (LPCSTR lpszDriver, BOOL fRemoveDSN, LPDWORD lpdwUsageCount) { /*char *szDriverFile = NULL; */ BOOL retcode = FALSE; PCONFIG pCfg = NULL, pInstCfg = NULL; LPSTR entries = (LPSTR) malloc (sizeof (char) * 65535), curr; int len = 0, i = 0; /* Check input parameters */ CLEAR_ERROR (); if (!lpszDriver || !STRLEN (lpszDriver)) { PUSH_ERROR (ODBC_ERROR_INVALID_NAME); goto quit; } /* Else go through user/system odbcinst.ini */ switch (configMode) { case ODBC_BOTH_DSN: case ODBC_USER_DSN: wSystemDSN = USERDSN_ONLY; break; case ODBC_SYSTEM_DSN: wSystemDSN = SYSTEMDSN_ONLY; break; } if (_iodbcdm_cfg_search_init (&pCfg, "odbc.ini", FALSE)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } if (_iodbcdm_cfg_search_init (&pInstCfg, "odbcinst.ini", FALSE)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } if (fRemoveDSN) { #ifdef WIN32 if (entries && (len = _iodbcdm_list_entries (pCfg, "ODBC 32 bit Data Sources", entries, 65535))) #else if (entries && (len = _iodbcdm_list_entries (pCfg, "ODBC Data Sources", entries, 65535))) #endif { for (curr = entries; i < len; i += (STRLEN (curr) + 1), curr += (STRLEN (curr) + 1)) { int nCursor = pCfg->cursor; if (_iodbcdm_cfg_rewind (pCfg)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } #ifdef WIN32 if (_iodbcdm_cfg_find (pCfg, "ODBC 32 bit Data Sources", curr)) #else if (_iodbcdm_cfg_find (pCfg, "ODBC Data Sources", curr)) #endif { if (_iodbcdm_cfg_rewind (pCfg)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } pCfg->cursor = nCursor; continue; } if (!strcmp (pCfg->value, lpszDriver)) { if (_iodbcdm_cfg_write (pCfg, curr, NULL, NULL)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } #ifdef WIN32 if (_iodbcdm_cfg_write (pCfg, "ODBC 32 bit Data Sources", curr, NULL)) #else if (_iodbcdm_cfg_write (pCfg, "ODBC Data Sources", curr, NULL)) #endif { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } } pCfg->cursor = nCursor; } } } if (_iodbcdm_cfg_write (pInstCfg, (char *) lpszDriver, NULL, NULL)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } #ifdef WIN32 if (_iodbcdm_cfg_write (pInstCfg, "ODBC 32 bit Drivers", lpszDriver, NULL)) #else if (_iodbcdm_cfg_write (pInstCfg, "ODBC Drivers", (LPSTR) lpszDriver, NULL)) #endif { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } if (_iodbcdm_cfg_commit (pCfg) || _iodbcdm_cfg_commit (pInstCfg)) { PUSH_ERROR (ODBC_ERROR_GENERAL_ERR); goto done; } retcode = TRUE; done: if (pCfg) _iodbcdm_cfg_done (pCfg); if (pInstCfg) _iodbcdm_cfg_done (pInstCfg); if (entries) free (entries); quit: wSystemDSN = USERDSN_ONLY; configMode = ODBC_BOTH_DSN; return retcode; }
static int _fix_home_odbc(PCONFIG pconf, char *lib_odbcini, int bIsInst) { char pathbuf[1024]; char *home_odbcini = _getinifilename (pathbuf, sizeof (pathbuf), bIsInst, TRUE); if (home_odbcini && lib_odbcini) { PCONFIG pCfg = NULL; stat_t home_stat; stat_t lib_stat; if (access(home_odbcini, R_OK)!=0) { symlink(lib_odbcini, home_odbcini); return 0; } else { char buf[4096]; int rc; if (stat(home_odbcini, &home_stat)) return -1; /* * if $HOME/.odbc[inst].ini is link * to $HOME/Library/ODBC/odbc[inst].ini */ if ((home_stat.st_mode & S_IFLNK) && (rc = readlink(home_odbcini, buf, sizeof(buf)))>0) { buf[rc]=0; if (strcmp(buf,lib_odbcini)==0) return 0; /* OK $HOME/.odbc.ini is linked to odbc.ini */ } if (stat(lib_odbcini, &lib_stat)) return -1; /* if $HOME/Library/ODBC/odbc[inst].ini is link * to $HOME/.odbc[inst].ini */ if ((lib_stat.st_mode & S_IFLNK) && (rc = readlink(lib_odbcini, buf, sizeof(buf)))>0) { buf[rc]=0; if (strcmp(buf,home_odbcini)==0) return 0; /* OK $HOME/.odbc.ini is linked to odbc.ini */ } } /* * import $HOME/.odbc[inst].ini and replace it with link * to $HOME/Library/ODBC/odbc[inst].ini */ if (!_iodbcdm_cfg_init (&pCfg, home_odbcini, FALSE)) { int len = 0; char root_buf[4096] = {0}; char *proot; char *root_val = NULL; int was_error = FALSE; char *root_lst = bIsInst?DRV_LST:DSN_LST; /* Move DSN/Driver list*/ len = _iodbcdm_list_entries (pCfg, root_lst, root_buf, sizeof(root_buf)); if (len >0) { /* move [ODBC Data Sources] section */ for(proot = root_buf; *proot; proot += STRLEN(proot) + 1) { if (!_iodbcdm_cfg_find (pCfg, root_lst, proot)) root_val = pCfg->value; else root_val = NULL; if (!proot || !root_val) continue; if (_iodbcdm_cfg_write (pconf, root_lst, proot, root_val) || _iodbcdm_cfg_commit (pconf)) { was_error = TRUE; break; } } /* move DSN defines */ for(proot = root_buf; *proot; proot += STRLEN(proot) + 1) { char buffer[4096]; char *pattr; char *pattr_val; len = _iodbcdm_list_entries (pCfg, proot, buffer, sizeof(buffer)); if (len>0) { /* move [DSN] description */ for(pattr = buffer; *pattr; pattr += STRLEN(pattr) + 1) { if (!_iodbcdm_cfg_find (pCfg, proot, pattr)) pattr_val = pCfg->value; else pattr_val = NULL; if (!pattr || !pattr_val) continue; if (_iodbcdm_cfg_write (pconf, proot, pattr, pattr_val) || _iodbcdm_cfg_commit (pconf)) { was_error = TRUE; break; } } } } } if (was_error) return -1; } /* make link */ if (access(home_odbcini, R_OK)==0) { if (unlink(home_odbcini)) return -1; } if (symlink(lib_odbcini, home_odbcini)) return -1; } return 0; }