/* Editor Settings: expandtabs and use 4 spaces for indentation * ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: * * -*- mode: c, c-basic-offset: 4 -*- */ /* * Copyright Likewise Software 2004-2008 * All rights reserved. * * This library is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation; either version 2.1 of the license, or (at * your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * General Public License for more details. You should have received a copy * of the GNU Lesser General Public License along with this program. If * not, see . * * LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING * TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT * WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE * TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU * LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU * HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING * TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT * license@likewisesoftware.com */ #include "domainjoin.h" #include "djparsehosts.h" #if defined(__LWI_MACOSX__) static CENTERROR RunSilentWithStatus( PCSTR Command, PSTR* Args, PLONG Status ) { CENTERROR ceError = CENTERROR_SUCCESS; int EE = 0; LONG status = 0; PPROCINFO procInfo = NULL; ceError = DJSpawnProcessSilent(Command, Args, &procInfo); GOTO_CLEANUP_ON_CENTERROR_EE(ceError, EE); ceError = DJGetProcessStatus(procInfo, &status); GOTO_CLEANUP_ON_CENTERROR_EE(ceError, EE); cleanup: if (procInfo) { FreeProcInfo(procInfo); } *Status = status; if (EE || ceError) { DJ_LOG_VERBOSE("RunSiledWithStatus LEAVE -> 0x%08x (EE = %d)", ceError, EE); } return ceError; } static void KickLookupd( ) { CENTERROR ceError = CENTERROR_SUCCESS; int EE = 0; char stopCommand[] = "/usr/bin/killall"; PSTR stopArgs[3] = { stopCommand, "lookupd" }; #if 0 char startCommand[] = "/usr/sbin/lookupd"; PSTR startArgs[2] = { startCommand }; #endif LONG status = 0; ceError = RunSilentWithStatus(stopCommand, stopArgs, &status); GOTO_CLEANUP_ON_CENTERROR_EE(ceError, EE); if (status != 0) { DJ_LOG_ERROR("%s failed [Status code: %d]", stopCommand, status); goto cleanup; } // We do not technically need to restart it since it will restart on // demand. #if 0 ceError = RunSilentWithStatus(startCommand, startArgs, &status); GOTO_CLEANUP_ON_CENTERROR_EE(ceError, EE); if (status != 0) { DJ_LOG_ERROR("%s failed [Status code: %d]", startCommand, status); } #endif cleanup: DJ_LOG_VERBOSE("KickLookupd LEAVE -> 0x%08x (EE = %d)", ceError, EE); } #endif static void DJFreeAlias( PHOSTFILEALIAS pAlias ) { if (pAlias->pszAlias) CTFreeString(pAlias->pszAlias); CTFreeMemory(pAlias); } static void DJFreeAliasList( PHOSTFILEALIAS pAliasList ) { PHOSTFILEALIAS pAlias = NULL; while (pAliasList) { pAlias = pAliasList; pAliasList = pAliasList->pNext; DJFreeAlias(pAlias); } } static void DJFreeHostsLine( PHOSTSFILELINE pHostsLine ) { PHOSTSFILEENTRY pEntry = NULL; if (pHostsLine->pszComment) CTFreeString(pHostsLine->pszComment); pEntry = pHostsLine->pEntry; if (pEntry) { DJFreeAliasList(pEntry->pAliasList); pEntry->pAliasList = NULL; if (pEntry->pszIpAddress) CTFreeString(pEntry->pszIpAddress); if (pEntry->pszCanonicalName) CTFreeString(pEntry->pszCanonicalName); CTFreeMemory(pEntry); } CTFreeMemory(pHostsLine); } static PHOSTSFILELINE * DJGetLastHostsLine( PHOSTSFILELINE *pHostsLine ) { while(*pHostsLine != NULL) { pHostsLine = &(*pHostsLine)->pNext; } return pHostsLine; } void DJFreeHostsFileLineList( PHOSTSFILELINE pHostsLineList ) { PHOSTSFILELINE pHostsLine = NULL; while (pHostsLineList) { pHostsLine = pHostsLineList; pHostsLineList = pHostsLineList->pNext; DJFreeHostsLine(pHostsLine); } } static PHOSTFILEALIAS DJReverseAliasList( PHOSTFILEALIAS pAliasList ) { PHOSTFILEALIAS pP = NULL; PHOSTFILEALIAS pQ = pAliasList; PHOSTFILEALIAS pR = NULL; while( pQ ) { pR = pQ->pNext; pQ->pNext = pP; pP = pQ; pQ = pR; } return pP; } CENTERROR DJParseHostsFile( const char *filename, PHOSTSFILELINE* ppHostsFileLineList ) { CENTERROR ceError = CENTERROR_SUCCESS; PHOSTSFILELINE pLineHead = NULL; PHOSTSFILELINE pHostsLine = NULL; PHOSTFILEALIAS pAlias = NULL; FILE* fp = NULL; CHAR szBuf[1024+1]; PSTR pszTmp = NULL; DWORD iToken = 0; PHOSTSFILELINE pLineTail = NULL; BOOLEAN exists; BAIL_ON_CENTERIS_ERROR(ceError = CTCheckFileOrLinkExists(filename, &exists)); if(!exists) BAIL_ON_CENTERIS_ERROR(ceError = CENTERROR_INVALID_FILENAME); fp = fopen(filename, "r"); if (fp == NULL) { ceError = CTMapSystemError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } while (1) { if (fgets(szBuf, 1024, fp) == NULL) { if (!feof(fp)) { ceError = CTMapSystemError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } else { break; } } CTStripWhitespace(szBuf); ceError = CTAllocateMemory(sizeof(HOSTSFILELINE), (PVOID*)(PVOID)&pHostsLine); BAIL_ON_CENTERIS_ERROR(ceError); pHostsLine->pEntry = NULL; pHostsLine->pszComment = NULL; pszTmp = strchr(szBuf, '#'); if (pszTmp != NULL) { ceError = CTAllocateString(pszTmp, &pHostsLine->pszComment); BAIL_ON_CENTERIS_ERROR(ceError); *pszTmp = '\0'; } if(szBuf[0] != '\0') { ceError = CTAllocateMemory(sizeof(HOSTSFILEENTRY), (PVOID*)(PVOID)&pHostsLine->pEntry); BAIL_ON_CENTERIS_ERROR(ceError); iToken = 0; pszTmp = strtok(szBuf, " \t"); while (pszTmp != NULL) { if (iToken == 0) { ceError = CTAllocateString(pszTmp, &pHostsLine->pEntry->pszIpAddress); BAIL_ON_CENTERIS_ERROR(ceError); } else if (iToken == 1) { ceError = CTAllocateString(pszTmp, &pHostsLine->pEntry->pszCanonicalName); BAIL_ON_CENTERIS_ERROR(ceError); } else { ceError = CTAllocateMemory(sizeof(HOSTFILEALIAS), (PVOID*)(PVOID)&pAlias); BAIL_ON_CENTERIS_ERROR(ceError); ceError = CTAllocateString(pszTmp, &pAlias->pszAlias); BAIL_ON_CENTERIS_ERROR(ceError); //The alias list is first built in reverse pAlias->pNext = pHostsLine->pEntry->pAliasList; pHostsLine->pEntry->pAliasList = pAlias; pAlias = NULL; } iToken++; pszTmp = strtok(NULL, " \t"); } if (pHostsLine->pEntry->pAliasList) { pHostsLine->pEntry->pAliasList = DJReverseAliasList(pHostsLine->pEntry->pAliasList); } } if(pLineTail != NULL) pLineTail->pNext = pHostsLine; else pLineHead = pHostsLine; pLineTail = pHostsLine; pHostsLine = NULL; } *ppHostsFileLineList = pLineHead; pLineHead = NULL; error: if (pAlias) DJFreeAlias(pAlias); if (pHostsLine) DJFreeHostsLine(pHostsLine); if (pLineHead) DJFreeHostsFileLineList(pLineHead); if (fp) fclose(fp); return ceError; } static BOOLEAN DJEntryHasAlias( PHOSTFILEALIAS pAliasList, PCSTR pszName ) { BOOLEAN bResult = FALSE; while (pAliasList) { if (pAliasList->pszAlias && !strcasecmp(pAliasList->pszAlias, pszName)) { bResult = TRUE; break; } pAliasList = pAliasList->pNext; } return bResult; } //Adds an alias to the head of the alias list static CENTERROR DJAddAlias( PHOSTSFILELINE pLine, PCSTR pszName, BOOLEAN alwaysAdd, PBOOLEAN pbAdded ) { CENTERROR ceError = CENTERROR_SUCCESS; PHOSTFILEALIAS pAlias = NULL; if (alwaysAdd || !DJEntryHasAlias(pLine->pEntry->pAliasList, pszName)) { ceError = CTAllocateMemory(sizeof(HOSTFILEALIAS), (PVOID*)(PVOID)&pAlias); BAIL_ON_CENTERIS_ERROR(ceError); ceError = CTAllocateString(pszName, &pAlias->pszAlias); BAIL_ON_CENTERIS_ERROR(ceError); pAlias->pNext = pLine->pEntry->pAliasList; pLine->pEntry->pAliasList = pAlias; pAlias = NULL; if (pbAdded != NULL) *pbAdded = TRUE; pLine->bModified = TRUE; } else if (pbAdded != NULL) { *pbAdded = FALSE; } error: if (pAlias) DJFreeAlias(pAlias); return ceError; } #if 0 // Currently unused static CENTERROR DJGetDnsDomain( PSTR pszHostname, PSTR* ppszDnsDomain ) { CENTERROR ceError = CENTERROR_SUCCESS; PSTR pszDnsDomain = NULL; PSTR pszTmp = strchr(pszHostname, '.'); if (pszTmp && *(pszTmp+1) != '\0') { ceError = CTAllocateString(pszTmp+1, &pszDnsDomain); BAIL_ON_CENTERIS_ERROR(ceError); } *ppszDnsDomain = pszDnsDomain; return ceError; error: if (pszDnsDomain) CTFreeString(pszDnsDomain); return ceError; } #endif static PHOSTSFILELINE DJFindLineByIPAddress( PHOSTSFILELINE pHostsFileLineList, PSTR pszIpAddress ) { while(pHostsFileLineList) { if (pHostsFileLineList->pEntry != NULL && !strcmp(pHostsFileLineList->pEntry->pszIpAddress, pszIpAddress)) return pHostsFileLineList; pHostsFileLineList = pHostsFileLineList->pNext; } return NULL; } BOOLEAN DJHostsFileWasModified( PHOSTSFILELINE pHostFileLineList ) { BOOLEAN bResult = FALSE; while (pHostFileLineList) { if (pHostFileLineList->bModified) { bResult = TRUE; break; } pHostFileLineList = pHostFileLineList->pNext; } return bResult; } static CENTERROR DJWriteHostsFileIfModified( const char *filename, PHOSTSFILELINE pHostFileLineList ) { CENTERROR ceError = CENTERROR_SUCCESS; PHOSTSFILELINE pLine = pHostFileLineList; FILE* fp = NULL; PHOSTFILEALIAS pAlias = NULL; BOOLEAN bRemoveFile = FALSE; char *tempName = NULL; char *finalName = NULL; ceError = CTGetFileTempPath( filename, &finalName, &tempName); BAIL_ON_CENTERIS_ERROR(ceError); if (DJHostsFileWasModified(pHostFileLineList)) { DJ_LOG_INFO("Writing out updated %s file", finalName); fp = fopen(tempName, "w"); if (fp == NULL) { ceError = CTMapSystemError(errno); BAIL_ON_CENTERIS_ERROR(ceError); } bRemoveFile = TRUE; while (pLine) { if (pLine->pEntry != NULL) { if (!IsNullOrEmptyString(pLine->pEntry->pszIpAddress)) fprintf(fp, "%s", pLine->pEntry->pszIpAddress); if (!IsNullOrEmptyString(pLine->pEntry->pszCanonicalName)) fprintf(fp, " %s", pLine->pEntry->pszCanonicalName); pAlias = pLine->pEntry->pAliasList; while (pAlias) { if (!IsNullOrEmptyString(pAlias->pszAlias)) fprintf(fp, " %s", pAlias->pszAlias); pAlias = pAlias->pNext; } if (pLine->pszComment != NULL) fprintf(fp, " %s", pLine->pszComment); fprintf(fp, "\n"); } else if(pLine->pszComment != NULL) { fprintf(fp, "%s\n", pLine->pszComment); } pLine = pLine->pNext; } if (fp) { fclose(fp); fp = NULL; } ceError = CTSafeReplaceFile(finalName, tempName); BAIL_ON_CENTERIS_ERROR(ceError); #if defined(__LWI_MACOSX__) // Work around Mac bug where lookupd sometimes fails to pick up // changes in /etc/hosts, even with -flushcache. KickLookupd(); #endif bRemoveFile = FALSE; } else DJ_LOG_INFO("%s file was not modified; not rewriting", finalName); error: if (fp) fclose(fp); if (bRemoveFile) CTRemoveFile(tempName); CT_SAFE_FREE_STRING(finalName); CT_SAFE_FREE_STRING(tempName); return ceError; } PCSTR Disp(PCSTR in) { if(in == NULL) return "(null)"; return in; } static CENTERROR DJUpdateHostEntry( PHOSTSFILELINE pLine, PCSTR pszShortName, PCSTR pszFqdnName, PCSTR pszRemoveName1, PCSTR pszRemoveName2 ) { CENTERROR ceError = CENTERROR_SUCCESS; PHOSTFILEALIAS *aliasPos; //This updates our hostname in a line of the hosts file // 1. pszFqdnName will be added as the primary name in the host entry // 2. pszShortName will be added as the first alias // 3. Whatever was previously the primary name and first alias will be // added as the second and third aliases // 4. If pszRemoveName1 and or pszRemoveName2 are not null, they will // be removed from the alias list if (pszFqdnName == NULL && pszShortName != NULL) { pszFqdnName = pszShortName; pszShortName = NULL; } else if (pszFqdnName != NULL && pszShortName != NULL && !strcasecmp(pszFqdnName, pszShortName)) { pszShortName = NULL; } DJ_LOG_INFO("Adding %s (fqdn %s) to /etc/hosts ip %s, " "removing %s, %s, %s, %s", Disp(pszShortName), Disp(pszFqdnName), Disp(pLine->pEntry->pszIpAddress), Disp(pszShortName), Disp(pszFqdnName), Disp(pszRemoveName1), Disp(pszRemoveName2)); if (pszFqdnName != NULL && (pLine->pEntry->pszCanonicalName == NULL || strcasecmp(pLine->pEntry->pszCanonicalName, pszFqdnName))) { if (pLine->pEntry->pszCanonicalName != NULL) { ceError = DJAddAlias(pLine, pLine->pEntry->pszCanonicalName, FALSE, NULL); BAIL_ON_CENTERIS_ERROR(ceError); CTFreeString(pLine->pEntry->pszCanonicalName); pLine->pEntry->pszCanonicalName = NULL; } ceError = CTAllocateString(pszFqdnName, &pLine->pEntry->pszCanonicalName); BAIL_ON_CENTERIS_ERROR(ceError); } aliasPos = &pLine->pEntry->pAliasList; if (pszShortName != NULL) { if (pLine->pEntry->pAliasList == NULL || strcasecmp(pLine->pEntry->pAliasList->pszAlias, pszShortName)) { ceError = DJAddAlias(pLine, pszShortName, TRUE, NULL); BAIL_ON_CENTERIS_ERROR(ceError); } //Skip over this so we don't delete it aliasPos = &(*aliasPos)->pNext; } { PCSTR removeStrings[] = { pszShortName, pszFqdnName, pszRemoveName1, pszRemoveName2 }; while (*aliasPos != NULL) { int i; for(i=0; ipszAlias, removeStrings[i])) { //Remove it PHOSTFILEALIAS remove = *aliasPos; (*aliasPos) = remove->pNext; DJFreeAlias(remove); pLine->bModified = TRUE; goto removed_entry; } } //Advance to the next entry because nothing was removed. aliasPos = &(*aliasPos)->pNext; removed_entry: ; } } error: return ceError; } // newFdqnHostname = . CENTERROR DJReplaceHostnameInMemory( PHOSTSFILELINE pHostsFileLineList, PCSTR oldShortHostname, PCSTR oldFqdnHostname, PCSTR shortHostname, PCSTR dnsDomainName ) { CENTERROR ceError = CENTERROR_SUCCESS; PSTR pszDomainName = NULL; PSTR pszHostName = NULL; PSTR pszCanonicalName = NULL; PHOSTSFILELINE pLine = NULL; PHOSTSFILELINE pCreatedLine = NULL; BOOLEAN bFound = FALSE; BOOLEAN bModified = FALSE; PHOSTFILEALIAS pAlias = NULL; // // Ideal algorithm: // // 1) Find any lines with hostname. // 2) Make sure the the FQDN is present as the first // name in each of those lines. // 3) If no lines were found, then add hostname to 127.0.0.1 // and put FQDN first. // 4) If 127.0.0.2 line is present, edit that to just have our info. // if (IsNullOrEmptyString(shortHostname)) { ceError = CENTERROR_INVALID_PARAMETER; BAIL_ON_CENTERIS_ERROR(ceError); } if (strchr(shortHostname, '.')) { ceError = CENTERROR_DOMAINJOIN_HOSTNAME_CONTAINS_DOT; BAIL_ON_CENTERIS_ERROR(ceError); } ceError = CTAllocateString(shortHostname, &pszHostName); BAIL_ON_CENTERIS_ERROR(ceError); CTStripWhitespace(pszHostName); CTStrToLower(pszHostName); if (dnsDomainName != NULL) { ceError = CTAllocateString(dnsDomainName, &pszDomainName); BAIL_ON_CENTERIS_ERROR(ceError); CTStripWhitespace(pszDomainName); CTStrToLower(pszDomainName); ceError = CTAllocateMemory(strlen(pszHostName)+strlen(pszDomainName)+2, (PVOID*)(PVOID)&pszCanonicalName); BAIL_ON_CENTERIS_ERROR(ceError); sprintf(pszCanonicalName, "%s.%s", pszHostName, pszDomainName); } else { ceError = CTAllocateString(pszHostName, &pszCanonicalName); BAIL_ON_CENTERIS_ERROR(ceError); } for (pLine = pHostsFileLineList; pLine; pLine = pLine->pNext) { if (pLine->pEntry != NULL) { if (pLine->pEntry->pszCanonicalName != NULL && (!strcasecmp(pLine->pEntry->pszCanonicalName, pszHostName) || !strcasecmp(pLine->pEntry->pszCanonicalName, oldShortHostname ? oldShortHostname : "") || !strcasecmp(pLine->pEntry->pszCanonicalName, oldFqdnHostname ? oldFqdnHostname : "") || !strcasecmp(pLine->pEntry->pszCanonicalName, pszCanonicalName))) { ceError = DJUpdateHostEntry( pLine, pszHostName, pszCanonicalName, oldShortHostname, oldFqdnHostname); BAIL_ON_CENTERIS_ERROR(ceError); bFound = TRUE; } else if (DJEntryHasAlias(pLine->pEntry->pAliasList, pszHostName)) { bFound = TRUE; ceError = DJUpdateHostEntry( pLine, pszHostName, pszCanonicalName, oldShortHostname, oldFqdnHostname); BAIL_ON_CENTERIS_ERROR(ceError); } } } if (!bFound) { //First try to setup ip address on the loop back device which are not //127.0.0.1 for (pLine = pHostsFileLineList; pLine; pLine = pLine->pNext) { if (pLine->pEntry != NULL && !strncmp(pLine->pEntry->pszIpAddress, "127.0.", strlen("127.0.")) && strcmp(pLine->pEntry->pszIpAddress, "127.0.0.1")) { ceError = DJUpdateHostEntry( pLine, pszHostName, pszCanonicalName, oldShortHostname, oldFqdnHostname); BAIL_ON_CENTERIS_ERROR(ceError); bFound = TRUE; } } if (!bFound) { //Have to add it to the 127.0.0.1 address pLine = DJFindLineByIPAddress(pHostsFileLineList, "127.0.0.1"); if(pLine == NULL) { //We have to create the 127.0.0.1 address ceError = CTAllocateMemory(sizeof(HOSTSFILELINE), (PVOID*)(PVOID)&pCreatedLine); BAIL_ON_CENTERIS_ERROR(ceError); ceError = CTAllocateMemory(sizeof(HOSTSFILEENTRY), (PVOID*)(PVOID)&pCreatedLine->pEntry); ceError = CTAllocateString("127.0.0.1", &pCreatedLine->pEntry->pszIpAddress); BAIL_ON_CENTERIS_ERROR(ceError); ceError = DJAddAlias(pCreatedLine, "localhost", FALSE, &bModified); BAIL_ON_CENTERIS_ERROR(ceError); *DJGetLastHostsLine(&pHostsFileLineList) = pCreatedLine; pLine = pCreatedLine; pCreatedLine = NULL; } ceError = DJUpdateHostEntry( pLine, pszHostName, pszCanonicalName, oldShortHostname, oldFqdnHostname); BAIL_ON_CENTERIS_ERROR(ceError); } } error: if (pAlias) DJFreeAlias(pAlias); if (pszHostName) CTFreeString(pszHostName); if (pszDomainName) CTFreeString(pszDomainName); if (pszCanonicalName) CTFreeMemory(pszCanonicalName); if(pCreatedLine) DJFreeHostsLine(pCreatedLine); return ceError; } CENTERROR DJCopyLine( PHOSTSFILELINE pSrc, PHOSTSFILELINE *ppDest) { PHOSTSFILELINE ret = NULL; PHOSTFILEALIAS srcAlias = NULL, *destAlias = NULL; CENTERROR ceError = CENTERROR_SUCCESS; ceError = CTAllocateMemory(sizeof(HOSTSFILELINE), (PVOID*)(PVOID)&ret); BAIL_ON_CENTERIS_ERROR(ceError); ret->bModified = pSrc->bModified; ceError = CTDupOrNullStr(pSrc->pszComment, &ret->pszComment); BAIL_ON_CENTERIS_ERROR(ceError); if(pSrc->pEntry != NULL) { ceError = CTAllocateMemory(sizeof(HOSTSFILEENTRY), (PVOID*)(PVOID)&ret->pEntry); BAIL_ON_CENTERIS_ERROR(ceError); ceError = CTDupOrNullStr(pSrc->pEntry->pszIpAddress, &ret->pEntry->pszIpAddress); BAIL_ON_CENTERIS_ERROR(ceError); ceError = CTDupOrNullStr(pSrc->pEntry->pszCanonicalName, &ret->pEntry->pszCanonicalName); BAIL_ON_CENTERIS_ERROR(ceError); srcAlias = pSrc->pEntry->pAliasList; destAlias = &ret->pEntry->pAliasList; } while(srcAlias != NULL) { ceError = CTAllocateMemory(sizeof(HOSTFILEALIAS), (PVOID*)(PVOID)destAlias); BAIL_ON_CENTERIS_ERROR(ceError); ceError = CTDupOrNullStr(srcAlias->pszAlias, &(*destAlias)->pszAlias); BAIL_ON_CENTERIS_ERROR(ceError); srcAlias = srcAlias->pNext; destAlias = &(*destAlias)->pNext; } *ppDest = ret; ret = NULL; error: if(ret != NULL) DJFreeHostsFileLineList(ret); return ceError; } CENTERROR DJCopyMissingHostsEntry( PCSTR destFile, PCSTR srcFile, PCSTR entryName1, PCSTR entryName2) { CENTERROR ceError = CENTERROR_SUCCESS; PHOSTSFILELINE pDestList = NULL; PHOSTSFILELINE pSrcList = NULL; PHOSTSFILELINE pLine = NULL; PHOSTSFILELINE pCopiedLine = NULL; ceError = DJParseHostsFile(destFile, &pDestList); BAIL_ON_CENTERIS_ERROR(ceError); ceError = DJParseHostsFile(srcFile, &pSrcList); BAIL_ON_CENTERIS_ERROR(ceError); if(entryName2 == NULL) entryName2 = ""; for (pLine = pDestList; pLine; pLine = pLine->pNext) { if (pLine->pEntry != NULL) { if ((pLine->pEntry->pszCanonicalName != NULL && (!strcasecmp(pLine->pEntry->pszCanonicalName, entryName1) || !strcasecmp(pLine->pEntry->pszCanonicalName, entryName2))) || DJEntryHasAlias(pLine->pEntry->pAliasList, entryName1) || DJEntryHasAlias(pLine->pEntry->pAliasList, entryName1)) { //The dest file already has this entry goto done; } } } for (pLine = pSrcList; pLine; pLine = pLine->pNext) { if (pLine->pEntry != NULL) { if ((pLine->pEntry->pszCanonicalName != NULL && (!strcasecmp(pLine->pEntry->pszCanonicalName, entryName1) || !strcasecmp(pLine->pEntry->pszCanonicalName, entryName2))) || DJEntryHasAlias(pLine->pEntry->pAliasList, entryName1) || DJEntryHasAlias(pLine->pEntry->pAliasList, entryName1)) { //Copy this line to dest ceError = DJCopyLine(pLine, &pCopiedLine); BAIL_ON_CENTERIS_ERROR(ceError); pCopiedLine->pNext = pDestList; pDestList = pCopiedLine; pCopiedLine->bModified = TRUE; pCopiedLine = NULL; } } } ceError = DJWriteHostsFileIfModified(destFile, pDestList); BAIL_ON_CENTERIS_ERROR(ceError); done: error: if (pDestList) DJFreeHostsFileLineList(pDestList); if (pSrcList) DJFreeHostsFileLineList(pSrcList); if (pCopiedLine) DJFreeHostsFileLineList(pCopiedLine); return ceError; } // newFdqnHostname = . CENTERROR DJReplaceNameInHostsFile( PCSTR filename, PSTR oldShortHostname, PSTR oldFqdnHostname, PSTR shortHostname, PCSTR dnsDomainName ) { CENTERROR ceError = CENTERROR_SUCCESS; PHOSTSFILELINE pHostsFileLineList = NULL; ceError = DJParseHostsFile(filename, &pHostsFileLineList); BAIL_ON_CENTERIS_ERROR(ceError); ceError = DJReplaceHostnameInMemory( pHostsFileLineList, oldShortHostname, oldFqdnHostname, shortHostname, dnsDomainName ); BAIL_ON_CENTERIS_ERROR(ceError); ceError = DJWriteHostsFileIfModified(filename, pHostsFileLineList); BAIL_ON_CENTERIS_ERROR(ceError); error: if (pHostsFileLineList) DJFreeHostsFileLineList(pHostsFileLineList); return ceError; }