Repository: trafficserver Updated Branches: refs/heads/master 93f283ef3 -> 82deca40f
Move WebMgmtUtils to libmgmt WebMgmtUtils actually has dependencies on MultiFile, so it needs to live in /mgmt so that libutils (/mgmt/utils) does not have a reverse dependency on libmgmt_lm. Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/82deca40 Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/82deca40 Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/82deca40 Branch: refs/heads/master Commit: 82deca40ff772bbe0cddd9b94cf0d9a4ae84f775 Parents: 93f283e Author: James Peach <[email protected]> Authored: Sat Aug 16 19:10:05 2014 -0700 Committer: James Peach <[email protected]> Committed: Sat Aug 16 19:12:27 2014 -0700 ---------------------------------------------------------------------- mgmt/Makefile.am | 4 +- mgmt/WebMgmtUtils.cc | 1378 +++++++++++++++++++++++++++++++++++++++ mgmt/WebMgmtUtils.h | 124 ++++ mgmt/utils/Makefile.am | 4 +- mgmt/utils/WebMgmtUtils.cc | 1378 --------------------------------------- mgmt/utils/WebMgmtUtils.h | 124 ---- 6 files changed, 1506 insertions(+), 1506 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/trafficserver/blob/82deca40/mgmt/Makefile.am ---------------------------------------------------------------------- diff --git a/mgmt/Makefile.am b/mgmt/Makefile.am index ce477e1..0c333dc 100644 --- a/mgmt/Makefile.am +++ b/mgmt/Makefile.am @@ -60,7 +60,9 @@ libmgmt_lm_la_SOURCES = \ MultiFile.cc \ MultiFile.h \ Rollback.cc \ - Rollback.h + Rollback.h \ + WebMgmtUtils.cc \ + WebMgmtUtils.h libmgmt_lm_la_LIBADD = \ cluster/libcluster.la \ http://git-wip-us.apache.org/repos/asf/trafficserver/blob/82deca40/mgmt/WebMgmtUtils.cc ---------------------------------------------------------------------- diff --git a/mgmt/WebMgmtUtils.cc b/mgmt/WebMgmtUtils.cc new file mode 100644 index 0000000..df7f6e6 --- /dev/null +++ b/mgmt/WebMgmtUtils.cc @@ -0,0 +1,1378 @@ +/** @file + + A brief file description + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#include "libts.h" +#include "LocalManager.h" +#include "MgmtUtils.h" +#include "WebMgmtUtils.h" +#include "MultiFile.h" + +#ifdef HAVE_PCRE_PCRE_H +#include <pcre/pcre.h> +#else +#include <pcre.h> +#endif + + +/**************************************************************************** + * + * WebMgmtUtils.cc - Functions for interfacing to management records + * + * + * + ****************************************************************************/ + + +// bool varSetFromStr(const char*, const char* ) +// +// Sets the named local manager variable from the value string +// passed in. Does the appropriate type conversion on +// value string to get it to the type of the local manager +// variable +// +// returns true if the variable was successfully set +// and false otherwise +// +bool +varSetFromStr(const char *varName, const char *value) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + int err = REC_ERR_FAIL; + RecData data; + + memset(&data, 0, sizeof(RecData)); + + err = RecGetRecordDataType((char *) varName, &varDataType); + if (err != REC_ERR_OKAY) { + return found; + } + // Use any empty string if we get a NULL so + // sprintf does puke. However, we need to + // switch this back to NULL for STRING types + if (value == NULL) { + value = ""; + } + + switch (varDataType) { + case RECD_INT: + if (sscanf(value, "%" PRId64 "", &data.rec_int) == 1) { + RecSetRecordInt((char *) varName, data.rec_int); + } else { + found = false; + } + break; + case RECD_COUNTER: + if (sscanf(value, "%" PRId64 "", &data.rec_counter) == 1) { + RecSetRecordCounter((char *) varName, data.rec_counter); + } else { + found = false; + } + break; + case RECD_FLOAT: + // coverity[secure_coding] + if (sscanf(value, "%f", &data.rec_float) == 1) { + RecSetRecordFloat((char *) varName, data.rec_float); + } else { + found = false; + } + break; + case RECD_STRING: + if (*value == '\0') { + RecSetRecordString((char *) varName, NULL); + } else { + RecSetRecordString((char *) varName, (char *) value); + } + break; + case RECD_NULL: + default: + found = false; + break; + } + + return found; +} + +// bool varSetFloat(const char* varName, RecFloat value) +// +// Sets the variable specifed by varName to value. varName +// must be a RecFloat variable. No conversion is done for +// other types unless convert is set to ture. In the case +// of convert is ture, type conversion is perform if applicable. +// By default, convert is set to be false and can be overrided +// when the function is called. +// +bool +varSetFloat(const char *varName, RecFloat value, bool convert) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + int err = REC_ERR_FAIL; + + err = RecGetRecordDataType((char *) varName, &varDataType); + if (err != REC_ERR_OKAY) { + return found; + } + + switch (varDataType) { + case RECD_FLOAT: + RecSetRecordFloat((char *) varName, (RecFloat) value); + break; + case RECD_INT: + if (convert) { + value += 0.5; // rounding up + RecSetRecordInt((char *) varName, (RecInt) value); + break; + } + case RECD_COUNTER: + if (convert) { + RecSetRecordCounter((char *) varName, (RecCounter) value); + break; + } + case RECD_STRING: + case RECD_NULL: + default: + found = false; + break; + } + + return found; +} + +// bool varSetCounter(const char* varName, RecCounter value) +// +// Sets the variable specifed by varName to value. varName +// must be an RecCounter variable. No conversion is done for +// other types unless convert is set to ture. In the case +// of convert is ture, type conversion is perform if applicable. +// By default, convert is set to be false and can be overrided +// when the function is called. +// +bool +varSetCounter(const char *varName, RecCounter value, bool convert) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + int err = REC_ERR_FAIL; + + err = RecGetRecordDataType((char *) varName, &varDataType); + if (err != REC_ERR_OKAY) { + return found; + } + + switch (varDataType) { + case RECD_COUNTER: + RecSetRecordCounter((char *) varName, (RecCounter) value); + break; + case RECD_INT: + if (convert) { + RecSetRecordInt((char *) varName, (RecInt) value); + break; + } + case RECD_FLOAT: + if (convert) { + RecSetRecordFloat((char *) varName, (RecFloat) value); + break; + } + case RECD_STRING: + case RECD_NULL: + default: + found = false; + break; + } + + return found; +} + +// bool varSetInt(const char* varName, RecInt value) +// +// Sets the variable specifed by varName to value. varName +// must be an RecInt variable. No conversion is done for +// other types unless convert is set to ture. In the case +// of convert is ture, type conversion is perform if applicable. +// By default, convert is set to be false and can be overrided +// when the function is called. +// +bool +varSetInt(const char *varName, RecInt value, bool convert) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + int err = REC_ERR_FAIL; + + err = RecGetRecordDataType((char *) varName, &varDataType); + if (err != REC_ERR_OKAY) { + return found; + } + + switch (varDataType) { + case RECD_INT: + RecSetRecordInt((char *) varName, (RecInt) value); + break; + case RECD_COUNTER: + if (convert) { + RecSetRecordCounter((char *) varName, (RecCounter) value); + break; + } + case RECD_FLOAT: + if (convert) { + RecSetRecordFloat((char *) varName, (RecFloat) value); + break; + } + case RECD_STRING: + case RECD_NULL: + default: + found = false; + break; + } + + return found; +} + +// bool varSetData(RecDataT varType, const char *varName, RecData value) +// +// Sets the variable specifed by varName to value. value and varName +// must be varType variables. +// +bool +varSetData(RecDataT varType, const char *varName, RecData value) +{ + int err = REC_ERR_FAIL; + + switch (varType) { + case RECD_INT: + err = RecSetRecordInt((char *)varName, value.rec_int); + break; + case RECD_COUNTER: + err = RecSetRecordCounter((char *)varName, value.rec_counter); + break; + case RECD_FLOAT: + err = RecSetRecordFloat((char *)varName, value.rec_float); + break; + default: + Fatal("unsupport type:%d\n", varType); + } + return (err == REC_ERR_OKAY); +} + +// bool varDataFromName(RecDataT varType, const char *varName, RecData *value) +// +// Sets the *value to value of the varName according varType. +// +// return true if bufVal was succefully set +// and false otherwise +// +bool +varDataFromName(RecDataT varType, const char *varName, RecData *value) +{ + int err; + + err = RecGetRecord_Xmalloc(varName, varType, value, true); + + return (err == REC_ERR_OKAY); +} + + +// bool varCounterFromName (const char*, RecFloat* ) +// +// Sets the *value to value of the varName. +// +// return true if bufVal was succefully set +// and false otherwise +// +bool +varCounterFromName(const char *varName, RecCounter * value) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + int err = REC_ERR_FAIL; + + err = RecGetRecordDataType((char *) varName, &varDataType); + + if (err == REC_ERR_FAIL) { + return false; + } + + switch (varDataType) { + case RECD_INT:{ + RecInt tempInt = 0; + RecGetRecordInt((char *) varName, &tempInt); + *value = (RecCounter) tempInt; + break; + } + case RECD_COUNTER:{ + *value = 0; + RecGetRecordCounter((char *) varName, value); + break; + } + case RECD_FLOAT:{ + RecFloat tempFloat = 0.0; + RecGetRecordFloat((char *) varName, &tempFloat); + *value = (RecCounter) tempFloat; + break; + } + case RECD_STRING: + case RECD_NULL: + default: + *value = -1; + found = false; + break; + } + + return found; +} + +// bool varFloatFromName (const char*, RecFloat* ) +// +// Sets the *value to value of the varName. +// +// return true if bufVal was succefully set +// and false otherwise +// +bool +varFloatFromName(const char *varName, RecFloat * value) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + + int err = REC_ERR_FAIL; + + err = RecGetRecordDataType((char *) varName, &varDataType); + + if (err == REC_ERR_FAIL) { + return false; + } + + switch (varDataType) { + case RECD_INT:{ + RecInt tempInt = 0; + RecGetRecordInt((char *) varName, &tempInt); + *value = (RecFloat) tempInt; + break; + } + case RECD_COUNTER:{ + RecCounter tempCounter = 0; + RecGetRecordCounter((char *) varName, &tempCounter); + *value = (RecFloat) tempCounter; + break; + } + case RECD_FLOAT:{ + *value = 0.0; + RecGetRecordFloat((char *) varName, value); + break; + } + case RECD_STRING: + case RECD_NULL: + default: + *value = -1.0; + found = false; + break; + } + + return found; +} + +// bool varIntFromName (const char*, RecInt* ) +// +// Sets the *value to value of the varName. +// +// return true if bufVal was succefully set +// and false otherwise +// +bool +varIntFromName(const char *varName, RecInt * value) +{ + RecDataT varDataType = RECD_NULL; + bool found = true; + int err = REC_ERR_FAIL; + + err = RecGetRecordDataType((char *) varName, &varDataType); + + if (err != REC_ERR_OKAY) { + return false; + } + + switch (varDataType) { + case RECD_INT:{ + *value = 0; + RecGetRecordInt((char *) varName, value); + break; + } + case RECD_COUNTER:{ + RecCounter tempCounter = 0; + RecGetRecordCounter((char *) varName, &tempCounter); + *value = (RecInt) tempCounter; + break; + } + case RECD_FLOAT:{ + RecFloat tempFloat = 0.0; + RecGetRecordFloat((char *) varName, &tempFloat); + *value = (RecInt) tempFloat; + break; + } + case RECD_STRING: + case RECD_NULL: + default: + *value = -1; + found = false; + break; + } + + return found; +} + + +// void percentStrFromFloat(MgmtFloat, char* bufVal) +// +// Converts a float to a percent string +// +// bufVal must point to adequate space a la sprintf +// +void +percentStrFromFloat(RecFloat val, char *bufVal) +{ + int percent; + + percent = (int) ((val * 100.0) + 0.5); + snprintf(bufVal, 4, "%d%%", percent); +} + +// void commaStrFromInt(RecInt bytes, char* bufVal) +// Converts an Int to string with commas in it +// +// bufVal must point to adequate space a la sprintf +// +void +commaStrFromInt(RecInt bytes, char *bufVal) +{ + int len; + int numCommas; + char *curPtr; + + sprintf(bufVal, "%" PRId64 "", bytes); + len = strlen(bufVal); + + // The string is too short to need commas + if (len < 4) { + return; + } + + numCommas = (len - 1) / 3; + curPtr = bufVal + (len + numCommas); + *curPtr = '\0'; + curPtr--; + + for (int i = 0; i < len; i++) { + *curPtr = bufVal[len - 1 - i]; + + if ((i + 1) % 3 == 0 && curPtr != bufVal) { + curPtr--; + *curPtr = ','; + } + curPtr--; + } + + ink_assert(curPtr + 1 == bufVal); +} + +// void MbytesFromInt(RecInt bytes, char* bufVal) +// Converts into a string in units of megabytes +// No unit specification is added +// +// bufVal must point to adequate space a la sprintf +// +void +MbytesFromInt(RecInt bytes, char *bufVal) +{ + RecInt mBytes = bytes / 1048576; + + sprintf(bufVal, "%" PRId64 "", mBytes); +} + +// void bytesFromInt(RecInt bytes, char* bufVal) +// +// Converts mgmt into a string with one of +// GB, MB, KB, B units +// +// bufVal must point to adequate space a la sprintf +void +bytesFromInt(RecInt bytes, char *bufVal) +{ + const int64_t gb = 1073741824; + const long int mb = 1048576; + const long int kb = 1024; + int bytesP; + double unitBytes; + + if (bytes >= gb) { + unitBytes = bytes / (double) gb; + snprintf(bufVal, 15, "%.1f GB", unitBytes); + } else { + // Reduce the precision of the bytes parameter + // because we know that it less than 1GB which + // has plenty of precision for a regular int + // and saves from 64 bit arithmetic which may + // be expensive on some processors + bytesP = (int) bytes; + if (bytesP >= mb) { + unitBytes = bytes / (double) mb; + snprintf(bufVal, 15, "%.1f MB", unitBytes); + } else if (bytesP >= kb) { + unitBytes = bytes / (double) kb; + snprintf(bufVal, 15, "%.1f KB", unitBytes); + } else { + snprintf(bufVal, 15, "%d", bytesP); + } + } +} + +// bool varStrFromName (const char*, char*, int) +// +// Sets the bufVal string to the value of the local manager +// named by varName. bufLen is size of bufVal +// +// return true if bufVal was succefully set +// and false otherwise +// +// EVIL ALERT: overviewRecord::varStrFromName is extremely +// similar to this function except in how it gets it's +// data. Changes to this fuction must be propogated +// to its twin. Cut and Paste sucks but there is not +// an easy way to merge the functions +// +bool +varStrFromName(const char *varNameConst, char *bufVal, int bufLen) +{ + char *varName = NULL; + RecDataT varDataType = RECD_NULL; + bool found = true; + int varNameLen = 0; + char formatOption = '\0'; + RecData data; + int err = REC_ERR_FAIL; + + memset(&data, 0, sizeof(RecData)); + + // Check to see if there is a \ option on the end of variable + // \ options indicate that we need special formatting + // of the results. Supported \ options are + // + /// b - bytes. Ints and Counts only. Amounts are + // transformed into one of GB, MB, KB, or B + // + varName = ats_strdup(varNameConst); + varNameLen = strlen(varName); + if (varNameLen > 3 && varName[varNameLen - 2] == '\\') { + formatOption = varName[varNameLen - 1]; + + // Now that we know the format option, terminate the string + // to make the option disappear + varName[varNameLen - 2] = '\0'; + + // Return not found for unknown format options + if (formatOption != 'b' && formatOption != 'm' && formatOption != 'c' && formatOption != 'p') { + ats_free(varName); + return false; + } + } + + err = RecGetRecordDataType(varName, &varDataType); + if (err == REC_ERR_FAIL) { + ats_free(varName); + return false; + } + + switch (varDataType) { + case RECD_INT: + RecGetRecordInt(varName, &data.rec_int); + if (formatOption == 'b') { + bytesFromInt(data.rec_int, bufVal); + } else if (formatOption == 'm') { + MbytesFromInt(data.rec_int, bufVal); + } else if (formatOption == 'c') { + commaStrFromInt(data.rec_int, bufVal); + } else { + snprintf(bufVal, bufLen, "%" PRId64 "", data.rec_int); + } + break; + + case RECD_COUNTER: + RecGetRecordCounter(varName, &data.rec_counter); + if (formatOption == 'b') { + bytesFromInt((MgmtInt) data.rec_counter, bufVal); + } else if (formatOption == 'm') { + MbytesFromInt((MgmtInt) data.rec_counter, bufVal); + } else if (formatOption == 'c') { + commaStrFromInt(data.rec_counter, bufVal); + } else { + snprintf(bufVal, bufLen, "%" PRId64 "", data.rec_counter); + } + break; + case RECD_FLOAT: + RecGetRecordFloat(varName, &data.rec_float); + if (formatOption == 'p') { + percentStrFromFloat(data.rec_float, bufVal); + } else { + snprintf(bufVal, bufLen, "%.2f", data.rec_float); + } + break; + case RECD_STRING: + RecGetRecordString_Xmalloc(varName, &data.rec_string); + if (data.rec_string == NULL) { + bufVal[0] = '\0'; + } else if (strlen(data.rec_string) < (size_t) (bufLen - 1)) { + ink_strlcpy(bufVal, data.rec_string, bufLen); + } else { + ink_strlcpy(bufVal, data.rec_string, bufLen); + } + ats_free(data.rec_string); + break; + default: + found = false; + break; + } + + ats_free(varName); + return found; +} + +// bool MgmtData::setFromName(const char*) +// +// Fills in class variables from the given +// variable name +// +// Returns true if the information could be set +// and false otherwise +// +bool +MgmtData::setFromName(const char *varName) +{ + bool found = true; + int err; + + err = RecGetRecordDataType((char *) varName, &this->type); + + if (err == REC_ERR_FAIL) { + return found; + } + + switch (this->type) { + case RECD_INT: + RecGetRecordInt((char *) varName, &this->data.rec_int); + break; + case RECD_COUNTER: + RecGetRecordCounter((char *) varName, &this->data.rec_counter); + break; + case RECD_FLOAT: + RecGetRecordFloat((char *) varName, &this->data.rec_float); + break; + case RECD_STRING: + RecGetRecordString_Xmalloc((char *) varName, &this->data.rec_string); + break; + case RECD_NULL: + default: + found = false; + break; + } + + return found; +} + +MgmtData::MgmtData() +{ + type = RECD_NULL; + memset(&data, 0, sizeof(RecData)); +} + +MgmtData::~MgmtData() +{ + if (type == RECD_STRING) + ats_free(data.rec_string); +} + +// MgmtData::compareFromString(const char* str, strLen) +// +// Compares the value of string converted to +// data type of this_>type with value +// held in this->data +// +bool +MgmtData::compareFromString(const char *str) +{ + RecData compData; + bool compare = false; + float floatDiff; + + switch (this->type) { + case RECD_INT: + // TODO: Add SI decimal multipliers rule ? + if (str && recordRegexCheck("^[0-9]+$", str)) { + compData.rec_int = ink_atoi64(str); + if (data.rec_int == compData.rec_int) { + compare = true; + } + } + break; + case RECD_COUNTER: + if (str && recordRegexCheck("^[0-9]+$", str)) { + compData.rec_counter = ink_atoi64(str); + if (data.rec_counter == compData.rec_counter) { + compare = true; + } + } + break; + case RECD_FLOAT: + compData.rec_float = atof(str); + // HACK - There are some rounding problems with + // floating point numbers so say we have a match if there difference + // is small + floatDiff = data.rec_float - compData.rec_float; + if (floatDiff > -0.001 && floatDiff < 0.001) { + compare = true; + } + break; + case RECD_STRING: + if (str == NULL || *str == '\0') { + if (data.rec_string == NULL) { + compare = true; + } + } else { + if ((data.rec_string != NULL) && (strcmp(str, data.rec_string) == 0)) { + compare = true; + } + } + break; + case RECD_NULL: + default: + compare = false; + break; + } + + return compare; +} + +// void RecDataT varType(const char* varName) +// +// Simply return the variable type +// +RecDataT +varType(const char *varName) +{ + RecDataT data_type; + int err; + + err = RecGetRecordDataType((char *) varName, &data_type); + + if (err == REC_ERR_FAIL) { + return RECD_NULL; + } + + Debug("RecOp", "[varType] %s is of type %d\n", varName, data_type); + return data_type; +} + + +// InkHashTable* processFormSubmission(char* submission) +// +// A generic way to handle a HTML form submission. +// Creates a hash table with name value pairs +// +// CALLEE must deallocate the returned hash table with +// ink_hash_table_destroy_and_xfree_values(InkHashTable *ht_ptr) +// + +InkHashTable * +processFormSubmission(char *submission) +{ + InkHashTable *nameVal = ink_hash_table_create(InkHashTableKeyType_String); + Tokenizer updates("&\n\r"); + Tokenizer pair("="); + int numUpdates; + char *name; + char *value; + char *submission_copy; + int pairNum; + + if (submission == NULL) { + ink_hash_table_destroy(nameVal); + return NULL; + } + + submission_copy = ats_strdup(submission); + numUpdates = updates.Initialize(submission_copy, SHARE_TOKS); + + for (int i = 0; i < numUpdates; i++) { + pairNum = pair.Initialize(updates[i]); + + // We should have gotten either either 1 or 2 tokens + // One token indicates an variable being set to + // blank. Two indicates the variable being set to + // a value. If the submission is invalid, just forget + // about it. + if (pairNum == 1 || pairNum == 2) { + name = ats_strdup(pair[0]); + substituteUnsafeChars(name); + + // If the value is blank, store it as a null + if (pairNum == 1) { + value = NULL; + } else { + value = ats_strdup(pair[1]); + substituteUnsafeChars(value); + } + + ink_hash_table_insert(nameVal, name, value); + ats_free(name); + } + } + ats_free(submission_copy); + + return nameVal; +} + +// InkHashTable* processFormSubmission_noSubstitute(char* submission) +// +// A generic way to handle a HTML form submission. +// Creates a hash table with name value pairs +// +// CALLEE must deallocate the returned hash table with +// ink_hash_table_destroy_and_xfree_values(InkHashTable *ht_ptr) +// +// Note: This function will _not_ substituteUnsafeChars() +InkHashTable * +processFormSubmission_noSubstitute(char *submission) +{ + + InkHashTable *nameVal = ink_hash_table_create(InkHashTableKeyType_String); + Tokenizer updates("&\n\r"); + Tokenizer pair("="); + int numUpdates; + char *name; + char *value; + char *submission_copy; + int pairNum; + + if (submission == NULL) { + ink_hash_table_destroy(nameVal); + return NULL; + } + + submission_copy = ats_strdup(submission); + numUpdates = updates.Initialize(submission_copy, SHARE_TOKS); + + for (int i = 0; i < numUpdates; i++) { + pairNum = pair.Initialize(updates[i]); + + // We should have gotten either either 1 or 2 tokens + // One token indicates an variable being set to + // blank. Two indicates the variable being set to + // a value. If the submission is invalid, just forget + // about it. + if (pairNum == 1 || pairNum == 2) { + name = ats_strdup(pair[0]); + + // If the value is blank, store it as a null + if (pairNum == 1) { + value = NULL; + } else { + value = ats_strdup(pair[1]); + } + + ink_hash_table_insert(nameVal, name, value); + ats_free(name); + } + } + ats_free(submission_copy); + + return nameVal; +} + +// +// Removes any cr/lf line breaks from the text data +// +int +convertHtmlToUnix(char *buffer) +{ + char *read = buffer; + char *write = buffer; + int numSub = 0; + + while (*read != '\0') { + if (*read == '\015') { + *write = ' '; + read++; + write++; + numSub++; + } else { + *write = *read; + write++; + read++; + } + } + *write = '\0'; + return numSub; +} + +// Substitutes HTTP unsafe character representations +// with their actual values. Modifies the passed +// in string +// +int +substituteUnsafeChars(char *buffer) +{ + char *read = buffer; + char *write = buffer; + char subStr[3]; + long charVal; + int numSub = 0; + + subStr[2] = '\0'; + while (*read != '\0') { + if (*read == '%') { + subStr[0] = *(++read); + subStr[1] = *(++read); + charVal = strtol(subStr, (char **) NULL, 16); + *write = (char) charVal; + read++; + write++; + numSub++; + } else if (*read == '+') { + *write = ' '; + write++; + read++; + } else { + *write = *read; + write++; + read++; + } + } + *write = '\0'; + return numSub; +} + +// Substitutes for characters that can be misconstrued +// as part of an HTML tag +// Allocates a new string which the +// the CALLEE MUST DELETE +// +char * +substituteForHTMLChars(const char *buffer) +{ + + char *safeBuf; // the return "safe" character buffer + char *safeCurrent; // where we are in the return buffer + const char *inCurrent = buffer; // where we are in the original buffer + int inLength = strlen(buffer); // how long the orig buffer in + + // Maximum character expansion is one to three + unsigned int bufferToAllocate = (inLength * 5) + 1; + safeBuf = new char[bufferToAllocate]; + safeCurrent = safeBuf; + + while (*inCurrent != '\0') { + switch (*inCurrent) { + case '"': + ink_strlcpy(safeCurrent, """, bufferToAllocate); + safeCurrent += 6; + break; + case '<': + ink_strlcpy(safeCurrent, "<", bufferToAllocate); + safeCurrent += 4; + break; + case '>': + ink_strlcpy(safeCurrent, ">", bufferToAllocate); + safeCurrent += 4; + break; + case '&': + ink_strlcpy(safeCurrent, "&", bufferToAllocate); + safeCurrent += 5; + break; + default: + *safeCurrent = *inCurrent; + safeCurrent += 1; + break; + } + + inCurrent++; + } + *safeCurrent = '\0'; + return safeBuf; +} + + +// bool ProxyShutdown() +// +// Attempts to turn the proxy off. Returns +// true if the proxy is off when the call returns +// and false if it is still on +// +bool +ProxyShutdown() +{ + int i = 0; + + // Check to make sure that we are not already down + if (!lmgmt->processRunning()) { + return true; + } + // Send the shutdown event + lmgmt->signalEvent(MGMT_EVENT_SHUTDOWN, "shutdown"); + + // Wait for awhile for shtudown to happen + do { + mgmt_sleep_sec(1); + i++; + } while (i < 10 && lmgmt->processRunning()); + + // See if we succeeded + if (lmgmt->processRunning()) { + return false; + } else { + return true; + } +} + +// +// +// Sets the LocalManager variable: proxy.node.hostname +// +// To the fully qualified hostname for the machine +// that we are running on +int +setHostnameVar() +{ + char ourHostName[MAXDNAME]; + char *firstDot; + + // Get Our HostName + if (gethostname(ourHostName, MAXDNAME) < 0) { + mgmt_fatal(stderr, errno, "[setHostnameVar] Can not determine our hostname"); + } + + res_init(); + appendDefaultDomain(ourHostName, MAXDNAME); + + // FQ is a Fully Qualified hostname (ie: proxydev.example.com) + varSetFromStr("proxy.node.hostname_FQ", ourHostName); + + // non-FQ is just the hostname (ie: proxydev) + firstDot = strchr(ourHostName, '.'); + if (firstDot != NULL) { + *firstDot = '\0'; + } + varSetFromStr("proxy.node.hostname", ourHostName); + + return 0; +} + +// void appendDefautDomain(char* hostname, int bufLength) +// +// Appends the pasted in hostname with the default +// domain if the hostname is an unqualified name +// +// The default domain is obtained from the resolver libraries +// data structure +// +// Truncates the domain name if bufLength is too small +// +// +void +appendDefaultDomain(char *hostname, int bufLength) +{ + + int len = strlen(hostname); + const char msg[] = "Nodes will be know by their unqualified host name"; + static int error_before = 0; // Race ok since effect is multple error msg + + ink_assert(len < bufLength); + ink_assert(bufLength >= 64); + + // Ensure null termination of the result string + hostname[bufLength - 1] = '\0'; + + if (strchr(hostname, '.') == NULL) { + if (_res.defdname[0] != '\0') { + if (bufLength - 2 >= (int) (strlen(hostname) + strlen(_res.defdname))) { + ink_strlcat(hostname, ".", bufLength); + ink_strlcat(hostname, _res.defdname, bufLength); + } else { + if (error_before == 0) { + mgmt_log(stderr, "%s %s\n", "[appendDefaultDomain] Domain name is too long.", msg); + error_before++; + } + } + } else { + if (error_before == 0) { + mgmt_log(stderr, "%s %s\n", "[appendDefaultDomain] Unable to determine default domain name.", msg); + error_before++; + } + } + } +} + +bool +recordValidityCheck(const char *varName, const char *value) +{ + RecCheckT check_t; + char *pattern; + + if (RecGetRecordCheckType((char *) varName, &check_t) != REC_ERR_OKAY) { + return false; + } + if (RecGetRecordCheckExpr((char *) varName, &pattern) != REC_ERR_OKAY) { + return false; + } + + switch (check_t) { + case RECC_STR: + if (recordRegexCheck(pattern, value)) { + return true; + } + break; + case RECC_INT: + if (recordRangeCheck(pattern, value)) { + return true; + } + break; + case RECC_IP: + if (recordIPCheck(pattern, value)) { + return true; + } + break; + case RECC_NULL: + // skip checking + return true; + default: + // unknown RecordCheckType... + mgmt_log(stderr, "[WebMgmtUtil] error, unknown RecordCheckType for record %s\n", varName); + } + + return false; + + +} + +bool +recordRegexCheck(const char *pattern, const char *value) +{ + pcre* regex; + const char* error; + int erroffset; + + regex = pcre_compile(pattern, 0, &error, &erroffset, NULL); + if (!regex) { + return false; + } else { + int r = pcre_exec(regex, NULL, value, strlen(value), 0, 0, NULL, 0); + + pcre_free(regex); + return (r != -1) ? true : false; + } + + return false; //no-op +} + +bool +recordRangeCheck(const char *pattern, const char *value) +{ + int l_limit; + int u_limit; + int val; + char *p = (char *) pattern; + Tokenizer dashTok("-"); + + if (recordRegexCheck("^[0-9]+$", value)) { + while (*p != '[') { + p++; + } // skip to '[' + if (dashTok.Initialize(++p, COPY_TOKS) == 2) { + l_limit = atoi(dashTok[0]); + u_limit = atoi(dashTok[1]); + val = atoi(value); + if (val >= l_limit && val <= u_limit) { + return true; + } + } + } + return false; +} + +bool +recordIPCheck(const char *pattern, const char *value) +{ + // regex_t regex; + // int result; + bool check; + const char *range_pattern = + "\\[[0-9]+\\-[0-9]+\\]\\\\\\.\\[[0-9]+\\-[0-9]+\\]\\\\\\.\\[[0-9]+\\-[0-9]+\\]\\\\\\.\\[[0-9]+\\-[0-9]+\\]"; + const char *ip_pattern = "[0-9]*[0-9]*[0-9].[0-9]*[0-9]*[0-9].[0-9]*[0-9]*[0-9].[0-9]*[0-9]*[0-9]"; + + Tokenizer dotTok1("."); + Tokenizer dotTok2("."); + int i; + + check = true; + if (recordRegexCheck(range_pattern, pattern) && recordRegexCheck(ip_pattern, value)) { + if (dotTok1.Initialize((char *) pattern, COPY_TOKS) == 4 && dotTok2.Initialize((char *) value, COPY_TOKS) == 4) { + for (i = 0; i < 4 && check; i++) { + if (!recordRangeCheck(dotTok1[i], dotTok2[i])) { + check = false; + } + } + if (check) { + return true; + } + } + } else if (strcmp(value, "") == 0) { + return true; + } + return false; +} + +bool +recordRestartCheck(const char *varName) +{ + + RecUpdateT update_t; + + if (RecGetRecordUpdateType((char *) varName, &update_t) != REC_ERR_OKAY) { + return false; + } + + if (update_t == RECU_RESTART_TS || update_t == RECU_RESTART_TM || update_t == RECU_RESTART_TC) { + return true; + } + + return false; + +} + +void +fileCheckSum(char *buffer, int size, char *checksum, const size_t checksumSize) +{ + INK_DIGEST_CTX md5_context; + char checksum_md5[16]; + + ink_code_incr_md5_init(&md5_context); + ink_code_incr_md5_update(&md5_context, buffer, size); + ink_code_incr_md5_final(checksum_md5, &md5_context); + ink_code_md5_stringify(checksum, checksumSize, checksum_md5); +} + +//------------------------------------------------------------------------- +// getFilesInDirectory +// +// copied from MultiFiles::WalkFiles - but slightly modified +// returns -1 if directory does not exit +// returns 1 if everything is ok +//------------------------------------------------------------------------- +int +getFilesInDirectory(char *managedDir, ExpandingArray * fileList) +{ + struct dirent *dirEntry; + DIR *dir; + + char *fileName; + char *filePath; + struct stat fileInfo; + // struct stat records_config_fileInfo; + fileEntry *fileListEntry; + + if ((dir = opendir(managedDir)) == NULL) { + mgmt_log(stderr, "[getFilesInDirectory] Unable to open %s directory: %s\n", managedDir, strerror(errno)); + return -1; + } + // The fun of Solaris - readdir_r requires a buffer passed into it + // The man page says this obscene expression gives us the proper + // size + dirEntry = (struct dirent *)alloca(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1); + + struct dirent *result; + while (readdir_r(dir, dirEntry, &result) == 0) { + if (!result) + break; + fileName = dirEntry->d_name; + if (!fileName || !*fileName) { + continue; + } + filePath = newPathString(managedDir, fileName); + if (stat(filePath, &fileInfo) < 0) { + mgmt_log(stderr, "[getFilesInDirectory] Stat of a %s failed : %s\n", fileName, strerror(errno)); + } else { + // Ignore ., .., and any dot files + if (fileName && *fileName != '.') { + fileListEntry = (fileEntry *)ats_malloc(sizeof(fileEntry)); + fileListEntry->c_time = fileInfo.st_ctime; + ink_strlcpy(fileListEntry->name, fileName, sizeof(fileListEntry->name)); + fileList->addEntry(fileListEntry); + } + } + delete[]filePath; + } + + closedir(dir); + + fileList->sortWithFunction(fileEntryCmpFunc); + return 1; +} + +//------------------------------------------------------------------------- +// newPathString +// +// copied from MultiFile::newPathString +// Note: uses C++ new/delete for memory allocation/deallocation +//------------------------------------------------------------------------- +char * +newPathString(const char *s1, const char *s2) +{ + char *newStr; + int srcLen; // is the length of the src rootpath + int addLen; // maximum total path length + + // Treat null as an empty path. + if (!s2) + s2 = ""; + addLen = strlen(s2) + 1; + if (*s2 == '/') { + // If addpath is rooted, then rootpath is unused. + newStr = new char[addLen]; + ink_strlcpy(newStr, s2, addLen); + return newStr; + } + if (!s1 || !*s1) { + // If there's no rootpath return the addpath + newStr = new char[addLen]; + ink_strlcpy(newStr, s2, addLen); + return newStr; + } + srcLen = strlen(s1); + newStr = new char[srcLen + addLen + 1]; + ink_assert(newStr != NULL); + + ink_strlcpy(newStr, s1, srcLen + addLen + 1); + if (newStr[srcLen - 1] != '/') + newStr[srcLen++] = '/'; + ink_strlcpy(&newStr[srcLen], s2, srcLen + addLen + 1); + + return newStr; +} http://git-wip-us.apache.org/repos/asf/trafficserver/blob/82deca40/mgmt/WebMgmtUtils.h ---------------------------------------------------------------------- diff --git a/mgmt/WebMgmtUtils.h b/mgmt/WebMgmtUtils.h new file mode 100644 index 0000000..503aec5 --- /dev/null +++ b/mgmt/WebMgmtUtils.h @@ -0,0 +1,124 @@ +/** @file + + A brief file description + + @section license License + + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + */ + +#ifndef _WEB_MGMT_UTILS_ +#define _WEB_MGMT_UTILS_ + +#include "MgmtDefs.h" + +/**************************************************************************** + * + * WebMgmtUtils.h - Functions for interfacing to management records + * + * + * + ****************************************************************************/ + +#include "ink_hash_table.h" +#include "TextBuffer.h" +#include "ExpandingArray.h" + +#include "P_RecCore.h" + +// class MgmtData - stores information from local manager +// variables in its native type +// +#include "P_RecCore.h" +class MgmtData +{ +public: + MgmtData(); + ~MgmtData(); + bool compareFromString(const char *str); + bool setFromName(const char *varName); + RecDataT type; + RecData data; +}; + +// Convert to byte units (GB, MB, KB) +void bytesFromInt(RecInt bytes, char *bufVal); + +// Convert to MB +void MbytesFromInt(RecInt bytes, char *bufVal); + +// Create comma string from int +void commaStrFromInt(RecInt bytes, char *bufVal); + +// Create percent string from float +void percentStrFromFloat(RecFloat val, char *bufVal); + +// All types converted to/from strings where appropriate +bool varStrFromName(const char *varName, char *bufVal, int bufLen); +bool varSetFromStr(const char *varName, const char *value); + +// Converts where applicable to specified type +bool varIntFromName(const char *varName, RecInt * value); +bool varFloatFromName(const char *varName, RecFloat * value); +bool varCounterFromName(const char *varName, RecCounter * value); +bool varDataFromName(RecDataT varType, const char *varName, RecData *value); + +// No conversion done. varName must represnt a value of the appropriate +// type +// Default arguement "convert" added to allow great flexiblity in type checking +bool varSetInt(const char *varName, RecInt value, bool convert = false); +bool varSetCounter(const char *varName, RecCounter value, bool convert = false); +bool varSetFloat(const char *varName, RecFloat value, bool convert = false); +bool varSetData(RecDataT varType, const char *varName, RecData value); + +// Return the type of the variable named +RecDataT varType(const char *varName); + +int convertHtmlToUnix(char *buffer); +int substituteUnsafeChars(char *buffer); +char *substituteForHTMLChars(const char *buffer); + +// Produce a hash table based on a HTML form submission +// +// CALLEE deallocates hashtable +InkHashTable *processFormSubmission(char *submission); +InkHashTable *processFormSubmission_noSubstitute(char *submission); + +// Shutdown the proxy +bool ProxyShutdown(); +int setHostnameVar(); +void appendDefaultDomain(char *hostname, int bufLength); + +// Some scaling constants +#define BYTES_TO_MB_SCALE (1/(1024*1024.0)) +#define MBIT_TO_KBIT_SCALE (1000.0) +#define SECOND_TO_MILLISECOND_SCALE (1000.0) +#define PCT_TO_INTPCT_SCALE (100.0) + +bool recordValidityCheck(const char *varName, const char *value); +bool recordRegexCheck(const char *pattern, const char *value); +bool recordRangeCheck(const char *pattern, const char *value); +bool recordIPCheck(const char *pattern, const char *value); +bool recordRestartCheck(const char *varName); + +void fileCheckSum(char *buffer, int size, char *checksum, const size_t checksumSize); + +// file management +int getFilesInDirectory(char *managedDir, ExpandingArray * fileList); +char *newPathString(const char *s1, const char *s2); + +#endif http://git-wip-us.apache.org/repos/asf/trafficserver/blob/82deca40/mgmt/utils/Makefile.am ---------------------------------------------------------------------- diff --git a/mgmt/utils/Makefile.am b/mgmt/utils/Makefile.am index 8321221..65dd206 100644 --- a/mgmt/utils/Makefile.am +++ b/mgmt/utils/Makefile.am @@ -39,9 +39,7 @@ libutils_lm_la_SOURCES = \ ExpandingArray.h \ MgmtLocalCleanup.cc \ MgmtUtils.cc \ - MgmtUtils.h \ - WebMgmtUtils.cc \ - WebMgmtUtils.h + MgmtUtils.h libutils_p_la_SOURCES = \ MgmtProcessCleanup.cc \ http://git-wip-us.apache.org/repos/asf/trafficserver/blob/82deca40/mgmt/utils/WebMgmtUtils.cc ---------------------------------------------------------------------- diff --git a/mgmt/utils/WebMgmtUtils.cc b/mgmt/utils/WebMgmtUtils.cc deleted file mode 100644 index df7f6e6..0000000 --- a/mgmt/utils/WebMgmtUtils.cc +++ /dev/null @@ -1,1378 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -#include "libts.h" -#include "LocalManager.h" -#include "MgmtUtils.h" -#include "WebMgmtUtils.h" -#include "MultiFile.h" - -#ifdef HAVE_PCRE_PCRE_H -#include <pcre/pcre.h> -#else -#include <pcre.h> -#endif - - -/**************************************************************************** - * - * WebMgmtUtils.cc - Functions for interfacing to management records - * - * - * - ****************************************************************************/ - - -// bool varSetFromStr(const char*, const char* ) -// -// Sets the named local manager variable from the value string -// passed in. Does the appropriate type conversion on -// value string to get it to the type of the local manager -// variable -// -// returns true if the variable was successfully set -// and false otherwise -// -bool -varSetFromStr(const char *varName, const char *value) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - int err = REC_ERR_FAIL; - RecData data; - - memset(&data, 0, sizeof(RecData)); - - err = RecGetRecordDataType((char *) varName, &varDataType); - if (err != REC_ERR_OKAY) { - return found; - } - // Use any empty string if we get a NULL so - // sprintf does puke. However, we need to - // switch this back to NULL for STRING types - if (value == NULL) { - value = ""; - } - - switch (varDataType) { - case RECD_INT: - if (sscanf(value, "%" PRId64 "", &data.rec_int) == 1) { - RecSetRecordInt((char *) varName, data.rec_int); - } else { - found = false; - } - break; - case RECD_COUNTER: - if (sscanf(value, "%" PRId64 "", &data.rec_counter) == 1) { - RecSetRecordCounter((char *) varName, data.rec_counter); - } else { - found = false; - } - break; - case RECD_FLOAT: - // coverity[secure_coding] - if (sscanf(value, "%f", &data.rec_float) == 1) { - RecSetRecordFloat((char *) varName, data.rec_float); - } else { - found = false; - } - break; - case RECD_STRING: - if (*value == '\0') { - RecSetRecordString((char *) varName, NULL); - } else { - RecSetRecordString((char *) varName, (char *) value); - } - break; - case RECD_NULL: - default: - found = false; - break; - } - - return found; -} - -// bool varSetFloat(const char* varName, RecFloat value) -// -// Sets the variable specifed by varName to value. varName -// must be a RecFloat variable. No conversion is done for -// other types unless convert is set to ture. In the case -// of convert is ture, type conversion is perform if applicable. -// By default, convert is set to be false and can be overrided -// when the function is called. -// -bool -varSetFloat(const char *varName, RecFloat value, bool convert) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - int err = REC_ERR_FAIL; - - err = RecGetRecordDataType((char *) varName, &varDataType); - if (err != REC_ERR_OKAY) { - return found; - } - - switch (varDataType) { - case RECD_FLOAT: - RecSetRecordFloat((char *) varName, (RecFloat) value); - break; - case RECD_INT: - if (convert) { - value += 0.5; // rounding up - RecSetRecordInt((char *) varName, (RecInt) value); - break; - } - case RECD_COUNTER: - if (convert) { - RecSetRecordCounter((char *) varName, (RecCounter) value); - break; - } - case RECD_STRING: - case RECD_NULL: - default: - found = false; - break; - } - - return found; -} - -// bool varSetCounter(const char* varName, RecCounter value) -// -// Sets the variable specifed by varName to value. varName -// must be an RecCounter variable. No conversion is done for -// other types unless convert is set to ture. In the case -// of convert is ture, type conversion is perform if applicable. -// By default, convert is set to be false and can be overrided -// when the function is called. -// -bool -varSetCounter(const char *varName, RecCounter value, bool convert) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - int err = REC_ERR_FAIL; - - err = RecGetRecordDataType((char *) varName, &varDataType); - if (err != REC_ERR_OKAY) { - return found; - } - - switch (varDataType) { - case RECD_COUNTER: - RecSetRecordCounter((char *) varName, (RecCounter) value); - break; - case RECD_INT: - if (convert) { - RecSetRecordInt((char *) varName, (RecInt) value); - break; - } - case RECD_FLOAT: - if (convert) { - RecSetRecordFloat((char *) varName, (RecFloat) value); - break; - } - case RECD_STRING: - case RECD_NULL: - default: - found = false; - break; - } - - return found; -} - -// bool varSetInt(const char* varName, RecInt value) -// -// Sets the variable specifed by varName to value. varName -// must be an RecInt variable. No conversion is done for -// other types unless convert is set to ture. In the case -// of convert is ture, type conversion is perform if applicable. -// By default, convert is set to be false and can be overrided -// when the function is called. -// -bool -varSetInt(const char *varName, RecInt value, bool convert) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - int err = REC_ERR_FAIL; - - err = RecGetRecordDataType((char *) varName, &varDataType); - if (err != REC_ERR_OKAY) { - return found; - } - - switch (varDataType) { - case RECD_INT: - RecSetRecordInt((char *) varName, (RecInt) value); - break; - case RECD_COUNTER: - if (convert) { - RecSetRecordCounter((char *) varName, (RecCounter) value); - break; - } - case RECD_FLOAT: - if (convert) { - RecSetRecordFloat((char *) varName, (RecFloat) value); - break; - } - case RECD_STRING: - case RECD_NULL: - default: - found = false; - break; - } - - return found; -} - -// bool varSetData(RecDataT varType, const char *varName, RecData value) -// -// Sets the variable specifed by varName to value. value and varName -// must be varType variables. -// -bool -varSetData(RecDataT varType, const char *varName, RecData value) -{ - int err = REC_ERR_FAIL; - - switch (varType) { - case RECD_INT: - err = RecSetRecordInt((char *)varName, value.rec_int); - break; - case RECD_COUNTER: - err = RecSetRecordCounter((char *)varName, value.rec_counter); - break; - case RECD_FLOAT: - err = RecSetRecordFloat((char *)varName, value.rec_float); - break; - default: - Fatal("unsupport type:%d\n", varType); - } - return (err == REC_ERR_OKAY); -} - -// bool varDataFromName(RecDataT varType, const char *varName, RecData *value) -// -// Sets the *value to value of the varName according varType. -// -// return true if bufVal was succefully set -// and false otherwise -// -bool -varDataFromName(RecDataT varType, const char *varName, RecData *value) -{ - int err; - - err = RecGetRecord_Xmalloc(varName, varType, value, true); - - return (err == REC_ERR_OKAY); -} - - -// bool varCounterFromName (const char*, RecFloat* ) -// -// Sets the *value to value of the varName. -// -// return true if bufVal was succefully set -// and false otherwise -// -bool -varCounterFromName(const char *varName, RecCounter * value) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - int err = REC_ERR_FAIL; - - err = RecGetRecordDataType((char *) varName, &varDataType); - - if (err == REC_ERR_FAIL) { - return false; - } - - switch (varDataType) { - case RECD_INT:{ - RecInt tempInt = 0; - RecGetRecordInt((char *) varName, &tempInt); - *value = (RecCounter) tempInt; - break; - } - case RECD_COUNTER:{ - *value = 0; - RecGetRecordCounter((char *) varName, value); - break; - } - case RECD_FLOAT:{ - RecFloat tempFloat = 0.0; - RecGetRecordFloat((char *) varName, &tempFloat); - *value = (RecCounter) tempFloat; - break; - } - case RECD_STRING: - case RECD_NULL: - default: - *value = -1; - found = false; - break; - } - - return found; -} - -// bool varFloatFromName (const char*, RecFloat* ) -// -// Sets the *value to value of the varName. -// -// return true if bufVal was succefully set -// and false otherwise -// -bool -varFloatFromName(const char *varName, RecFloat * value) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - - int err = REC_ERR_FAIL; - - err = RecGetRecordDataType((char *) varName, &varDataType); - - if (err == REC_ERR_FAIL) { - return false; - } - - switch (varDataType) { - case RECD_INT:{ - RecInt tempInt = 0; - RecGetRecordInt((char *) varName, &tempInt); - *value = (RecFloat) tempInt; - break; - } - case RECD_COUNTER:{ - RecCounter tempCounter = 0; - RecGetRecordCounter((char *) varName, &tempCounter); - *value = (RecFloat) tempCounter; - break; - } - case RECD_FLOAT:{ - *value = 0.0; - RecGetRecordFloat((char *) varName, value); - break; - } - case RECD_STRING: - case RECD_NULL: - default: - *value = -1.0; - found = false; - break; - } - - return found; -} - -// bool varIntFromName (const char*, RecInt* ) -// -// Sets the *value to value of the varName. -// -// return true if bufVal was succefully set -// and false otherwise -// -bool -varIntFromName(const char *varName, RecInt * value) -{ - RecDataT varDataType = RECD_NULL; - bool found = true; - int err = REC_ERR_FAIL; - - err = RecGetRecordDataType((char *) varName, &varDataType); - - if (err != REC_ERR_OKAY) { - return false; - } - - switch (varDataType) { - case RECD_INT:{ - *value = 0; - RecGetRecordInt((char *) varName, value); - break; - } - case RECD_COUNTER:{ - RecCounter tempCounter = 0; - RecGetRecordCounter((char *) varName, &tempCounter); - *value = (RecInt) tempCounter; - break; - } - case RECD_FLOAT:{ - RecFloat tempFloat = 0.0; - RecGetRecordFloat((char *) varName, &tempFloat); - *value = (RecInt) tempFloat; - break; - } - case RECD_STRING: - case RECD_NULL: - default: - *value = -1; - found = false; - break; - } - - return found; -} - - -// void percentStrFromFloat(MgmtFloat, char* bufVal) -// -// Converts a float to a percent string -// -// bufVal must point to adequate space a la sprintf -// -void -percentStrFromFloat(RecFloat val, char *bufVal) -{ - int percent; - - percent = (int) ((val * 100.0) + 0.5); - snprintf(bufVal, 4, "%d%%", percent); -} - -// void commaStrFromInt(RecInt bytes, char* bufVal) -// Converts an Int to string with commas in it -// -// bufVal must point to adequate space a la sprintf -// -void -commaStrFromInt(RecInt bytes, char *bufVal) -{ - int len; - int numCommas; - char *curPtr; - - sprintf(bufVal, "%" PRId64 "", bytes); - len = strlen(bufVal); - - // The string is too short to need commas - if (len < 4) { - return; - } - - numCommas = (len - 1) / 3; - curPtr = bufVal + (len + numCommas); - *curPtr = '\0'; - curPtr--; - - for (int i = 0; i < len; i++) { - *curPtr = bufVal[len - 1 - i]; - - if ((i + 1) % 3 == 0 && curPtr != bufVal) { - curPtr--; - *curPtr = ','; - } - curPtr--; - } - - ink_assert(curPtr + 1 == bufVal); -} - -// void MbytesFromInt(RecInt bytes, char* bufVal) -// Converts into a string in units of megabytes -// No unit specification is added -// -// bufVal must point to adequate space a la sprintf -// -void -MbytesFromInt(RecInt bytes, char *bufVal) -{ - RecInt mBytes = bytes / 1048576; - - sprintf(bufVal, "%" PRId64 "", mBytes); -} - -// void bytesFromInt(RecInt bytes, char* bufVal) -// -// Converts mgmt into a string with one of -// GB, MB, KB, B units -// -// bufVal must point to adequate space a la sprintf -void -bytesFromInt(RecInt bytes, char *bufVal) -{ - const int64_t gb = 1073741824; - const long int mb = 1048576; - const long int kb = 1024; - int bytesP; - double unitBytes; - - if (bytes >= gb) { - unitBytes = bytes / (double) gb; - snprintf(bufVal, 15, "%.1f GB", unitBytes); - } else { - // Reduce the precision of the bytes parameter - // because we know that it less than 1GB which - // has plenty of precision for a regular int - // and saves from 64 bit arithmetic which may - // be expensive on some processors - bytesP = (int) bytes; - if (bytesP >= mb) { - unitBytes = bytes / (double) mb; - snprintf(bufVal, 15, "%.1f MB", unitBytes); - } else if (bytesP >= kb) { - unitBytes = bytes / (double) kb; - snprintf(bufVal, 15, "%.1f KB", unitBytes); - } else { - snprintf(bufVal, 15, "%d", bytesP); - } - } -} - -// bool varStrFromName (const char*, char*, int) -// -// Sets the bufVal string to the value of the local manager -// named by varName. bufLen is size of bufVal -// -// return true if bufVal was succefully set -// and false otherwise -// -// EVIL ALERT: overviewRecord::varStrFromName is extremely -// similar to this function except in how it gets it's -// data. Changes to this fuction must be propogated -// to its twin. Cut and Paste sucks but there is not -// an easy way to merge the functions -// -bool -varStrFromName(const char *varNameConst, char *bufVal, int bufLen) -{ - char *varName = NULL; - RecDataT varDataType = RECD_NULL; - bool found = true; - int varNameLen = 0; - char formatOption = '\0'; - RecData data; - int err = REC_ERR_FAIL; - - memset(&data, 0, sizeof(RecData)); - - // Check to see if there is a \ option on the end of variable - // \ options indicate that we need special formatting - // of the results. Supported \ options are - // - /// b - bytes. Ints and Counts only. Amounts are - // transformed into one of GB, MB, KB, or B - // - varName = ats_strdup(varNameConst); - varNameLen = strlen(varName); - if (varNameLen > 3 && varName[varNameLen - 2] == '\\') { - formatOption = varName[varNameLen - 1]; - - // Now that we know the format option, terminate the string - // to make the option disappear - varName[varNameLen - 2] = '\0'; - - // Return not found for unknown format options - if (formatOption != 'b' && formatOption != 'm' && formatOption != 'c' && formatOption != 'p') { - ats_free(varName); - return false; - } - } - - err = RecGetRecordDataType(varName, &varDataType); - if (err == REC_ERR_FAIL) { - ats_free(varName); - return false; - } - - switch (varDataType) { - case RECD_INT: - RecGetRecordInt(varName, &data.rec_int); - if (formatOption == 'b') { - bytesFromInt(data.rec_int, bufVal); - } else if (formatOption == 'm') { - MbytesFromInt(data.rec_int, bufVal); - } else if (formatOption == 'c') { - commaStrFromInt(data.rec_int, bufVal); - } else { - snprintf(bufVal, bufLen, "%" PRId64 "", data.rec_int); - } - break; - - case RECD_COUNTER: - RecGetRecordCounter(varName, &data.rec_counter); - if (formatOption == 'b') { - bytesFromInt((MgmtInt) data.rec_counter, bufVal); - } else if (formatOption == 'm') { - MbytesFromInt((MgmtInt) data.rec_counter, bufVal); - } else if (formatOption == 'c') { - commaStrFromInt(data.rec_counter, bufVal); - } else { - snprintf(bufVal, bufLen, "%" PRId64 "", data.rec_counter); - } - break; - case RECD_FLOAT: - RecGetRecordFloat(varName, &data.rec_float); - if (formatOption == 'p') { - percentStrFromFloat(data.rec_float, bufVal); - } else { - snprintf(bufVal, bufLen, "%.2f", data.rec_float); - } - break; - case RECD_STRING: - RecGetRecordString_Xmalloc(varName, &data.rec_string); - if (data.rec_string == NULL) { - bufVal[0] = '\0'; - } else if (strlen(data.rec_string) < (size_t) (bufLen - 1)) { - ink_strlcpy(bufVal, data.rec_string, bufLen); - } else { - ink_strlcpy(bufVal, data.rec_string, bufLen); - } - ats_free(data.rec_string); - break; - default: - found = false; - break; - } - - ats_free(varName); - return found; -} - -// bool MgmtData::setFromName(const char*) -// -// Fills in class variables from the given -// variable name -// -// Returns true if the information could be set -// and false otherwise -// -bool -MgmtData::setFromName(const char *varName) -{ - bool found = true; - int err; - - err = RecGetRecordDataType((char *) varName, &this->type); - - if (err == REC_ERR_FAIL) { - return found; - } - - switch (this->type) { - case RECD_INT: - RecGetRecordInt((char *) varName, &this->data.rec_int); - break; - case RECD_COUNTER: - RecGetRecordCounter((char *) varName, &this->data.rec_counter); - break; - case RECD_FLOAT: - RecGetRecordFloat((char *) varName, &this->data.rec_float); - break; - case RECD_STRING: - RecGetRecordString_Xmalloc((char *) varName, &this->data.rec_string); - break; - case RECD_NULL: - default: - found = false; - break; - } - - return found; -} - -MgmtData::MgmtData() -{ - type = RECD_NULL; - memset(&data, 0, sizeof(RecData)); -} - -MgmtData::~MgmtData() -{ - if (type == RECD_STRING) - ats_free(data.rec_string); -} - -// MgmtData::compareFromString(const char* str, strLen) -// -// Compares the value of string converted to -// data type of this_>type with value -// held in this->data -// -bool -MgmtData::compareFromString(const char *str) -{ - RecData compData; - bool compare = false; - float floatDiff; - - switch (this->type) { - case RECD_INT: - // TODO: Add SI decimal multipliers rule ? - if (str && recordRegexCheck("^[0-9]+$", str)) { - compData.rec_int = ink_atoi64(str); - if (data.rec_int == compData.rec_int) { - compare = true; - } - } - break; - case RECD_COUNTER: - if (str && recordRegexCheck("^[0-9]+$", str)) { - compData.rec_counter = ink_atoi64(str); - if (data.rec_counter == compData.rec_counter) { - compare = true; - } - } - break; - case RECD_FLOAT: - compData.rec_float = atof(str); - // HACK - There are some rounding problems with - // floating point numbers so say we have a match if there difference - // is small - floatDiff = data.rec_float - compData.rec_float; - if (floatDiff > -0.001 && floatDiff < 0.001) { - compare = true; - } - break; - case RECD_STRING: - if (str == NULL || *str == '\0') { - if (data.rec_string == NULL) { - compare = true; - } - } else { - if ((data.rec_string != NULL) && (strcmp(str, data.rec_string) == 0)) { - compare = true; - } - } - break; - case RECD_NULL: - default: - compare = false; - break; - } - - return compare; -} - -// void RecDataT varType(const char* varName) -// -// Simply return the variable type -// -RecDataT -varType(const char *varName) -{ - RecDataT data_type; - int err; - - err = RecGetRecordDataType((char *) varName, &data_type); - - if (err == REC_ERR_FAIL) { - return RECD_NULL; - } - - Debug("RecOp", "[varType] %s is of type %d\n", varName, data_type); - return data_type; -} - - -// InkHashTable* processFormSubmission(char* submission) -// -// A generic way to handle a HTML form submission. -// Creates a hash table with name value pairs -// -// CALLEE must deallocate the returned hash table with -// ink_hash_table_destroy_and_xfree_values(InkHashTable *ht_ptr) -// - -InkHashTable * -processFormSubmission(char *submission) -{ - InkHashTable *nameVal = ink_hash_table_create(InkHashTableKeyType_String); - Tokenizer updates("&\n\r"); - Tokenizer pair("="); - int numUpdates; - char *name; - char *value; - char *submission_copy; - int pairNum; - - if (submission == NULL) { - ink_hash_table_destroy(nameVal); - return NULL; - } - - submission_copy = ats_strdup(submission); - numUpdates = updates.Initialize(submission_copy, SHARE_TOKS); - - for (int i = 0; i < numUpdates; i++) { - pairNum = pair.Initialize(updates[i]); - - // We should have gotten either either 1 or 2 tokens - // One token indicates an variable being set to - // blank. Two indicates the variable being set to - // a value. If the submission is invalid, just forget - // about it. - if (pairNum == 1 || pairNum == 2) { - name = ats_strdup(pair[0]); - substituteUnsafeChars(name); - - // If the value is blank, store it as a null - if (pairNum == 1) { - value = NULL; - } else { - value = ats_strdup(pair[1]); - substituteUnsafeChars(value); - } - - ink_hash_table_insert(nameVal, name, value); - ats_free(name); - } - } - ats_free(submission_copy); - - return nameVal; -} - -// InkHashTable* processFormSubmission_noSubstitute(char* submission) -// -// A generic way to handle a HTML form submission. -// Creates a hash table with name value pairs -// -// CALLEE must deallocate the returned hash table with -// ink_hash_table_destroy_and_xfree_values(InkHashTable *ht_ptr) -// -// Note: This function will _not_ substituteUnsafeChars() -InkHashTable * -processFormSubmission_noSubstitute(char *submission) -{ - - InkHashTable *nameVal = ink_hash_table_create(InkHashTableKeyType_String); - Tokenizer updates("&\n\r"); - Tokenizer pair("="); - int numUpdates; - char *name; - char *value; - char *submission_copy; - int pairNum; - - if (submission == NULL) { - ink_hash_table_destroy(nameVal); - return NULL; - } - - submission_copy = ats_strdup(submission); - numUpdates = updates.Initialize(submission_copy, SHARE_TOKS); - - for (int i = 0; i < numUpdates; i++) { - pairNum = pair.Initialize(updates[i]); - - // We should have gotten either either 1 or 2 tokens - // One token indicates an variable being set to - // blank. Two indicates the variable being set to - // a value. If the submission is invalid, just forget - // about it. - if (pairNum == 1 || pairNum == 2) { - name = ats_strdup(pair[0]); - - // If the value is blank, store it as a null - if (pairNum == 1) { - value = NULL; - } else { - value = ats_strdup(pair[1]); - } - - ink_hash_table_insert(nameVal, name, value); - ats_free(name); - } - } - ats_free(submission_copy); - - return nameVal; -} - -// -// Removes any cr/lf line breaks from the text data -// -int -convertHtmlToUnix(char *buffer) -{ - char *read = buffer; - char *write = buffer; - int numSub = 0; - - while (*read != '\0') { - if (*read == '\015') { - *write = ' '; - read++; - write++; - numSub++; - } else { - *write = *read; - write++; - read++; - } - } - *write = '\0'; - return numSub; -} - -// Substitutes HTTP unsafe character representations -// with their actual values. Modifies the passed -// in string -// -int -substituteUnsafeChars(char *buffer) -{ - char *read = buffer; - char *write = buffer; - char subStr[3]; - long charVal; - int numSub = 0; - - subStr[2] = '\0'; - while (*read != '\0') { - if (*read == '%') { - subStr[0] = *(++read); - subStr[1] = *(++read); - charVal = strtol(subStr, (char **) NULL, 16); - *write = (char) charVal; - read++; - write++; - numSub++; - } else if (*read == '+') { - *write = ' '; - write++; - read++; - } else { - *write = *read; - write++; - read++; - } - } - *write = '\0'; - return numSub; -} - -// Substitutes for characters that can be misconstrued -// as part of an HTML tag -// Allocates a new string which the -// the CALLEE MUST DELETE -// -char * -substituteForHTMLChars(const char *buffer) -{ - - char *safeBuf; // the return "safe" character buffer - char *safeCurrent; // where we are in the return buffer - const char *inCurrent = buffer; // where we are in the original buffer - int inLength = strlen(buffer); // how long the orig buffer in - - // Maximum character expansion is one to three - unsigned int bufferToAllocate = (inLength * 5) + 1; - safeBuf = new char[bufferToAllocate]; - safeCurrent = safeBuf; - - while (*inCurrent != '\0') { - switch (*inCurrent) { - case '"': - ink_strlcpy(safeCurrent, """, bufferToAllocate); - safeCurrent += 6; - break; - case '<': - ink_strlcpy(safeCurrent, "<", bufferToAllocate); - safeCurrent += 4; - break; - case '>': - ink_strlcpy(safeCurrent, ">", bufferToAllocate); - safeCurrent += 4; - break; - case '&': - ink_strlcpy(safeCurrent, "&", bufferToAllocate); - safeCurrent += 5; - break; - default: - *safeCurrent = *inCurrent; - safeCurrent += 1; - break; - } - - inCurrent++; - } - *safeCurrent = '\0'; - return safeBuf; -} - - -// bool ProxyShutdown() -// -// Attempts to turn the proxy off. Returns -// true if the proxy is off when the call returns -// and false if it is still on -// -bool -ProxyShutdown() -{ - int i = 0; - - // Check to make sure that we are not already down - if (!lmgmt->processRunning()) { - return true; - } - // Send the shutdown event - lmgmt->signalEvent(MGMT_EVENT_SHUTDOWN, "shutdown"); - - // Wait for awhile for shtudown to happen - do { - mgmt_sleep_sec(1); - i++; - } while (i < 10 && lmgmt->processRunning()); - - // See if we succeeded - if (lmgmt->processRunning()) { - return false; - } else { - return true; - } -} - -// -// -// Sets the LocalManager variable: proxy.node.hostname -// -// To the fully qualified hostname for the machine -// that we are running on -int -setHostnameVar() -{ - char ourHostName[MAXDNAME]; - char *firstDot; - - // Get Our HostName - if (gethostname(ourHostName, MAXDNAME) < 0) { - mgmt_fatal(stderr, errno, "[setHostnameVar] Can not determine our hostname"); - } - - res_init(); - appendDefaultDomain(ourHostName, MAXDNAME); - - // FQ is a Fully Qualified hostname (ie: proxydev.example.com) - varSetFromStr("proxy.node.hostname_FQ", ourHostName); - - // non-FQ is just the hostname (ie: proxydev) - firstDot = strchr(ourHostName, '.'); - if (firstDot != NULL) { - *firstDot = '\0'; - } - varSetFromStr("proxy.node.hostname", ourHostName); - - return 0; -} - -// void appendDefautDomain(char* hostname, int bufLength) -// -// Appends the pasted in hostname with the default -// domain if the hostname is an unqualified name -// -// The default domain is obtained from the resolver libraries -// data structure -// -// Truncates the domain name if bufLength is too small -// -// -void -appendDefaultDomain(char *hostname, int bufLength) -{ - - int len = strlen(hostname); - const char msg[] = "Nodes will be know by their unqualified host name"; - static int error_before = 0; // Race ok since effect is multple error msg - - ink_assert(len < bufLength); - ink_assert(bufLength >= 64); - - // Ensure null termination of the result string - hostname[bufLength - 1] = '\0'; - - if (strchr(hostname, '.') == NULL) { - if (_res.defdname[0] != '\0') { - if (bufLength - 2 >= (int) (strlen(hostname) + strlen(_res.defdname))) { - ink_strlcat(hostname, ".", bufLength); - ink_strlcat(hostname, _res.defdname, bufLength); - } else { - if (error_before == 0) { - mgmt_log(stderr, "%s %s\n", "[appendDefaultDomain] Domain name is too long.", msg); - error_before++; - } - } - } else { - if (error_before == 0) { - mgmt_log(stderr, "%s %s\n", "[appendDefaultDomain] Unable to determine default domain name.", msg); - error_before++; - } - } - } -} - -bool -recordValidityCheck(const char *varName, const char *value) -{ - RecCheckT check_t; - char *pattern; - - if (RecGetRecordCheckType((char *) varName, &check_t) != REC_ERR_OKAY) { - return false; - } - if (RecGetRecordCheckExpr((char *) varName, &pattern) != REC_ERR_OKAY) { - return false; - } - - switch (check_t) { - case RECC_STR: - if (recordRegexCheck(pattern, value)) { - return true; - } - break; - case RECC_INT: - if (recordRangeCheck(pattern, value)) { - return true; - } - break; - case RECC_IP: - if (recordIPCheck(pattern, value)) { - return true; - } - break; - case RECC_NULL: - // skip checking - return true; - default: - // unknown RecordCheckType... - mgmt_log(stderr, "[WebMgmtUtil] error, unknown RecordCheckType for record %s\n", varName); - } - - return false; - - -} - -bool -recordRegexCheck(const char *pattern, const char *value) -{ - pcre* regex; - const char* error; - int erroffset; - - regex = pcre_compile(pattern, 0, &error, &erroffset, NULL); - if (!regex) { - return false; - } else { - int r = pcre_exec(regex, NULL, value, strlen(value), 0, 0, NULL, 0); - - pcre_free(regex); - return (r != -1) ? true : false; - } - - return false; //no-op -} - -bool -recordRangeCheck(const char *pattern, const char *value) -{ - int l_limit; - int u_limit; - int val; - char *p = (char *) pattern; - Tokenizer dashTok("-"); - - if (recordRegexCheck("^[0-9]+$", value)) { - while (*p != '[') { - p++; - } // skip to '[' - if (dashTok.Initialize(++p, COPY_TOKS) == 2) { - l_limit = atoi(dashTok[0]); - u_limit = atoi(dashTok[1]); - val = atoi(value); - if (val >= l_limit && val <= u_limit) { - return true; - } - } - } - return false; -} - -bool -recordIPCheck(const char *pattern, const char *value) -{ - // regex_t regex; - // int result; - bool check; - const char *range_pattern = - "\\[[0-9]+\\-[0-9]+\\]\\\\\\.\\[[0-9]+\\-[0-9]+\\]\\\\\\.\\[[0-9]+\\-[0-9]+\\]\\\\\\.\\[[0-9]+\\-[0-9]+\\]"; - const char *ip_pattern = "[0-9]*[0-9]*[0-9].[0-9]*[0-9]*[0-9].[0-9]*[0-9]*[0-9].[0-9]*[0-9]*[0-9]"; - - Tokenizer dotTok1("."); - Tokenizer dotTok2("."); - int i; - - check = true; - if (recordRegexCheck(range_pattern, pattern) && recordRegexCheck(ip_pattern, value)) { - if (dotTok1.Initialize((char *) pattern, COPY_TOKS) == 4 && dotTok2.Initialize((char *) value, COPY_TOKS) == 4) { - for (i = 0; i < 4 && check; i++) { - if (!recordRangeCheck(dotTok1[i], dotTok2[i])) { - check = false; - } - } - if (check) { - return true; - } - } - } else if (strcmp(value, "") == 0) { - return true; - } - return false; -} - -bool -recordRestartCheck(const char *varName) -{ - - RecUpdateT update_t; - - if (RecGetRecordUpdateType((char *) varName, &update_t) != REC_ERR_OKAY) { - return false; - } - - if (update_t == RECU_RESTART_TS || update_t == RECU_RESTART_TM || update_t == RECU_RESTART_TC) { - return true; - } - - return false; - -} - -void -fileCheckSum(char *buffer, int size, char *checksum, const size_t checksumSize) -{ - INK_DIGEST_CTX md5_context; - char checksum_md5[16]; - - ink_code_incr_md5_init(&md5_context); - ink_code_incr_md5_update(&md5_context, buffer, size); - ink_code_incr_md5_final(checksum_md5, &md5_context); - ink_code_md5_stringify(checksum, checksumSize, checksum_md5); -} - -//------------------------------------------------------------------------- -// getFilesInDirectory -// -// copied from MultiFiles::WalkFiles - but slightly modified -// returns -1 if directory does not exit -// returns 1 if everything is ok -//------------------------------------------------------------------------- -int -getFilesInDirectory(char *managedDir, ExpandingArray * fileList) -{ - struct dirent *dirEntry; - DIR *dir; - - char *fileName; - char *filePath; - struct stat fileInfo; - // struct stat records_config_fileInfo; - fileEntry *fileListEntry; - - if ((dir = opendir(managedDir)) == NULL) { - mgmt_log(stderr, "[getFilesInDirectory] Unable to open %s directory: %s\n", managedDir, strerror(errno)); - return -1; - } - // The fun of Solaris - readdir_r requires a buffer passed into it - // The man page says this obscene expression gives us the proper - // size - dirEntry = (struct dirent *)alloca(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1); - - struct dirent *result; - while (readdir_r(dir, dirEntry, &result) == 0) { - if (!result) - break; - fileName = dirEntry->d_name; - if (!fileName || !*fileName) { - continue; - } - filePath = newPathString(managedDir, fileName); - if (stat(filePath, &fileInfo) < 0) { - mgmt_log(stderr, "[getFilesInDirectory] Stat of a %s failed : %s\n", fileName, strerror(errno)); - } else { - // Ignore ., .., and any dot files - if (fileName && *fileName != '.') { - fileListEntry = (fileEntry *)ats_malloc(sizeof(fileEntry)); - fileListEntry->c_time = fileInfo.st_ctime; - ink_strlcpy(fileListEntry->name, fileName, sizeof(fileListEntry->name)); - fileList->addEntry(fileListEntry); - } - } - delete[]filePath; - } - - closedir(dir); - - fileList->sortWithFunction(fileEntryCmpFunc); - return 1; -} - -//------------------------------------------------------------------------- -// newPathString -// -// copied from MultiFile::newPathString -// Note: uses C++ new/delete for memory allocation/deallocation -//------------------------------------------------------------------------- -char * -newPathString(const char *s1, const char *s2) -{ - char *newStr; - int srcLen; // is the length of the src rootpath - int addLen; // maximum total path length - - // Treat null as an empty path. - if (!s2) - s2 = ""; - addLen = strlen(s2) + 1; - if (*s2 == '/') { - // If addpath is rooted, then rootpath is unused. - newStr = new char[addLen]; - ink_strlcpy(newStr, s2, addLen); - return newStr; - } - if (!s1 || !*s1) { - // If there's no rootpath return the addpath - newStr = new char[addLen]; - ink_strlcpy(newStr, s2, addLen); - return newStr; - } - srcLen = strlen(s1); - newStr = new char[srcLen + addLen + 1]; - ink_assert(newStr != NULL); - - ink_strlcpy(newStr, s1, srcLen + addLen + 1); - if (newStr[srcLen - 1] != '/') - newStr[srcLen++] = '/'; - ink_strlcpy(&newStr[srcLen], s2, srcLen + addLen + 1); - - return newStr; -} http://git-wip-us.apache.org/repos/asf/trafficserver/blob/82deca40/mgmt/utils/WebMgmtUtils.h ---------------------------------------------------------------------- diff --git a/mgmt/utils/WebMgmtUtils.h b/mgmt/utils/WebMgmtUtils.h deleted file mode 100644 index 503aec5..0000000 --- a/mgmt/utils/WebMgmtUtils.h +++ /dev/null @@ -1,124 +0,0 @@ -/** @file - - A brief file description - - @section license License - - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (the - "License"); you may not use this file except in compliance - with the License. You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - */ - -#ifndef _WEB_MGMT_UTILS_ -#define _WEB_MGMT_UTILS_ - -#include "MgmtDefs.h" - -/**************************************************************************** - * - * WebMgmtUtils.h - Functions for interfacing to management records - * - * - * - ****************************************************************************/ - -#include "ink_hash_table.h" -#include "TextBuffer.h" -#include "ExpandingArray.h" - -#include "P_RecCore.h" - -// class MgmtData - stores information from local manager -// variables in its native type -// -#include "P_RecCore.h" -class MgmtData -{ -public: - MgmtData(); - ~MgmtData(); - bool compareFromString(const char *str); - bool setFromName(const char *varName); - RecDataT type; - RecData data; -}; - -// Convert to byte units (GB, MB, KB) -void bytesFromInt(RecInt bytes, char *bufVal); - -// Convert to MB -void MbytesFromInt(RecInt bytes, char *bufVal); - -// Create comma string from int -void commaStrFromInt(RecInt bytes, char *bufVal); - -// Create percent string from float -void percentStrFromFloat(RecFloat val, char *bufVal); - -// All types converted to/from strings where appropriate -bool varStrFromName(const char *varName, char *bufVal, int bufLen); -bool varSetFromStr(const char *varName, const char *value); - -// Converts where applicable to specified type -bool varIntFromName(const char *varName, RecInt * value); -bool varFloatFromName(const char *varName, RecFloat * value); -bool varCounterFromName(const char *varName, RecCounter * value); -bool varDataFromName(RecDataT varType, const char *varName, RecData *value); - -// No conversion done. varName must represnt a value of the appropriate -// type -// Default arguement "convert" added to allow great flexiblity in type checking -bool varSetInt(const char *varName, RecInt value, bool convert = false); -bool varSetCounter(const char *varName, RecCounter value, bool convert = false); -bool varSetFloat(const char *varName, RecFloat value, bool convert = false); -bool varSetData(RecDataT varType, const char *varName, RecData value); - -// Return the type of the variable named -RecDataT varType(const char *varName); - -int convertHtmlToUnix(char *buffer); -int substituteUnsafeChars(char *buffer); -char *substituteForHTMLChars(const char *buffer); - -// Produce a hash table based on a HTML form submission -// -// CALLEE deallocates hashtable -InkHashTable *processFormSubmission(char *submission); -InkHashTable *processFormSubmission_noSubstitute(char *submission); - -// Shutdown the proxy -bool ProxyShutdown(); -int setHostnameVar(); -void appendDefaultDomain(char *hostname, int bufLength); - -// Some scaling constants -#define BYTES_TO_MB_SCALE (1/(1024*1024.0)) -#define MBIT_TO_KBIT_SCALE (1000.0) -#define SECOND_TO_MILLISECOND_SCALE (1000.0) -#define PCT_TO_INTPCT_SCALE (100.0) - -bool recordValidityCheck(const char *varName, const char *value); -bool recordRegexCheck(const char *pattern, const char *value); -bool recordRangeCheck(const char *pattern, const char *value); -bool recordIPCheck(const char *pattern, const char *value); -bool recordRestartCheck(const char *varName); - -void fileCheckSum(char *buffer, int size, char *checksum, const size_t checksumSize); - -// file management -int getFilesInDirectory(char *managedDir, ExpandingArray * fileList); -char *newPathString(const char *s1, const char *s2); - -#endif
