3
A brief file description
5
@section license License
7
Licensed to the Apache Software Foundation (ASF) under one
8
or more contributor license agreements. See the NOTICE file
9
distributed with this work for additional information
10
regarding copyright ownership. The ASF licenses this file
11
to you under the Apache License, Version 2.0 (the
12
"License"); you may not use this file except in compliance
13
with the License. You may obtain a copy of the License at
15
http://www.apache.org/licenses/LICENSE-2.0
17
Unless required by applicable law or agreed to in writing, software
18
distributed under the License is distributed on an "AS IS" BASIS,
19
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
See the License for the specific language governing permissions and
21
limitations under the License.
24
#include "ink_platform.h"
26
#include "ink_assert.h"
27
#include "ink_resource.h"
28
#include "ink_error.h"
30
#include "ink_string.h"
32
#include "ink_unused.h"
34
#include "Compatability.h"
35
#include "MgmtUtils.h"
36
#include "MultiFile.h"
37
#include "ExpandingArray.h"
38
#include "TextBuffer.h"
39
#include "WebMgmtUtils.h"
41
/****************************************************************************
43
* MultiFile.cc - base class to handle reading and displaying config
44
* files and directories
47
****************************************************************************/
49
MultiFile::MultiFile()
55
// void MultiFile::addTableEntries(ExpandingArray* fileList, textBuffer* output)
57
// Adds table entries to output from the result of WalkFiles
60
MultiFile::addTableEntries(ExpandingArray * fileList, textBuffer * output)
62
int numFiles = fileList->getNumEntries();
66
const char dataOpen[] = "\t<td>";
67
const char dataClose[] = "</td>\n";
68
const int dataOpenLen = strlen(dataOpen);
69
const int dataCloseLen = strlen(dataClose);
71
for (int i = 0; i < numFiles; i++) {
72
current = (fileEntry *) ((*fileList)[i]);
74
output->copyFrom("<tr>\n", 5);
75
output->copyFrom(dataOpen, dataOpenLen);
76
safeName = substituteForHTMLChars(current->name);
77
output->copyFrom(safeName, strlen(safeName));
79
output->copyFrom(dataClose, dataCloseLen);
80
output->copyFrom(dataOpen, dataOpenLen);
82
if (ink_ctime_r(¤t->c_time, dateBuf) == NULL) {
83
ink_strncpy(dateBuf, "<em>No time-stamp</em>", sizeof(dateBuf));
85
output->copyFrom(dateBuf, strlen(dateBuf));
86
output->copyFrom(dataClose, dataCloseLen);
87
output->copyFrom("</tr>\n", 6);
92
// Mfresult MultiFile::WalkFiles(ExpandingArray* fileList)
94
// Iterates through the managed directory and adds every managed file
95
// into the parameter snapList
99
MultiFile::WalkFiles(ExpandingArray * fileList)
102
struct dirent *dirEntry;
106
WIN32_FIND_DATA W32FD;
110
char *records_config_filePath = NULL;
111
struct stat fileInfo;
112
struct stat records_config_fileInfo;
113
fileEntry *fileListEntry;
116
if ((dir = opendir(managedDir)) == NULL) {
117
mgmt_log(stderr, "[MultiFile::WalkFiles] Unable to open %s directory: %s: %s\n",
118
dirDescript, managedDir, strerror(errno));
121
// The fun of Solaris - readdir_r requires a buffer passed into it
122
// The man page says this obscene expression gives us the proper
124
dirEntry = (struct dirent *) xmalloc(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1);
126
struct dirent *result;
127
while (readdir_r(dir, dirEntry, &result) == 0) {
130
fileName = dirEntry->d_name;
131
filePath = newPathString(managedDir, fileName);
132
records_config_filePath = newPathString(filePath, "records.config");
133
if (stat(filePath, &fileInfo) < 0) {
134
mgmt_log(stderr, "[MultiFile::WalkFiles] Stat of a %s failed %s: %s\n", dirDescript, fileName, strerror(errno));
136
if (stat(records_config_filePath, &records_config_fileInfo) < 0) {
140
// Ignore ., .., and any dot files
141
if (*fileName != '.' && isManaged(fileName)) {
142
fileListEntry = (fileEntry *) xmalloc(sizeof(fileEntry));
143
fileListEntry->c_time = fileInfo.st_ctime;
144
ink_strncpy(fileListEntry->name, fileName, sizeof(fileListEntry->name));
145
fileList->addEntry(fileListEntry);
154
// Append '\*' as a wildcard for FindFirstFile()
155
searchPattern = newPathString(managedDir, "*");
156
HANDLE hDInfo = FindFirstFile(searchPattern, &W32FD);
158
if (INVALID_HANDLE_VALUE == hDInfo) {
159
mgmt_log(stderr, "[MultiFile::WalkFiles] FindFirstFile failed for %s: %s\n", searchPattern, ink_last_err());
160
delete[]searchPattern;
163
delete[]searchPattern;
165
while (FindNextFile(hDInfo, &W32FD)) {
166
fileName = W32FD.cFileName;
167
filePath = newPathString(managedDir, fileName);
168
if (stat(filePath, &fileInfo) < 0) {
169
mgmt_log(stderr, "[MultiFile::WalkFiles] Stat of a %s failed %s: %s\n", dirDescript, fileName, strerror(errno));
171
// Ignore ., .., and any dot files
172
if (*fileName != '.' && isManaged(fileName)) {
173
fileListEntry = (fileEntry *) xmalloc(sizeof(fileEntry));
174
fileListEntry->c_time = fileInfo.st_ctime;
175
strcpy(fileListEntry->name, fileName);
176
fileList->addEntry(fileListEntry);
185
fileList->sortWithFunction(fileEntryCmpFunc);
186
delete[]records_config_filePath;
192
MultiFile::isManaged(const char *fileName)
194
if (fileName == NULL) {
202
MultiFile::addSelectOptions(textBuffer * output, ExpandingArray * options)
204
const char selectEnd[] = "</select>\n";
205
const char option[] = "\t<option value='";
206
const int optionLen = strlen(option);
207
const char option_end[] = "'>";
210
int numOptions = options->getNumEntries();
212
for (int i = 0; i < numOptions; i++) {
213
output->copyFrom(option, optionLen);
214
safeCurrent = substituteForHTMLChars((char *) ((*options)[i]));
215
output->copyFrom(safeCurrent, strlen(safeCurrent));
216
output->copyFrom(option_end, strlen(option_end));
217
output->copyFrom(safeCurrent, strlen(safeCurrent));
219
output->copyFrom("\n", 1);
221
output->copyFrom(selectEnd, strlen(selectEnd));
224
// int fileEntryCmpFunc(void* e1, void* e2)
226
// a cmp function for fileEntry structs that can
232
fileEntryCmpFunc(const void *e1, const void *e2)
234
fileEntry *entry1 = (fileEntry *) * (void **) e1;
235
fileEntry *entry2 = (fileEntry *) * (void **) e2;
237
if (entry1->c_time > entry2->c_time) {
239
} else if (entry1->c_time < entry2->c_time) {
246
// char* MultiFile::newPathString(const char* s1, const char* s2)
248
// creates a new string that is composed of s1/s2
249
// Callee is responsible for deleting storage
250
// Method makes sure there is no double slash between s1 and s2
251
// The code is borrowed from ink_filepath_make with dynamic allocation.
254
MultiFile::newPathString(const char *s1, const char *s2)
257
int srcLen; // is the length of the src rootpath
258
int addLen; // maximum total path length
260
// Treat null as an empty path.
263
addLen = strlen(s2) + 1;
265
// If addpath is rooted, then rootpath is unused.
266
newStr = new char[addLen];
271
// If there's no rootpath return the addpath
272
newStr = new char[addLen];
277
newStr = new char[srcLen + addLen + 1];
278
ink_assert(newStr != NULL);
281
if (newStr[srcLen - 1] != '/')
282
newStr[srcLen++] = '/';
283
strcpy(&newStr[srcLen], s2);