~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to proxy/mgmt2/MultiFile.cc

  • Committer: Bazaar Package Importer
  • Author(s): Arno Toell
  • Date: 2011-01-13 11:49:18 UTC
  • Revision ID: james.westby@ubuntu.com-20110113114918-vu422h8dknrgkj15
Tags: upstream-2.1.5-unstable
ImportĀ upstreamĀ versionĀ 2.1.5-unstable

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/** @file
 
2
 
 
3
  A brief file description
 
4
 
 
5
  @section license License
 
6
 
 
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
 
14
 
 
15
      http://www.apache.org/licenses/LICENSE-2.0
 
16
 
 
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.
 
22
 */
 
23
 
 
24
#include "ink_platform.h"
 
25
#include "ink_port.h"
 
26
#include "ink_assert.h"
 
27
#include "ink_resource.h"
 
28
#include "ink_error.h"
 
29
#include "ink_file.h"
 
30
#include "ink_string.h"
 
31
#include "ink_time.h"
 
32
#include "ink_unused.h"
 
33
 
 
34
#include "Compatability.h"
 
35
#include "MgmtUtils.h"
 
36
#include "MultiFile.h"
 
37
#include "ExpandingArray.h"
 
38
#include "TextBuffer.h"
 
39
#include "WebMgmtUtils.h"
 
40
 
 
41
/****************************************************************************
 
42
 *
 
43
 *  MultiFile.cc - base class to handle reading and displaying config
 
44
 *                 files and directories
 
45
 *
 
46
 *
 
47
 ****************************************************************************/
 
48
 
 
49
MultiFile::MultiFile()
 
50
{
 
51
  managedDir = NULL;
 
52
  dirDescript = NULL;
 
53
}
 
54
 
 
55
// void MultiFile::addTableEntries(ExpandingArray* fileList, textBuffer* output)
 
56
//
 
57
//   Adds table entries to output from the result of WalkFiles
 
58
//
 
59
void
 
60
MultiFile::addTableEntries(ExpandingArray * fileList, textBuffer * output)
 
61
{
 
62
  int numFiles = fileList->getNumEntries();
 
63
  fileEntry *current;
 
64
  char *safeName;
 
65
  char dateBuf[64];
 
66
  const char dataOpen[] = "\t<td>";
 
67
  const char dataClose[] = "</td>\n";
 
68
  const int dataOpenLen = strlen(dataOpen);
 
69
  const int dataCloseLen = strlen(dataClose);
 
70
 
 
71
  for (int i = 0; i < numFiles; i++) {
 
72
    current = (fileEntry *) ((*fileList)[i]);
 
73
 
 
74
    output->copyFrom("<tr>\n", 5);
 
75
    output->copyFrom(dataOpen, dataOpenLen);
 
76
    safeName = substituteForHTMLChars(current->name);
 
77
    output->copyFrom(safeName, strlen(safeName));
 
78
    delete[]safeName;
 
79
    output->copyFrom(dataClose, dataCloseLen);
 
80
    output->copyFrom(dataOpen, dataOpenLen);
 
81
 
 
82
    if (ink_ctime_r(&current->c_time, dateBuf) == NULL) {
 
83
      ink_strncpy(dateBuf, "<em>No time-stamp</em>", sizeof(dateBuf));
 
84
    }
 
85
    output->copyFrom(dateBuf, strlen(dateBuf));
 
86
    output->copyFrom(dataClose, dataCloseLen);
 
87
    output->copyFrom("</tr>\n", 6);
 
88
  }
 
89
 
 
90
}
 
91
 
 
92
// Mfresult MultiFile::WalkFiles(ExpandingArray* fileList)
 
93
//
 
94
//   Iterates through the managed directory and adds every managed file
 
95
//     into the parameter snapList
 
96
//
 
97
 
 
98
MFresult
 
99
MultiFile::WalkFiles(ExpandingArray * fileList)
 
100
{
 
101
#ifndef _WIN32
 
102
  struct dirent *dirEntry;
 
103
  DIR *dir;
 
104
#else
 
105
  char *searchPattern;
 
106
  WIN32_FIND_DATA W32FD;
 
107
#endif
 
108
  char *fileName;
 
109
  char *filePath;
 
110
  char *records_config_filePath = NULL;
 
111
  struct stat fileInfo;
 
112
  struct stat records_config_fileInfo;
 
113
  fileEntry *fileListEntry;
 
114
 
 
115
#ifndef _WIN32
 
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));
 
119
    return MF_NO_DIR;
 
120
  }
 
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
 
123
  //     size
 
124
  dirEntry = (struct dirent *) xmalloc(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1);
 
125
 
 
126
  struct dirent *result;
 
127
  while (readdir_r(dir, dirEntry, &result) == 0) {
 
128
    if (!result)
 
129
      break;
 
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));
 
135
    } else {
 
136
      if (stat(records_config_filePath, &records_config_fileInfo) < 0) {
 
137
        delete[]filePath;
 
138
        continue;
 
139
      }
 
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);
 
146
      }
 
147
    }
 
148
    delete[]filePath;
 
149
  }
 
150
 
 
151
  xfree(dirEntry);
 
152
  closedir(dir);
 
153
#else
 
154
  // Append '\*' as a wildcard for FindFirstFile()
 
155
  searchPattern = newPathString(managedDir, "*");
 
156
  HANDLE hDInfo = FindFirstFile(searchPattern, &W32FD);
 
157
 
 
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;
 
161
    return MF_NO_DIR;
 
162
  }
 
163
  delete[]searchPattern;
 
164
 
 
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));
 
170
    } else {
 
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);
 
177
      }
 
178
    }
 
179
    delete[]filePath;
 
180
  }
 
181
 
 
182
  FindClose(hDInfo);
 
183
#endif
 
184
 
 
185
  fileList->sortWithFunction(fileEntryCmpFunc);
 
186
  delete[]records_config_filePath;
 
187
  return MF_OK;
 
188
}
 
189
 
 
190
 
 
191
bool
 
192
MultiFile::isManaged(const char *fileName)
 
193
{
 
194
  if (fileName == NULL) {
 
195
    return false;
 
196
  } else {
 
197
    return true;
 
198
  }
 
199
}
 
200
 
 
201
void
 
202
MultiFile::addSelectOptions(textBuffer * output, ExpandingArray * options)
 
203
{
 
204
  const char selectEnd[] = "</select>\n";
 
205
  const char option[] = "\t<option value='";
 
206
  const int optionLen = strlen(option);
 
207
  const char option_end[] = "'>";
 
208
  char *safeCurrent;
 
209
 
 
210
  int numOptions = options->getNumEntries();
 
211
 
 
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));
 
218
    delete[]safeCurrent;
 
219
    output->copyFrom("\n", 1);
 
220
  }
 
221
  output->copyFrom(selectEnd, strlen(selectEnd));
 
222
}
 
223
 
 
224
//  int fileEntryCmpFunc(void* e1, void* e2)
 
225
//
 
226
//  a cmp function for fileEntry structs that can
 
227
//     used with qsort
 
228
//
 
229
//  compares c_time
 
230
//
 
231
int
 
232
fileEntryCmpFunc(const void *e1, const void *e2)
 
233
{
 
234
  fileEntry *entry1 = (fileEntry *) * (void **) e1;
 
235
  fileEntry *entry2 = (fileEntry *) * (void **) e2;
 
236
 
 
237
  if (entry1->c_time > entry2->c_time) {
 
238
    return 1;
 
239
  } else if (entry1->c_time < entry2->c_time) {
 
240
    return -1;
 
241
  } else {
 
242
    return 0;
 
243
  }
 
244
}
 
245
 
 
246
// char* MultiFile::newPathString(const char* s1, const char* s2)
 
247
//
 
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.
 
252
//
 
253
char *
 
254
MultiFile::newPathString(const char *s1, const char *s2)
 
255
{
 
256
  char *newStr;
 
257
  int  srcLen; // is the length of the src rootpath
 
258
  int  addLen; // maximum total path length
 
259
 
 
260
  // Treat null as an empty path.
 
261
  if (!s2)
 
262
    s2 = "";
 
263
  addLen = strlen(s2) + 1;
 
264
  if (*s2 == '/') {
 
265
    // If addpath is rooted, then rootpath is unused.
 
266
    newStr = new char[addLen];
 
267
    strcpy(newStr, s2);
 
268
    return newStr;
 
269
  }
 
270
  if (!s1 || !*s1) {
 
271
    // If there's no rootpath return the addpath
 
272
    newStr = new char[addLen];
 
273
    strcpy(newStr, s2);
 
274
    return newStr;
 
275
  }
 
276
  srcLen = strlen(s1);
 
277
  newStr = new char[srcLen + addLen + 1];
 
278
  ink_assert(newStr != NULL);
 
279
 
 
280
  strcpy(newStr, s1);
 
281
  if (newStr[srcLen - 1] != '/')
 
282
    newStr[srcLen++] = '/';
 
283
  strcpy(&newStr[srcLen], s2);
 
284
 
 
285
  return newStr;
 
286
}