static void unescapeHostPathQuery(const char *const host, const char *const path, const char *const query, const char **const hostP, const char **const pathP, const char **const queryP, const char **const errorP) { /*---------------------------------------------------------------------------- Unescape each of the four components of a URI. Each may be NULL, in which case we return NULL. -----------------------------------------------------------------------------*/ if (host) unescapeUri(host, hostP, errorP); else *hostP = NULL; if (!*errorP) { if (path) unescapeUri(path, pathP, errorP); else *pathP = NULL; if (!*errorP) { if (query) unescapeUri(query, queryP, errorP); else *queryP = NULL; if (*errorP) xmlrpc_strfree(*pathP); } else { if (*hostP) xmlrpc_strfree(*hostP); } } }
abyss_bool HandleTime(TSession *r) { char z[50]; time_t ltime; TDate date; const char * dateString; const char * answer; if (strcmp(r->uri,"/time")!=0) return FALSE; if (!RequestAuth(r,"Mot de passe","moez","hello")) return TRUE; time(<ime); DateFromGMT(&date, ltime); DateToString(&date, &dateString); xmlrpc_asprintf(&answer, "The time is %s", dateString); Answer(r, 200, answer); xmlrpc_strfree(dateString); xmlrpc_strfree(answer); return TRUE; }
static void sendHeader(TConn * const connP, TTable const fields) { /*---------------------------------------------------------------------------- Send the HTTP response header whose fields are fields[]. Don't include the blank line that separates the header from the body. fields[] contains syntactically valid HTTP header field names and values. But to the extent that int contains undefined field names or semantically invalid values, the header we send is invalid. -----------------------------------------------------------------------------*/ unsigned int i; for (i = 0; i < fields.size; ++i) { TTableItem * const fieldP = &fields.item[i]; const char * const fieldValue = formatFieldValue(fieldP->value); const char * line; xmlrpc_asprintf(&line, "%s: %s\r\n", fieldP->name, fieldValue); ConnWrite(connP, line, strlen(line)); xmlrpc_strfree(line); xmlrpc_strfree(fieldValue); } }
bool RequestAuth(TSession * const sessionP, const char * const credential, const char * const user, const char * const pass) { /*---------------------------------------------------------------------------- Authenticate requester, in a very simplistic fashion. If the request executing on session *sessionP specifies basic authentication (via Authorization header) with username 'user', password 'pass', then return TRUE. Else, return FALSE and set up an authorization failure response (HTTP response status 401) that says user must supply an identity in the 'credential' domain. When we return TRUE, we also set the username in the request info for the session to 'user' so that a future SessionGetRequestInfo can get it. -----------------------------------------------------------------------------*/ bool authorized; char * authHdrPtr; authHdrPtr = RequestHeaderValue(sessionP, "authorization"); if (authHdrPtr) { const char * authType; NextToken((const char **)&authHdrPtr); GetTokenConst(&authHdrPtr, &authType); authType = GetToken(&authHdrPtr); if (authType) { if (xmlrpc_strcaseeq(authType, "basic")) { const char * userPass; char userPassEncoded[80]; NextToken((const char **)&authHdrPtr); xmlrpc_asprintf(&userPass, "%s:%s", user, pass); xmlrpc_base64Encode(userPass, userPassEncoded); xmlrpc_strfree(userPass); if (xmlrpc_streq(authHdrPtr, userPassEncoded)) { sessionP->requestInfo.user = strdup(user); authorized = TRUE; } else authorized = FALSE; } else authorized = FALSE; } else authorized = FALSE; } else authorized = FALSE; if (!authorized) { const char * hdrValue; xmlrpc_asprintf(&hdrValue, "Basic realm=\"%s\"", credential); ResponseAddField(sessionP, "WWW-Authenticate", hdrValue); xmlrpc_strfree(hdrValue); ResponseStatus(sessionP, 401); } return authorized; }
void ServerFree(TServer * const serverP) { struct _TServer * const srvP = serverP->srvP; if (srvP->weCreatedListenSocket) SocketDestroy(srvP->listenSocketP); xmlrpc_strfree(srvP->name); xmlrpc_strfree(srvP->filespath); ListFree(&srvP->defaultfilenames); terminateHandlers(&srvP->handlers); ListFree(&srvP->handlers); logClose(srvP); if (srvP->logfilename) xmlrpc_strfree(srvP->logfilename); free(srvP); }
static void handleDirectory(TSession *const sessionP, const char *const dirName, time_t const fileModTime, MIMEType *const mimeTypeP) { bool text; bool ascending; uint16_t sort; /* 1=by name, 2=by date */ const char *error; determineSortType(sessionP->requestInfo.query, &ascending, &sort, &text, &error); if (error) { ResponseStatus(sessionP, 400); xmlrpc_strfree(error); } else if (notRecentlyModified(sessionP, fileModTime)) { ResponseStatus(sessionP, 304); ResponseWriteStart(sessionP); } else { TPool pool; bool succeeded; succeeded = PoolCreate(&pool, 1024); if (!succeeded) ResponseStatus(sessionP, 500); else { TList list; uint16_t responseStatus; const char *error; generateListing(&list, dirName, sessionP->requestInfo.uri, &pool, &error, &responseStatus); if (error) { ResponseStatus(sessionP, responseStatus); xmlrpc_strfree(error); } else { ResponseStatus(sessionP, 200); ResponseContentType(sessionP, text ? "text/plain" : "text/html"); addLastModifiedHeader(sessionP, fileModTime); ResponseChunked(sessionP); ResponseWriteStart(sessionP); if (sessionP->requestInfo.method != m_head) sendDirectoryDocument(&list, ascending, sort, text, sessionP->requestInfo.uri, mimeTypeP, sessionP); HTTPWriteEndChunk(sessionP); ListFree(&list); } PoolFree(&pool); } } }
static void createServerBare(xmlrpc_env * const envP, const xmlrpc_server_abyss_parms * const parmsP, unsigned int const parmSize, TServer * const serverP, TChanSwitch ** const chanSwitchPP) { /*---------------------------------------------------------------------------- Create a bare server. It will need further setup before it is ready to use. -----------------------------------------------------------------------------*/ bool socketBound; const struct sockaddr * sockAddrP; socklen_t sockAddrLen; unsigned int portNumber; TOsSocket socketFd; const char * logFileName; extractServerCreateParms(envP, parmsP, parmSize, &socketBound, &sockAddrP, &sockAddrLen, &portNumber, &socketFd, &logFileName); if (!envP->fault_occurred) { TChanSwitch * chanSwitchP; if (socketBound) createChanSwitchOsSocket(envP, socketFd, &chanSwitchP); else { if (sockAddrP) createChanSwitchSockAddr(envP, sockAddrP, sockAddrLen, &chanSwitchP); else createChanSwitchIpv4Port(envP, portNumber, &chanSwitchP); } if (!envP->fault_occurred) { const char * error; ServerCreateSwitch(serverP, chanSwitchP, &error); if (error) { xmlrpc_faultf(envP, "Abyss failed to create server. %s", error); xmlrpc_strfree(error); } else { *chanSwitchPP = chanSwitchP; ServerSetName(serverP, "XmlRpcServer"); if (logFileName) ServerSetLogFileName(serverP, logFileName); } if (envP->fault_occurred) ChanSwitchDestroy(chanSwitchP); } if (logFileName) xmlrpc_strfree(logFileName); } }
static void freeRequestInfo(TRequestInfo * const requestInfoP) { if (requestInfoP->requestline) xmlrpc_strfree(requestInfoP->requestline); if (requestInfoP->user) xmlrpc_strfree(requestInfoP->user); }
static void unescapeUri(const char * const uriComponent, const char ** const unescapedP, const char ** const errorP) { /*---------------------------------------------------------------------------- Unescape a component of a URI, e.g. the host name. That component may have %HH encoding, especially of characters that are delimiters within a URI like slash and colon. Return the unescaped version as *unescapedP in newly malloced storage. -----------------------------------------------------------------------------*/ char * buffer; buffer = strdup(uriComponent); if (!buffer) xmlrpc_asprintf(errorP, "Couldn't get memory for URI unescape buffer"); else { const char * src; char * dst; src = dst = buffer; *errorP = NULL; /* initial value */ while (*src && !*errorP) { switch (*src) { case '%': { char unescaped; const char * error; parsePerCentEscape(&src, &unescaped, &error); if (error) { xmlrpc_asprintf(errorP, "Invalid %%HH escape sequence. %s", error); xmlrpc_strfree(error); } else *dst++ = unescaped; } break; default: *dst++ = *src++; break; } } *dst = '\0'; if (*errorP) xmlrpc_strfree(buffer); else *unescapedP = buffer; } }
static void freeRequestInfo(TRequestInfo * const requestInfoP) { xmlrpc_strfreenull(requestInfoP->host); xmlrpc_strfreenull(requestInfoP->user); xmlrpc_strfree(requestInfoP->uri); xmlrpc_strfree(requestInfoP->requestline); }
static void releaseDecomposition(const struct decompTreeNode * const decompRootP, bool const oldstyleMemMgmt) { /*---------------------------------------------------------------------------- Assuming that Caller has decomposed something according to 'decompRootP', release whatever resources the decomposed information occupies. E.g. if it's an XML-RPC string, Caller would have allocated memory for the C string that represents the decomposed value of XML-RPC string, and we release that memory. -----------------------------------------------------------------------------*/ switch (decompRootP->formatSpecChar) { case 'i': case 'b': case 'd': case 'n': case 'I': case 't': case 'p': /* Nothing was allocated; nothing to release */ break; case '8': xmlrpc_strfree(*decompRootP->store.Tdatetime8.valueP); break; case 's': xmlrpc_strfree(*decompRootP->store.Tstring.valueP); break; case 'w': free((void*)*decompRootP->store.TwideString.valueP); break; case '6': free((void*)*decompRootP->store.TbitString.valueP); break; case 'V': xmlrpc_DECREF(*decompRootP->store.Tvalue.valueP); break; case 'A': xmlrpc_DECREF(*decompRootP->store.TarrayVal.valueP); break; case 'S': xmlrpc_DECREF(*decompRootP->store.TstructVal.valueP); break; case '(': releaseDecompArray(decompRootP->store.Tarray, oldstyleMemMgmt); break; case '{': releaseDecompStruct(decompRootP->store.Tstruct, oldstyleMemMgmt); break; } }
void ServerInit2(TServer * const serverP, const char ** const errorP) { /*---------------------------------------------------------------------------- Initialize a server to accept connections. Do not confuse this with creating the server -- ServerCreate(). Not necessary or valid with a server that doesn't accept connections (i.e. user supplies the channels (TCP connections)). -----------------------------------------------------------------------------*/ struct _TServer * const srvP = serverP->srvP; if (!srvP->serverAcceptsConnections) xmlrpc_asprintf(errorP, "ServerInit() is not valid on a server that doesn't " "accept connections " "(i.e. created with ServerCreateNoAccept)"); else { *errorP = NULL; /* initial value */ if (!srvP->chanSwitchP) { const char * error; createChanSwitch(srvP, &error); if (error) { xmlrpc_asprintf(errorP, "Unable to create a channel switch " "for the server. %s", error); xmlrpc_strfree(error); } } if (!*errorP) { const char * error; assert(srvP->chanSwitchP); ChanSwitchListen(srvP->chanSwitchP, srvP->maxConnBacklog, &error); if (error) { xmlrpc_asprintf(errorP, "Failed to listen on bound socket. %s", error); xmlrpc_strfree(error); } } } }
abyss_bool ServerCreateSocket(TServer * const serverP, const char * const name, TOsSocket const socketFd, const char * const filesPath, const char * const logFileName) { abyss_bool success; TSocket * socketP; createSocketFromOsSocket(socketFd, &socketP); if (socketP) { abyss_bool const noAcceptFalse = FALSE; const char * error; createServer(&serverP->srvP, noAcceptFalse, socketP, 0, &error); if (error) { TraceMsg(error); success = FALSE; xmlrpc_strfree(error); } else { success = TRUE; setNamePathLog(serverP, name, filesPath, logFileName); } } else success = FALSE; return success; }
abyss_bool SessionLog(TSession * const sessionP) { abyss_bool retval; if (!sessionP->validRequest) retval = FALSE; else { const char * const user = sessionP->request_info.user; const char * logline; char date[30]; DateToLogString(&sessionP->date, date); xmlrpc_asprintf(&logline, "%d.%d.%d.%d - %s - [%s] \"%s\" %d %d", IPB1(sessionP->conn->peerip), IPB2(sessionP->conn->peerip), IPB3(sessionP->conn->peerip), IPB4(sessionP->conn->peerip), user ? user : "", date, sessionP->request_info.requestline, sessionP->status, sessionP->conn->outbytes ); if (logline) { LogWrite(sessionP->conn->server, logline); xmlrpc_strfree(logline); } retval = TRUE; } return retval; }
void curlMulti_addHandle(xmlrpc_env * const envP, curlMulti * const curlMultiP, CURL * const curlSessionP) { CURLMcode rc; curlMultiP->lockP->acquire(curlMultiP->lockP); rc = curl_multi_add_handle(curlMultiP->curlMultiP, curlSessionP); curlMultiP->lockP->release(curlMultiP->lockP); /* Old libcurl (e.g. 7.12) actually returns CURLM_CALL_MULTI_PERFORM (by design) when it succeeds. Current libcurl returns CURLM_OK. */ if (rc != CURLM_OK && rc != CURLM_CALL_MULTI_PERFORM) { const char * reason; interpretCurlMultiError(&reason, rc); xmlrpc_faultf(envP, "Could not add Curl session to the " "curl multi manager. curl_multi_add_handle() " "failed: %s", reason); xmlrpc_strfree(reason); } }
abyss_bool ServerCreate(TServer * const serverP, const char * const name, uint16_t const portNumber, const char * const filesPath, const char * const logFileName) { abyss_bool const noAcceptFalse = FALSE; abyss_bool success; const char * error; createServer(&serverP->srvP, noAcceptFalse, NULL, portNumber, &error); if (error) { TraceMsg(error); xmlrpc_strfree(error); success = FALSE; } else { success = TRUE; setNamePathLog(serverP, name, filesPath, logFileName); } return success; }
void HandlerSetFilesPath(BIHandler *const handlerP, const char *const filesPath) { xmlrpc_strfree(handlerP->filesPath); handlerP->filesPath = strdup(filesPath); }
static void copyServerInfoContent(xmlrpc_env * const envP, xmlrpc_server_info * const dstP, const xmlrpc_server_info * const srcP) { dstP->serverUrl = strdup(srcP->serverUrl); if (dstP->serverUrl == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for server URL"); else { copyUserNamePw(envP, srcP->userNamePw, &dstP->userNamePw); if (!envP->fault_occurred) { copyBasicAuthHdrValue(envP, srcP->basicAuthHdrValue, &dstP->basicAuthHdrValue); if (!envP->fault_occurred) { dstP->allowedAuth.basic = srcP->allowedAuth.basic; dstP->allowedAuth.digest = srcP->allowedAuth.digest; dstP->allowedAuth.gssnegotiate = srcP->allowedAuth.gssnegotiate; dstP->allowedAuth.ntlm = srcP->allowedAuth.ntlm; if (envP->fault_occurred) freeIfNonNull(dstP->basicAuthHdrValue); } if (envP->fault_occurred) freeIfNonNull(dstP->userNamePw); } if (envP->fault_occurred) xmlrpc_strfree(dstP->serverUrl); } }
xmlrpc_server_info * xmlrpc_server_info_new(xmlrpc_env * const envP, const char * const serverUrl) { xmlrpc_server_info * serverInfoP; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT_PTR_OK(serverUrl); MALLOCVAR(serverInfoP); if (serverInfoP == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for xmlrpc_server_info"); else { serverInfoP->serverUrl = strdup(serverUrl); if (serverInfoP->serverUrl == NULL) xmlrpc_faultf(envP, "Couldn't allocate memory for server URL"); else { serverInfoP->allowedAuth.basic = false; serverInfoP->allowedAuth.digest = false; serverInfoP->allowedAuth.gssnegotiate = false; serverInfoP->allowedAuth.ntlm = false; serverInfoP->userNamePw = NULL; serverInfoP->basicAuthHdrValue = NULL; if (envP->fault_occurred) xmlrpc_strfree(serverInfoP->serverUrl); } if (envP->fault_occurred) free(serverInfoP); } return serverInfoP; }
void RequestRead(TSession * const sessionP, uint32_t const timeout, const char ** const errorP, uint16_t * const httpErrorCodeP) { /*---------------------------------------------------------------------------- Read the headers of a new HTTP request (assuming nothing has yet been read on the session). Update *sessionP with the information from the headers. Leave the connection positioned to the body of the request, ready to be read by an HTTP request handler (via SessionRefillBuffer() and SessionGetReadData()). -----------------------------------------------------------------------------*/ time_t const deadline = time(NULL) + timeout; uint16_t httpErrorCode; /* zero for no error */ char * requestLine; /* In connection;s internal buffer */ readRequestHeader(sessionP, deadline, &requestLine, &httpErrorCode); if (httpErrorCode) { xmlrpc_asprintf(errorP, "Problem getting the request header"); *httpErrorCodeP = httpErrorCode; } else { TMethod httpMethod; const char * host; const char * path; const char * query; unsigned short port; bool moreHeaders; parseRequestLine(requestLine, &httpMethod, &sessionP->version, &host, &port, &path, &query, &moreHeaders, &httpErrorCode); if (httpErrorCode) { xmlrpc_asprintf(errorP, "Unable to parse the request header " "'%s'", requestLine); *httpErrorCodeP = httpErrorCode; } else { initRequestInfo(&sessionP->requestInfo, sessionP->version, requestLine, httpMethod, host, port, path, query); if (moreHeaders) { readAndProcessHeaders(sessionP, deadline, errorP, httpErrorCodeP); } else *errorP = NULL; if (!*errorP) sessionP->validRequest = true; xmlrpc_strfreenull(host); xmlrpc_strfree(path); xmlrpc_strfreenull(query); } } }
static void makeThread(TConn * const connectionP, enum abyss_foreback const foregroundBackground, abyss_bool const useSigchld, const char ** const errorP) { switch (foregroundBackground) { case ABYSS_FOREGROUND: connectionP->hasOwnThread = FALSE; *errorP = NULL; break; case ABYSS_BACKGROUND: { const char * error; connectionP->hasOwnThread = TRUE; ThreadCreate(&connectionP->threadP, connectionP, &connJob, &threadDone, useSigchld, &error); if (error) { xmlrpc_asprintf(errorP, "Unable to create thread to " "process connection. %s", error); xmlrpc_strfree(error); } else *errorP = NULL; } break; } /* switch */ }
void xml_element_free(xml_element * const elemP) { /*---------------------------------------------------------------------------- Blow away an existing element & all of its child elements. -----------------------------------------------------------------------------*/ xmlrpc_mem_block * children; unsigned int size; unsigned int i; xml_element ** contents; XMLRPC_ASSERT_ELEM_OK(elemP); xmlrpc_strfree(elemP->name); elemP->name = XMLRPC_BAD_POINTER; xmlrpc_mem_block_clean(&elemP->cdata); /* Deallocate all of our children recursively. */ children = &elemP->children; contents = XMLRPC_TYPED_MEM_BLOCK_CONTENTS(xml_element *, children); size = XMLRPC_TYPED_MEM_BLOCK_SIZE(xml_element *, children); for (i = 0; i < size; ++i) xml_element_free(contents[i]); xmlrpc_mem_block_clean(&elemP->children); free(elemP); }
xmlrpc_value * xmlrpc_parse_response(xmlrpc_env * const envP, const char * const xmlData, size_t const xmlDataLen) { /*---------------------------------------------------------------------------- This exists for backward compatibility. It is like xmlrpc_parse_response2(), except that it merges the concepts of a failed RPC and an error in executing the RPC. -----------------------------------------------------------------------------*/ xmlrpc_value * retval; xmlrpc_value * result; const char * faultString; int faultCode; xmlrpc_parse_response2(envP, xmlData, xmlDataLen, &result, &faultCode, &faultString); if (envP->fault_occurred) retval = NULL; else { if (faultString) { xmlrpc_env_set_fault(envP, faultCode, faultString); xmlrpc_strfree(faultString); retval = NULL; } else retval = result; /* transfer reference */ } return retval; }
void SocketUnixCreateFd(int const fd, TSocket ** const socketPP) { TSocket * socketP; const char * error; if (connected(fd)) { TChannel * channelP; struct abyss_unix_chaninfo * channelInfoP; ChannelUnixCreateFd(fd, &channelP, &channelInfoP, &error); if (!error) SocketCreateChannel(channelP, channelInfoP, &socketP); } else { TChanSwitch * chanSwitchP; ChanSwitchUnixCreateFd(fd, &chanSwitchP, &error); if (!error) SocketCreateChanSwitch(chanSwitchP, &socketP); } if (error) { *socketPP = NULL; xmlrpc_strfree(error); } else *socketPP = socketP; }
static void setParseErr(xmlrpc_env * const envP, Tokenizer * const tokP, const char * const format, ...) { struct docPosition const pos = currentDocumentPosition(tokP); va_list args; const char * msg; XMLRPC_ASSERT(envP != NULL); XMLRPC_ASSERT(format != NULL); va_start(args, format); xmlrpc_vasprintf(&msg, format, args); xmlrpc_env_set_fault_formatted( envP, XMLRPC_PARSE_ERROR, "JSON parse error at Line %u, Column %u: %s", pos.lineNum, pos.colNum, msg); xmlrpc_strfree(msg); va_end(args); }
abyss_bool ServerCreateNoAccept(TServer * const serverP, const char * const name, const char * const filesPath, const char * const logFileName) { bool const noAcceptTrue = TRUE; bool const userChanSwitchFalse = FALSE; bool success; const char * error; createServer(&serverP->srvP, noAcceptTrue, NULL, userChanSwitchFalse, 0, &error); if (error) { TraceMsg(error); success = FALSE; xmlrpc_strfree(error); } else { success = TRUE; setNamePathLog(serverP, name, filesPath, logFileName); } return success; }
static void traceBuffer(const char * const label, const unsigned char * const buffer, unsigned int const size) { const char * const buffer_t = (const char *)buffer; size_t cursor; /* Index into buffer[] */ fprintf(stderr, "%s:\n\n", label); for (cursor = 0; cursor < size; ) { /* Print one line of buffer */ size_t const lineSize = nextLineSize(buffer_t, cursor, size); const char * const printableLine = xmlrpc_makePrintable_lp(&buffer_t[cursor], lineSize); fprintf(stderr, "%s\n", printableLine); cursor += lineSize; xmlrpc_strfree(printableLine); } fprintf(stderr, "\n"); }
static void createServer(xmlrpc_env * const envP, const xmlrpc_server_abyss_parms * const parmsP, unsigned int const parmSize, TServer * const abyssServerP, TChanSwitch ** const chanSwitchPP) { createServerBare(envP, parmsP, parmSize, abyssServerP, chanSwitchPP); if (!envP->fault_occurred) { const char * error; setAdditionalServerParms(parmsP, parmSize, abyssServerP); setHandlersRegistry(abyssServerP, uriPathParm(parmsP, parmSize), parmsP->registryP, chunkResponseParm(parmsP, parmSize), allowOriginParm(parmsP, parmSize), expiresParm(parmsP, parmSize), maxAgeParm(parmsP, parmSize)); ServerInit2(abyssServerP, &error); if (error) { xmlrpc_faultf(envP, error); xmlrpc_strfree(error); } } }
void xmlrpc_server_info_set_user(xmlrpc_env * const envP, xmlrpc_server_info * const serverInfoP, const char * const username, const char * const password) { const char * userNamePw; xmlrpc_mem_block * userNamePw64; XMLRPC_ASSERT_ENV_OK(envP); XMLRPC_ASSERT_PTR_OK(serverInfoP); XMLRPC_ASSERT_PTR_OK(username); XMLRPC_ASSERT_PTR_OK(password); xmlrpc_asprintf(&userNamePw, "%s:%s", username, password); userNamePw64 = xmlrpc_base64_encode_without_newlines(envP, (unsigned char*) userNamePw, strlen(userNamePw)); if (!envP->fault_occurred) { const char * const data = XMLRPC_MEMBLOCK_CONTENTS(char, userNamePw64); size_t const len = XMLRPC_MEMBLOCK_SIZE(char, userNamePw64); const char * const authType = "Basic "; char * hdrValue; hdrValue = malloc(strlen(authType) + len + 1); if (hdrValue == NULL) xmlrpc_faultf(envP, "Could not allocate memory to store " "authorization header value."); else { strcpy(hdrValue, authType); strncat(hdrValue, data, len); if (serverInfoP->basicAuthHdrValue) xmlrpc_strfree(serverInfoP->basicAuthHdrValue); serverInfoP->basicAuthHdrValue = hdrValue; } XMLRPC_MEMBLOCK_FREE(char, userNamePw64); } if (serverInfoP->userNamePw) xmlrpc_strfree(serverInfoP->userNamePw); serverInfoP->userNamePw = userNamePw; }
void ServerSetName(TServer * const serverP, const char * const name) { xmlrpc_strfree(serverP->srvP->name); serverP->srvP->name = strdup(name); }