~ps10gel/ubuntu/xenial/trafficserver/6.2.0

« back to all changes in this revision

Viewing changes to proxy/mgmt2/web2/WebHttp.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
 /***************************************/
 
25
/****************************************************************************
 
26
 *
 
27
 *  WebHttp.cc - code to process requests, and create responses
 
28
 *
 
29
 *
 
30
 ****************************************************************************/
 
31
 
 
32
#include "libts.h"
 
33
#include "ink_platform.h"
 
34
#include "ink_unused.h" /* MAGIC_EDITING_TAG */
 
35
 
 
36
#include "SimpleTokenizer.h"
 
37
 
 
38
#include "WebCompatibility.h"
 
39
#include "WebHttp.h"
 
40
#include "WebHttpAuth.h"
 
41
#include "WebHttpContext.h"
 
42
#include "WebHttpLog.h"
 
43
#include "WebHttpMessage.h"
 
44
#include "WebHttpRender.h"
 
45
#include "WebHttpSession.h"
 
46
#include "WebHttpTree.h"
 
47
#include "WebOverview.h"
 
48
#include "WebConfig.h"
 
49
 
 
50
#include "INKMgmtAPI.h"
 
51
//#include "I_AccCrypto.h"
 
52
#include "LocalManager.h"
 
53
#include "WebMgmtUtils.h"
 
54
#include "MgmtUtils.h"
 
55
#include "EnvBlock.h"
 
56
#include "CfgContextUtils.h"
 
57
 
 
58
#include "ConfigAPI.h"
 
59
#include "SysAPI.h"
 
60
 
 
61
#include "openssl/ssl.h"
 
62
#include "openssl/err.h"
 
63
#include "openssl/crypto.h"
 
64
#if !defined(_WIN32)
 
65
// Ugly hack - define HEAP_H and STACK_H to prevent stuff from the
 
66
// template library from being included which SUNPRO CC does not not
 
67
// like.
 
68
#define HEAP_H
 
69
#define STACK_H
 
70
#endif // !defined(_WIN32)
 
71
 
 
72
 
 
73
//-------------------------------------------------------------------------
 
74
// defines
 
75
//-------------------------------------------------------------------------
 
76
 
 
77
#ifndef _WIN32
 
78
#define DIR_MODE S_IRWXU
 
79
#define FILE_MODE S_IRWXU
 
80
#else
 
81
#define FILE_MODE S_IWRITE
 
82
#endif
 
83
 
 
84
#define MAX_ARGS         10
 
85
#define MAX_TMP_BUF_LEN  1024
 
86
 
 
87
#define MAX_ADD_RULES    50     // update c_config_display.ink
 
88
 
 
89
//-------------------------------------------------------------------------
 
90
// types
 
91
//-------------------------------------------------------------------------
 
92
 
 
93
typedef int (*WebHttpHandler) (WebHttpContext * whc, const char *file);
 
94
 
 
95
//-------------------------------------------------------------------------
 
96
// globals
 
97
//-------------------------------------------------------------------------
 
98
 
 
99
// only allow access to specific files on the autoconf port
 
100
static InkHashTable *g_autoconf_allow_ht = 0;
 
101
 
 
102
static InkHashTable *g_submit_bindings_ht = 0;
 
103
static InkHashTable *g_file_bindings_ht = 0;
 
104
static InkHashTable *g_extn_bindings_ht = 0;
 
105
 
 
106
InkHashTable *g_display_config_ht = 0;
 
107
 
 
108
//-------------------------------------------------------------------------
 
109
// prototypes
 
110
//-------------------------------------------------------------------------
 
111
 
 
112
void spawn_script(WebHttpContext * whc, char *script, char **args);
 
113
 
 
114
//-------------------------------------------------------------------------
 
115
// record_version_valid
 
116
//-------------------------------------------------------------------------
 
117
 
 
118
static bool
 
119
record_version_valid(char *record_version)
 
120
{
 
121
  int old_version, old_pid, cur_version;
 
122
  // coverity[secure_coding]
 
123
  if (sscanf(record_version, "%d:%d", &old_pid, &old_version) == 2 && old_version >= 0) {
 
124
    cur_version = RecGetRecordUpdateCount(RECT_CONFIG);
 
125
    //fix me --> lmgmt->record_data->pid
 
126
    // TODO: need to check the PID ??
 
127
    //    if (cur_version != old_version || lmgmt->record_data->pid != old_pid) {
 
128
    if (cur_version != old_version) {
 
129
      // we are out of date since the version number has been incremented
 
130
      return false;
 
131
    } else {
 
132
      return true;
 
133
    }
 
134
  }
 
135
  // bad format, return false to be safe
 
136
  return false;
 
137
}
 
138
 
 
139
//-------------------------------------------------------------------------
 
140
// set_record_value
 
141
//-------------------------------------------------------------------------
 
142
 
 
143
static bool
 
144
set_record_value(WebHttpContext * whc, const char *rec, const char *value)
 
145
{
 
146
  MgmtData varValue;
 
147
  char *record;
 
148
  char *script = NULL;
 
149
  char *script_path;
 
150
 
 
151
  if (rec == NULL) {
 
152
    return false;
 
153
  }
 
154
  if (value == NULL) {
 
155
    value = "";
 
156
  }
 
157
  // INKqa11771: exec script that associates with a record
 
158
  record = xstrdup(rec);
 
159
  if ((script = strchr(record, ':'))) {
 
160
    *script = '\0';
 
161
    script++;
 
162
  }
 
163
  // FIXME: If someone else has already added a NOTE or WARN, then we
 
164
  // won't be able to add anymore.  This is desired for
 
165
  // handle_submit_update, but going forward, we'll need a more
 
166
  // general mechanism.
 
167
 
 
168
  varValue.setFromName(record);
 
169
  if (varValue.compareFromString(value) == false) {
 
170
    if (recordValidityCheck(record, value)) {
 
171
      if (recordRestartCheck(record)) {
 
172
        ink_hash_table_insert(whc->submit_note_ht, record, NULL);
 
173
        if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_NOTE)) {
 
174
          HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_RESTART_REQUIRED);
 
175
          HtmlRndrBr(whc->submit_note);
 
176
        }
 
177
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
 
178
      }
 
179
      varSetFromStr(record, value);
 
180
 
 
181
#ifndef _WIN32
 
182
      if (script) {
 
183
        const char *args[MAX_ARGS + 1];
 
184
        for (int i = 0; i < MAX_ARGS; i++)
 
185
          args[i] = NULL;
 
186
        script_path = WebHttpAddDocRoot_Xmalloc(whc, script);
 
187
        args[0] = script_path;
 
188
        args[1] = value;
 
189
        processSpawn(&args[0], NULL, NULL, NULL, false, false);
 
190
        xfree(script_path);
 
191
      }
 
192
#endif
 
193
    } else {
 
194
      ink_hash_table_insert(whc->submit_warn_ht, record, NULL);
 
195
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
196
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
 
197
        HtmlRndrBr(whc->submit_warn);
 
198
      }
 
199
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
200
    }
 
201
  }
 
202
  xfree(record);
 
203
  return true;
 
204
}
 
205
 
 
206
//-------------------------------------------------------------------------
 
207
// set_config_file
 
208
//-------------------------------------------------------------------------
 
209
 
 
210
static bool
 
211
set_config_file(WebHttpContext * whc, char *file_version, char *file_contents, char *file_checksum)
 
212
{
 
213
 
 
214
  bool err = true;
 
215
 
 
216
  Rollback *rb;
 
217
  textBuffer *tb;
 
218
  version_t fversion;
 
219
  char frecord[MAX_VAR_LENGTH + 1];
 
220
  char fname[MAX_VAL_LENGTH + 1];
 
221
  char checksum[MAX_CHECKSUM_LENGTH + 1];
 
222
  int file_size;
 
223
 
 
224
  // coverity[secure_coding]
 
225
  if (sscanf(file_version, "%d:%s", &fversion, frecord) == 2) {
 
226
    if (varStrFromName(frecord, fname, MAX_VAL_LENGTH)) {
 
227
      if (configFiles->getRollbackObj(fname, &rb)) {
 
228
        // INKqa12198: remove ^M (CR) from each line in file_contents
 
229
        convertHtmlToUnix(file_contents);
 
230
        file_size = strlen(file_contents);
 
231
        tb = NEW(new textBuffer(file_size + 1));
 
232
        tb->copyFrom(file_contents, file_size); //orig
 
233
 
 
234
        // calculate checksum - skip file update if match checksum
 
235
        fileCheckSum(tb->bufPtr(), tb->spaceUsed(), checksum, sizeof(checksum));
 
236
        if (strcmp(file_checksum, checksum) != 0) {
 
237
          if (rb->updateVersion(tb, fversion) != OK_ROLLBACK) {
 
238
            err = false;
 
239
          }
 
240
          // put note if file update required restart
 
241
          if (recordRestartCheck(frecord)) {
 
242
            ink_hash_table_insert(whc->submit_note_ht, frecord, NULL);
 
243
            if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_NOTE)) {
 
244
              HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_RESTART_REQUIRED);
 
245
              HtmlRndrBr(whc->submit_note);
 
246
            }
 
247
            whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
 
248
          }
 
249
        }
 
250
        delete tb;
 
251
      }
 
252
    }
 
253
  }
 
254
  return err;
 
255
}
 
256
 
 
257
//-------------------------------------------------------------------------
 
258
// spawn_cgi
 
259
//-------------------------------------------------------------------------
 
260
 
 
261
#if defined(_WIN32)
 
262
 
 
263
// adjustCmdLine
 
264
//
 
265
// This function is used for constructing a command line from a CGI
 
266
// scripting program because Windows doesn't know how to execute a
 
267
// script.  For example, instead of executing "blacklist.cgi", we need
 
268
// to tell Windows to execute "perl.exe blacklist.cgi".
 
269
 
 
270
static void
 
271
adjustCmdLine(char *cmdLine, int cmdline_len, const char *cgiFullPath)
 
272
{
 
273
  char line[1024 + 1];
 
274
  char *interpreter = NULL;
 
275
 
 
276
  FILE *f = fopen(cgiFullPath, "r");
 
277
  if (f != NULL) {
 
278
    if (fgets(line, 1024, f) != NULL) {
 
279
      int n = strlen(line);
 
280
      if (n > 2 && strncmp(line, "#!", 2) == 0 && line[n - 1] == '\n') {
 
281
        line[n - 1] = '\0';
 
282
        interpreter = line + 2;
 
283
      }
 
284
    }
 
285
    fclose(f);
 
286
  }
 
287
 
 
288
  if (interpreter) {
 
289
    snprintf(cmdLine, cmdline_len, "\"%s\" \"%s\"", interpreter, cgiFullPath);
 
290
  } else {
 
291
    ink_strncpy(cmdLine, cgiFullPath, cmdline_len);
 
292
  }
 
293
  return;
 
294
}
 
295
 
 
296
#endif
 
297
 
 
298
int
 
299
spawn_cgi(WebHttpContext * whc, const char *cgi_path, char **args, bool nowait, bool run_as_root)
 
300
{
 
301
 
 
302
  struct stat info;
 
303
  const char *query_string;
 
304
  textBuffer query_string_tb(MAX_TMP_BUF_LEN);
 
305
  int qlen = 0;
 
306
  char content_length_buffer[10];
 
307
  EnvBlock env;
 
308
  bool success = false;
 
309
  const char *a[MAX_ARGS + 2];
 
310
  int i;
 
311
 
 
312
  httpMessage *request = whc->request;
 
313
  textBuffer *replyMsg = whc->response_bdy;
 
314
  httpResponse *answerHdr = whc->response_hdr;
 
315
 
 
316
  // check if file exists
 
317
  if (stat(cgi_path, &info) < 0) {
 
318
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
319
    answerHdr->setStatus(STATUS_NOT_FOUND);
 
320
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
321
  }
 
322
  // initialize arguments
 
323
  for (i = 0; i < MAX_ARGS + 2; i++)
 
324
    a[i] = NULL;
 
325
  a[0] = cgi_path;
 
326
  for (i = 1; i < MAX_ARGS + 1 && args && args[i - 1]; i++)
 
327
    a[i] = args[i - 1];
 
328
 
 
329
  // initialize environment
 
330
  if (request->getContentType() != NULL) {
 
331
    env.setVar("CONTENT_TYPE", request->getContentType());
 
332
  }
 
333
  if (request->getMethod() == METHOD_POST) {
 
334
    env.setVar("REQUEST_METHOD", "POST");
 
335
    query_string = request->getBody();
 
336
 
 
337
  } else if (request->getMethod() == METHOD_GET) {
 
338
    env.setVar("REQUEST_METHOD", "GET");
 
339
    query_string = request->getQuery();
 
340
 
 
341
  } else {
 
342
    answerHdr->setStatus(STATUS_NOT_IMPLEMENTED);
 
343
    WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
 
344
    return WEB_HTTP_ERR_REQUEST_ERROR;;
 
345
  }
 
346
  if (query_string != NULL) {
 
347
 
 
348
    // use getConLen() to handle binary
 
349
    qlen = request->getConLen();
 
350
    if (qlen <= 0)
 
351
      qlen = strlen(query_string);
 
352
    snprintf(content_length_buffer, sizeof(content_length_buffer), "%d", qlen);
 
353
    env.setVar("CONTENT_LENGTH", content_length_buffer);
 
354
    env.setVar("QUERY_STRING", query_string);
 
355
 
 
356
    query_string_tb.copyFrom(query_string, qlen);
 
357
  }
 
358
#ifndef _WIN32
 
359
  if (processSpawn(&a[0], &env, &query_string_tb, replyMsg, nowait, run_as_root) != 0) {
 
360
    mgmt_elog(stderr, "[spawn_cgi] Unable to fork child process\n");
 
361
    WebHttpSetErrorResponse(whc, STATUS_INTERNAL_SERVER_ERROR);
 
362
    answerHdr->setStatus(STATUS_INTERNAL_SERVER_ERROR);
 
363
 
 
364
  } else {
 
365
    success = true;
 
366
  }
 
367
#else
 
368
 
 
369
  char buffer[1024];
 
370
  char cmdLine[PATH_MAX * 2 + 6];
 
371
  DWORD nbytes = 0;
 
372
 
 
373
  SECURITY_ATTRIBUTES saAttr;
 
374
  saAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
 
375
  saAttr.bInheritHandle = TRUE;
 
376
  saAttr.lpSecurityDescriptor = NULL;
 
377
 
 
378
  // STDIN
 
379
  HANDLE hChildStdinR = NULL;
 
380
  HANDLE hChildStdinW = NULL;
 
381
 
 
382
  CreatePipe(&hChildStdinR, &hChildStdinW, &saAttr, 0);
 
383
 
 
384
  // Dup to NULL and set inheritable to FALSE so that
 
385
  // it won't be inherited by the child process
 
386
  DuplicateHandle(GetCurrentProcess(), hChildStdinW, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_SAME_ACCESS);
 
387
 
 
388
  // STDOUT
 
389
  HANDLE hChildStdoutR = NULL;
 
390
  HANDLE hChildStdoutW = NULL;
 
391
 
 
392
  CreatePipe(&hChildStdoutR, &hChildStdoutW, &saAttr, 0);
 
393
 
 
394
  // Dup to NULL and set inheritable to FALSE so that
 
395
  // it won't be inherited by the child process
 
396
  DuplicateHandle(GetCurrentProcess(), hChildStdoutR, GetCurrentProcess(), NULL, 0, FALSE, DUPLICATE_SAME_ACCESS);
 
397
 
 
398
  STARTUPINFO suInfo;
 
399
  PROCESS_INFORMATION procInfo;
 
400
  ZeroMemory((PVOID) & suInfo, sizeof(suInfo));
 
401
 
 
402
  // hide the new console window from the user
 
403
  suInfo.cb = sizeof(STARTUPINFO);
 
404
  suInfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
 
405
  suInfo.wShowWindow = SW_HIDE;
 
406
  suInfo.hStdInput = hChildStdinR;
 
407
  suInfo.hStdOutput = hChildStdoutW;
 
408
  suInfo.hStdError = GetStdHandle(STD_ERROR_HANDLE);
 
409
 
 
410
  adjustCmdLine(cmdLine, sizeof(cmdLine), cgi_path);
 
411
 
 
412
  if (CreateProcess(NULL, cmdLine, NULL,        // FIX THIS: process security attributes
 
413
                    NULL,       // FIX THIS: thread security attributes
 
414
                    TRUE,       // make handles inheritable
 
415
                    0,          // FIX THIS: specify a priority
 
416
                    env.toString(), ts_base_dir,        // make script run from TSBase
 
417
                    &suInfo, &procInfo) == FALSE) {
 
418
 
 
419
    mgmt_elog(stderr, "[spawn_cgi] CreateProcess error: %s\n", ink_last_err());
 
420
    WebHttpSetErrorResponse(whc, STATUS_INTERNAL_SERVER_ERROR);
 
421
    answerHdr->setStatus(STATUS_INTERNAL_SERVER_ERROR);
 
422
 
 
423
  } else {
 
424
 
 
425
    CloseHandle(hChildStdinR);
 
426
    if (request->getMethod() == METHOD_POST && query_string != NULL) {
 
427
      WriteFile(hChildStdinW, query_string, qlen, &nbytes, NULL);
 
428
    }
 
429
    CloseHandle(hChildStdinW);
 
430
 
 
431
    CloseHandle(hChildStdoutW);
 
432
    while (ReadFile(hChildStdoutR, buffer, 1024, &nbytes, NULL) == TRUE) {
 
433
      if (nbytes == 0) {
 
434
        break;
 
435
      }
 
436
      replyMsg->copyFrom(buffer, nbytes);
 
437
    }
 
438
    CloseHandle(hChildStdoutR);
 
439
    success = true;
 
440
  }
 
441
 
 
442
#endif
 
443
 
 
444
  // was this a plugin callout?
 
445
  if (whc->request_state & WEB_HTTP_STATE_PLUGIN) {
 
446
    // notify server plugin to update its config
 
447
    if (success == true && query_string != NULL) {
 
448
      char *plugin_name = new char[qlen];
 
449
      const char *tmp = strstr(query_string, "INK_PLUGIN_NAME=");
 
450
      if (tmp != NULL) {
 
451
        tmp += strlen("INK_PLUGIN_NAME=");
 
452
        for (i = 0; *tmp != '&' && *tmp != '\0'; tmp++) {
 
453
          plugin_name[i++] = *tmp;
 
454
        }
 
455
        plugin_name[i] = '\0';
 
456
        substituteUnsafeChars(plugin_name);
 
457
        lmgmt->signalEvent(MGMT_EVENT_PLUGIN_CONFIG_UPDATE, plugin_name);
 
458
      }
 
459
      delete[]plugin_name;
 
460
    }
 
461
  }
 
462
 
 
463
  return WEB_HTTP_ERR_OKAY;
 
464
 
 
465
}
 
466
//-------------------------------------------------------------------------
 
467
// handle_cgi_extn
 
468
//-------------------------------------------------------------------------
 
469
 
 
470
static int
 
471
handle_cgi_extn(WebHttpContext * whc, const char *file)
 
472
{
 
473
  NOWARN_UNUSED(file);
 
474
  int err;
 
475
  char *cgi_path;
 
476
  whc->response_hdr->setCachable(0);
 
477
  whc->response_hdr->setStatus(STATUS_OK);
 
478
  whc->response_hdr->setContentType(TEXT_HTML);
 
479
  cgi_path = WebHttpAddDocRoot_Xmalloc(whc, whc->request->getFile());
 
480
  err = spawn_cgi(whc, cgi_path, NULL, false, false);
 
481
  xfree(cgi_path);
 
482
  return err;
 
483
}
 
484
 
 
485
//-------------------------------------------------------------------------
 
486
// handle_ink_extn
 
487
//-------------------------------------------------------------------------
 
488
 
 
489
static int
 
490
handle_ink_extn(WebHttpContext * whc, const char *file)
 
491
{
 
492
  int err;
 
493
  if ((err = WebHttpRender(whc, file)) == WEB_HTTP_ERR_OKAY) {
 
494
    whc->response_hdr->setStatus(STATUS_OK);
 
495
    whc->response_hdr->setLength(whc->response_bdy->spaceUsed());
 
496
    whc->response_hdr->setContentType(TEXT_HTML);
 
497
  }
 
498
  return err;
 
499
}
 
500
 
 
501
//-------------------------------------------------------------------------
 
502
// handle_chart
 
503
//-------------------------------------------------------------------------
 
504
 
 
505
static int
 
506
handle_chart(WebHttpContext * whc, const char *file)
 
507
{
 
508
  NOWARN_UNUSED(file);
 
509
  //-----------------------------------------------------------------------
 
510
  // FIXME: HARD-CODED HTML HELL!!!
 
511
  //-----------------------------------------------------------------------
 
512
 
 
513
  // Note that chart.cgi is a special case so it can not be handled
 
514
  // like our other submit_bindings; the browswer can access the cgi
 
515
  // either by a GET/query or by a POST/body combo.
 
516
 
 
517
  int err = WEB_HTTP_ERR_OKAY;
 
518
 
 
519
  httpMessage *request = whc->request;
 
520
  textBuffer *replyMsg = whc->response_bdy;
 
521
  httpResponse *answerHdr = whc->response_hdr;
 
522
  InkHashTable *post_data_ht, *params;
 
523
 
 
524
  char *varName = NULL;
 
525
  int varNameLen;
 
526
  char tmpVal[MAX_VAL_LENGTH];
 
527
  bool postForm = true;
 
528
  bool clusterGraph = false;
 
529
 
 
530
  //800, 410
 
531
  static const char dimensions[] = "width=\"1600\" height=\"1200\"";
 
532
  static const char multiGraph[] = "Inktomi Real-time Graphing";
 
533
  int numGraphs = 0;
 
534
  const int totalNumGraphs = 10;
 
535
  char numGraphStr[8];
 
536
  char *theGraphs[totalNumGraphs];
 
537
  const char *theGraphNames[totalNumGraphs];
 
538
  const char *graphNames[] = {
 
539
    "Document Hit Rate", "Bandwidth Savings", "Cache Percent Free",
 
540
    "Open Server Connections", "Open Client Connections",
 
541
    "Cache Transfers In Progress", "Client Throughput",
 
542
    "Transactions Per Second", "Host Database Hit Rate",
 
543
    "DNS Lookups Per Second"
 
544
  };
 
545
 
 
546
  static const char str1[] = "<html>\n" "<title>";
 
547
  static const char str1_5[] =
 
548
    "</title>\n" "<body><b> No variable(s) were selected for graphing. </b></body>\n" "</html>\n";
 
549
  static const char str2[] =
 
550
    "</title>\n"
 
551
    "<body bgcolor=\"#C0C0C0\" onResize=\"resize()\" onLoad=\"resize()\" "
 
552
    " topmargin=\"0\" leftmargin=\"0\" marginwidth=\"0\" marginheight=\"0\">\n"
 
553
    "<SCRIPT LANGUAGE=\"JavaScript\">\n"
 
554
    "   function myFunc(page, winName) {\n"
 
555
    "          window.open(page, winName, \"width=850,height=435,status,resizable=yes\");\n"
 
556
    "   }\n"
 
557
    "   function resize() {\n"
 
558
    "   var w_newWidth,w_newHeight;\n"
 
559
    "   var w_maxWidth=1600,w_maxHeight=1200;\n"
 
560
    "   if (navigator.appName.indexOf(\"Microsoft\") != -1)\n"
 
561
    "   {\n"
 
562
    "           w_newWidth=document.body.clientWidth;\n"
 
563
    "           w_newHeight=document.body.clientHeight;\n"
 
564
    "   } else {\n"
 
565
    "           var netscapeScrollWidth=15;\n"
 
566
    "           w_newWidth=window.innerWidth-netscapeScrollWidth;\n"
 
567
    "           w_newHeight=window.innerHeight-netscapeScrollWidth;\n"
 
568
    "   }\n"
 
569
    "   if (w_newWidth>w_maxWidth)\n"
 
570
    "           w_newWidth=w_maxWidth;\n"
 
571
    "   if (w_newHeight>w_maxHeight)\n"
 
572
    "           w_newHeight=w_maxHeight;\n"
 
573
    "   document.ink_chart.resizeFrame(w_newWidth,w_newHeight);\n"
 
574
    "        window.scroll(0,0);\n" "   }\n" "   window.onResize = resize;\n" "   window.onLoad = resize;\n"
 
575
    //kwt
 
576
    "   function closeTheBrowser() {\n"
 
577
    "   window.close();\n"
 
578
    "   }\n"
 
579
    "   function SnapshotAlert() {\n"
 
580
    "   window.alert(\"Snapshot is currently not supported on SSL connection.\");\n" "   }\n"
 
581
    //kwt
 
582
    "</SCRIPT>\n"
 
583
    "<applet NAME=\"ink_chart\" CODE=\"InktomiCharter.class\" " " ARCHIVE=\"/charting/InkChart.jar\" MAYSCRIPT ";
 
584
  static const char str3[] = ">\n<param name=ServerName value=\"";
 
585
  static const char str3_2[] = "\">\n<param name=ServerPort value=\"";
 
586
  static const char str3_3[] = "\">\n<param name=ServerWebPort value=\"";
 
587
  static const char str3_4[] = "\">\n<param name=Graphs value=\"";
 
588
  static const char str3_5[] = "\">\n<param name=StatNames   value=\"";
 
589
  static const char str3_6[] = "\">\n<param name=SSL value=\"";
 
590
  static const char str4[] = "\">\n</applet>\n</body>\n</html>\n";
 
591
 
 
592
  static const int str1Len = strlen(str1);
 
593
  static const int str1_5Len = strlen(str1_5);
 
594
  static const int str2Len = strlen(str2);
 
595
  static const int str3Len = strlen(str3);
 
596
  static const int str3_2Len = strlen(str3_2);
 
597
  static const int str3_3Len = strlen(str3_3);
 
598
  static const int str3_4Len = strlen(str3_4);
 
599
  static const int str3_5Len = strlen(str3_5);
 
600
  static const int str3_6Len = strlen(str3_6);
 
601
  static const int str4Len = strlen(str4);
 
602
 
 
603
  // The graph Generator is a POST form, while the cluster graphs are
 
604
  // GET forms.  If we get nothing, assume that we have a postForm.
 
605
  post_data_ht = processFormSubmission(request->getBody());
 
606
  if (post_data_ht == NULL) {
 
607
    postForm = false;
 
608
    params = whc->query_data_ht;
 
609
    // If we still didn't get anything, there is nothing to be had
 
610
    if (params == NULL) {
 
611
      err = WEB_HTTP_ERR_REQUEST_ERROR;
 
612
      goto Ldone;
 
613
    }
 
614
  } else {
 
615
    params = post_data_ht;
 
616
  }
 
617
 
 
618
  if (postForm == false) {
 
619
    // We are trying to generate a cluster graph for a node variable
 
620
    int ink_hash_lookup_result = ink_hash_table_lookup(params, "cluster", (void **) &varName);
 
621
    if (!ink_hash_lookup_result || varName == NULL) {
 
622
      mgmt_log(stderr, "Invalid Graph Submission No graph will be generated\n");
 
623
      err = WEB_HTTP_ERR_REQUEST_ERROR;
 
624
      goto Ldone;
 
625
    }
 
626
    clusterGraph = true;
 
627
  } else {
 
628
    for (int i = 0; i < totalNumGraphs; i++) {
 
629
      if (ink_hash_table_lookup(params, graphNames[i], (void **) &varName)) {
 
630
        theGraphs[numGraphs] = (char *) varName;
 
631
        theGraphNames[numGraphs] = graphNames[i];
 
632
        numGraphs += 1;
 
633
      }
 
634
    }
 
635
    clusterGraph = false;
 
636
  }
 
637
 
 
638
  varNameLen = varName ? strlen(varName) : 0;
 
639
 
 
640
  // Build the reply
 
641
  replyMsg->copyFrom(str1, str1Len);
 
642
  if (clusterGraph == true && varName) {
 
643
    replyMsg->copyFrom(varName, varNameLen);
 
644
  } else {
 
645
    replyMsg->copyFrom(multiGraph, strlen(multiGraph));
 
646
    if (numGraphs == 0) {
 
647
      replyMsg->copyFrom(str1_5, str1_5Len);
 
648
      answerHdr->setStatus(STATUS_OK);
 
649
      goto Ldone;
 
650
    }
 
651
  }
 
652
  replyMsg->copyFrom(str2, str2Len);
 
653
  replyMsg->copyFrom(dimensions, strlen(dimensions));
 
654
 
 
655
  replyMsg->copyFrom(str3, str3Len);
 
656
  varStrFromName("proxy.node.hostname_FQ", tmpVal, MAX_VAL_LENGTH);
 
657
  replyMsg->copyFrom(tmpVal, strlen(tmpVal));
 
658
 
 
659
  replyMsg->copyFrom(str3_2, str3_2Len);
 
660
  varStrFromName("proxy.config.admin.overseer_port", tmpVal, MAX_VAL_LENGTH);
 
661
  replyMsg->copyFrom(tmpVal, strlen(tmpVal));
 
662
 
 
663
  replyMsg->copyFrom(str3_3, str3_3Len);
 
664
  varStrFromName("proxy.config.admin.web_interface_port", tmpVal, MAX_VAL_LENGTH);
 
665
  replyMsg->copyFrom(tmpVal, strlen(tmpVal));
 
666
 
 
667
  replyMsg->copyFrom(str3_4, str3_4Len);
 
668
  if (clusterGraph == true) {
 
669
    replyMsg->copyFrom("CLUSTER", 7);
 
670
  } else {
 
671
    snprintf(numGraphStr, sizeof(numGraphStr), "%d", numGraphs);
 
672
    replyMsg->copyFrom(numGraphStr, strlen(numGraphStr));
 
673
  }
 
674
 
 
675
  replyMsg->copyFrom(str3_5, str3_5Len);
 
676
  if (clusterGraph == true) {
 
677
    replyMsg->copyFrom(varName, varNameLen);
 
678
  } else {
 
679
    for (int j = 1; j < numGraphs; j++) {
 
680
      replyMsg->copyFrom(theGraphs[j], strlen(theGraphs[j]));
 
681
      replyMsg->copyFrom(",", 1);
 
682
      replyMsg->copyFrom(theGraphNames[j], strlen(theGraphNames[j]));
 
683
 
 
684
      replyMsg->copyFrom(",", 1);
 
685
    }
 
686
    replyMsg->copyFrom(theGraphs[0], strlen(theGraphs[0]));
 
687
    replyMsg->copyFrom(",", 1);
 
688
    replyMsg->copyFrom(theGraphNames[0], strlen(theGraphNames[0]));
 
689
  }
 
690
 
 
691
  replyMsg->copyFrom(str3_6, str3_6Len);
 
692
  if (whc->server_state & WEB_HTTP_SERVER_STATE_SSL_ENABLED) {
 
693
    replyMsg->copyFrom("enabled", strlen("enabled"));
 
694
  } else {
 
695
    replyMsg->copyFrom("disabled", strlen("disabled"));
 
696
  }
 
697
 
 
698
  replyMsg->copyFrom(str4, str4Len);
 
699
  answerHdr->setLength(strlen(replyMsg->bufPtr()));
 
700
 
 
701
Ldone:
 
702
  if (post_data_ht) {
 
703
    ink_hash_table_destroy_and_xfree_values(post_data_ht);
 
704
  }
 
705
  return err;
 
706
 
 
707
}
 
708
 
 
709
//-------------------------------------------------------------------------
 
710
// handle_record_info
 
711
//
 
712
// Warning!!! This is really hacky since we should not be directly
 
713
// accessing the librecords data structures.  Just do this here
 
714
// tempoarily until we can have something better.
 
715
//-------------------------------------------------------------------------
 
716
 
 
717
#include "P_RecCore.h"
 
718
 
 
719
#define LINE_SIZE 512
 
720
#define BUF_SIZE 128
 
721
#define NULL_STR "NULL"
 
722
 
 
723
#undef LINE_SIZE
 
724
#undef BUF_SIZE
 
725
#undef NULL_STR
 
726
 
 
727
static int
 
728
handle_config_files(WebHttpContext * whc, const char *file)
 
729
{
 
730
  NOWARN_UNUSED(file);
 
731
  return WebHttpRender(whc, HTML_FILE_ALL_CONFIG);
 
732
}
 
733
 
 
734
static int
 
735
handle_debug_logs(WebHttpContext * whc, const char *file)
 
736
{
 
737
  NOWARN_UNUSED(file);
 
738
  return WebHttpRender(whc, HTML_VIEW_DEBUG_LOGS_FILE);
 
739
}
 
740
 
 
741
//-------------------------------------------------------------------------
 
742
// handle_synthetic
 
743
//-------------------------------------------------------------------------
 
744
 
 
745
static int
 
746
handle_synthetic(WebHttpContext * whc, const char *file)
 
747
{
 
748
  NOWARN_UNUSED(file);
 
749
  char buffer[28];
 
750
  char cur = 'a';
 
751
  whc->response_hdr->setContentType(TEXT_PLAIN);
 
752
  whc->response_hdr->setStatus(STATUS_OK);
 
753
  buffer[26] = '\n';
 
754
  buffer[27] = '\0';
 
755
  for (int i = 0; i < 26; i++) {
 
756
    *(buffer + i) = cur;
 
757
    cur++;
 
758
  }
 
759
  for (int j = 0; j < 60; j++) {
 
760
    whc->response_bdy->copyFrom(buffer, 27);
 
761
  }
 
762
  return WEB_HTTP_ERR_OKAY;
 
763
}
 
764
 
 
765
//-------------------------------------------------------------------------
 
766
// handle_submit_alarm
 
767
//-------------------------------------------------------------------------
 
768
 
 
769
static int
 
770
handle_submit_alarm(WebHttpContext * whc, const char *file)
 
771
{
 
772
  NOWARN_UNUSED(file);
 
773
  resolveAlarm(whc->post_data_ht);
 
774
  whc->top_level_render_file = xstrdup(HTML_ALARM_FILE);
 
775
  return handle_ink_extn(whc, HTML_ALARM_FILE);
 
776
}
 
777
 
 
778
//-------------------------------------------------------------------------
 
779
// handle_submit_mgmt_auth
 
780
//-------------------------------------------------------------------------
 
781
 
 
782
// set_admin_passwd (sub-function)
 
783
static inline void
 
784
set_admin_passwd(WebHttpContext * whc)
 
785
{
 
786
 
 
787
  char *admin_orig_epasswd;
 
788
  char *admin_old_passwd;
 
789
  char *admin_old_epasswd;
 
790
  char *admin_new_passwd;
 
791
  char *admin_new_passwd_retype;
 
792
  char *admin_new_epasswd;
 
793
 
 
794
  char empty_str[1];
 
795
  *empty_str = '\0';
 
796
 
 
797
  if (!ink_hash_table_lookup(whc->post_data_ht, "admin_old_passwd", (void **) &admin_old_passwd))
 
798
    admin_old_passwd = NULL;
 
799
  if (!ink_hash_table_lookup(whc->post_data_ht, "admin_new_passwd", (void **) &admin_new_passwd))
 
800
    admin_new_passwd = NULL;
 
801
  if (!ink_hash_table_lookup(whc->post_data_ht, "admin_new_passwd_retype", (void **) &admin_new_passwd_retype))
 
802
    admin_new_passwd_retype = NULL;
 
803
 
 
804
  if ((admin_old_passwd != NULL) || (admin_new_passwd != NULL) || (admin_new_passwd_retype != NULL)) {
 
805
 
 
806
    if (admin_old_passwd == NULL)
 
807
      admin_old_passwd = empty_str;
 
808
    if (admin_new_passwd == NULL)
 
809
      admin_new_passwd = empty_str;
 
810
    if (admin_new_passwd_retype == NULL)
 
811
      admin_new_passwd_retype = empty_str;
 
812
 
 
813
    admin_orig_epasswd = (char *) alloca(INK_ENCRYPT_PASSWD_LEN + 1);
 
814
    varStrFromName("proxy.config.admin.admin_password", admin_orig_epasswd, INK_ENCRYPT_PASSWD_LEN + 1);
 
815
 
 
816
    // INKqa12084: do not encrypt password if empty_str
 
817
    if (strcmp(admin_old_passwd, empty_str) == 0) {
 
818
      admin_old_epasswd = xstrdup(empty_str);
 
819
    } else {
 
820
      INKEncryptPassword(admin_old_passwd, &admin_old_epasswd);
 
821
    }
 
822
 
 
823
    if (strncmp(admin_old_epasswd, admin_orig_epasswd, INK_ENCRYPT_PASSWD_LEN) == 0) {
 
824
      if (strcmp(admin_new_passwd, admin_new_passwd_retype) == 0) {
 
825
        // INKqa12084: do not encrypt password if empty_str
 
826
        if (strcmp(admin_new_passwd, empty_str) == 0) {
 
827
          admin_new_epasswd = xstrdup(empty_str);
 
828
        } else {
 
829
          INKEncryptPassword(admin_new_passwd, &admin_new_epasswd);
 
830
        }
 
831
 
 
832
        set_record_value(whc, "proxy.config.admin.admin_password", admin_new_epasswd);
 
833
        xfree(admin_new_epasswd);
 
834
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
 
835
        HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_NEW_ADMIN_PASSWD_SET);
 
836
        HtmlRndrBr(whc->submit_note);
 
837
      } else {
 
838
        ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.admin.admin_password", NULL);
 
839
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
840
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_PASSWD_MISTYPE);
 
841
        HtmlRndrBr(whc->submit_warn);
 
842
      }
 
843
    } else {
 
844
      ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.admin.admin_password", NULL);
 
845
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
846
      HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_OLD_PASSWD_INCORRECT);
 
847
      HtmlRndrBr(whc->submit_warn);
 
848
    }
 
849
    xfree(admin_old_epasswd);
 
850
  }
 
851
 
 
852
}
 
853
 
 
854
static int
 
855
handle_submit_mgmt_auth(WebHttpContext * whc, const char *file)
 
856
{
 
857
  NOWARN_UNUSED(file);
 
858
  bool recs_out_of_date;
 
859
  char *value;
 
860
  char *cancel;
 
861
  char *record_version;
 
862
  char *submit_from_page;
 
863
  char *aa_session_id, *aa_user_count;
 
864
  char *aa_user, *aa_access, *aa_delete;
 
865
  char *aa_new_user, *aa_new_passwd, *aa_new_passwd_retype, *aa_new_access;
 
866
  char *aa_new_epasswd;
 
867
  char admin_user[MAX_VAL_LENGTH + 1];
 
868
  int user, user_count;
 
869
  INKCfgContext ctx;
 
870
  INKAdminAccessEle *ele;
 
871
  INKActionNeedT action_need;
 
872
  INKAccessT access_t;
 
873
  bool ctx_updated;
 
874
 
 
875
  char tmp_a[32];
 
876
  char tmp_b[32];
 
877
 
 
878
  char empty_str[1];
 
879
  *empty_str = '\0';
 
880
 
 
881
  // initialize pointers we may assign memeory to
 
882
  aa_new_epasswd = NULL;
 
883
 
 
884
  // check for submit_from_page
 
885
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
886
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
887
    whc->top_level_render_file = xstrdup(submit_from_page);
 
888
  } else {
 
889
    submit_from_page = NULL;
 
890
  }
 
891
 
 
892
  // check for cancel
 
893
  if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel))
 
894
    goto Ldone;
 
895
 
 
896
  // check for record_version
 
897
  recs_out_of_date = true;
 
898
  if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
 
899
    recs_out_of_date = !record_version_valid(record_version);
 
900
    ink_hash_table_delete(whc->post_data_ht, "record_version");
 
901
    xfree(record_version);
 
902
  }
 
903
  if (recs_out_of_date)
 
904
    goto Lout_of_date;
 
905
 
 
906
  // proxy.config.admin.basic_auth
 
907
  if (ink_hash_table_lookup(whc->post_data_ht, "proxy.config.admin.basic_auth", (void **) &value))
 
908
    set_record_value(whc, "proxy.config.admin.basic_auth", value);
 
909
 
 
910
  // proxy.config.admin.admin_user
 
911
  if (ink_hash_table_lookup(whc->post_data_ht, "proxy.config.admin.admin_user", (void **) &value))
 
912
    set_record_value(whc, "proxy.config.admin.admin_user", value);
 
913
 
 
914
  // proxy.config.admin.admin_password (call sub-function)
 
915
  set_admin_passwd(whc);
 
916
 
 
917
  // grab our session_id and user_count
 
918
  if (ink_hash_table_lookup(whc->post_data_ht, "session_id", (void **) &aa_session_id)) {
 
919
    if (!ink_hash_table_lookup(whc->post_data_ht, "user_count", (void **) &aa_user_count))
 
920
      goto Lunable_to_submit;
 
921
    // find our current session
 
922
    if (WebHttpSessionRetrieve(aa_session_id, (void **) &ctx) != WEB_HTTP_ERR_OKAY)
 
923
      goto Lout_of_date;
 
924
    // get new additional-user information
 
925
    if (!ink_hash_table_lookup(whc->post_data_ht, "new_user", (void **) &aa_new_user))
 
926
      aa_new_user = NULL;
 
927
    if (!ink_hash_table_lookup(whc->post_data_ht, "new_passwd", (void **) &aa_new_passwd))
 
928
      aa_new_passwd = NULL;
 
929
    if (!ink_hash_table_lookup(whc->post_data_ht, "new_passwd_retype", (void **) &aa_new_passwd_retype))
 
930
      aa_new_passwd_retype = NULL;
 
931
    if (!ink_hash_table_lookup(whc->post_data_ht, "new_access", (void **) &aa_new_access))
 
932
      aa_new_access = NULL;
 
933
    // check if the user is trying to add a new additional-user
 
934
    if (aa_new_user != NULL) {
 
935
      // kwt 12.March.2001 check for username length
 
936
      if (strlen(aa_new_user) > WEB_HTTP_AUTH_USER_MAX) {
 
937
        ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
 
938
        ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
 
939
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
940
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_USERNAME_LENGTH);
 
941
        HtmlRndrBr(whc->submit_warn);
 
942
        aa_new_user = NULL;
 
943
      }
 
944
      // kwt
 
945
      if (aa_new_user != NULL) {
 
946
        if (aa_new_passwd == NULL)
 
947
          aa_new_passwd = empty_str;
 
948
        if (aa_new_passwd_retype == NULL)
 
949
          aa_new_passwd_retype = empty_str;
 
950
        if (strcmp(aa_new_passwd, aa_new_passwd_retype) == 0) {
 
951
          // allocating memory on aa_new_epasswd
 
952
          INKEncryptPassword(aa_new_passwd, &aa_new_epasswd);
 
953
        } else {
 
954
          ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
 
955
          ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
 
956
          whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
957
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_PASSWD_MISTYPE);
 
958
          HtmlRndrBr(whc->submit_warn);
 
959
        }
 
960
      }
 
961
      // check if the new_user is the same as the proxy.config.admin.admin_user
 
962
      if (aa_new_user != NULL) {
 
963
        varStrFromName("proxy.config.admin.admin_user", admin_user, MAX_VAL_LENGTH + 1);
 
964
        if (strcmp(aa_new_user, admin_user) == 0) {
 
965
          ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
 
966
          ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
 
967
          whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
968
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_USER_DUPLICATE);
 
969
          HtmlRndrBr(whc->submit_warn);
 
970
          aa_new_user = NULL;
 
971
        }
 
972
      }
 
973
    }
 
974
    // Walk through members and update settings in ctx backwards.
 
975
    // Client submitted values should be in the same order as the ctx
 
976
    // since we originally created this page from the same ctx.
 
977
    // Looping backwards helps so that we can delete elements by
 
978
    // index.
 
979
    ctx_updated = false;
 
980
    user_count = ink_atoi(aa_user_count);
 
981
    for (user = user_count - 1; user >= 0; user--) {
 
982
      snprintf(tmp_a, sizeof(tmp_a), "user:%d", user);
 
983
      snprintf(tmp_b, sizeof(tmp_b), "access:%d", user);
 
984
      if (ink_hash_table_lookup(whc->post_data_ht, tmp_a, (void **) &aa_user) &&
 
985
          ink_hash_table_lookup(whc->post_data_ht, tmp_b, (void **) &aa_access)) {
 
986
        snprintf(tmp_a, sizeof(tmp_a), "delete:%d", user);
 
987
        if (ink_hash_table_lookup(whc->post_data_ht, tmp_a, (void **) &aa_delete)) {
 
988
          INKCfgContextRemoveEleAt(ctx, user);
 
989
          ctx_updated = true;
 
990
          continue;
 
991
        }
 
992
        ele = (INKAdminAccessEle *) INKCfgContextGetEleAt(ctx, user);
 
993
        if (strcmp(ele->user, aa_user) != 0) {
 
994
          goto Lunable_to_submit;
 
995
        }
 
996
        if (aa_new_user && (strcmp(aa_new_user, aa_user) == 0)) {
 
997
          ink_hash_table_insert(whc->submit_warn_ht, "additional_administrative_accounts", NULL);
 
998
          ink_hash_table_insert(whc->submit_warn_ht, "add_new_administrative_user", NULL);
 
999
          whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1000
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NEW_USER_DUPLICATE);
 
1001
          HtmlRndrBr(whc->submit_warn);
 
1002
          aa_new_user = NULL;
 
1003
        }
 
1004
        access_t = (INKAccessT) ink_atoi(aa_access);
 
1005
        if (ele->access != access_t) {
 
1006
          ele->access = access_t;
 
1007
          ctx_updated = true;
 
1008
        }
 
1009
      } else {
 
1010
        goto Lunable_to_submit;
 
1011
      }
 
1012
    }
 
1013
    // add new user
 
1014
    if ((aa_new_user != NULL) && (aa_new_epasswd != NULL)) {
 
1015
      ele = INKAdminAccessEleCreate();
 
1016
      ele->user = xstrdup(aa_new_user);
 
1017
      ele->password = xstrdup(aa_new_epasswd);
 
1018
      // FIXME: no access for now, add back later?
 
1019
      //ele->access = aa_new_access ? (INKAccessT)ink_atoi(aa_new_access) : INK_ACCESS_NONE;
 
1020
      ele->access = INK_ACCESS_NONE;
 
1021
      INKCfgContextAppendEle(ctx, (INKCfgEle *) ele);
 
1022
      ctx_updated = true;
 
1023
    }
 
1024
    if (ctx_updated) {
 
1025
      if (INKCfgContextCommit(ctx, &action_need, NULL) != INK_ERR_OKAY) {
 
1026
        WebHttpSessionDelete(aa_session_id);
 
1027
        goto Lout_of_date;
 
1028
      }
 
1029
      INKActionDo(action_need);
 
1030
    }
 
1031
    WebHttpSessionDelete(aa_session_id);
 
1032
  } else {
 
1033
    goto Lunable_to_submit;
 
1034
  }
 
1035
  goto Ldone;
 
1036
 
 
1037
Lout_of_date:
 
1038
  whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1039
  HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_OUT_OF_DATE);
 
1040
  HtmlRndrBr(whc->submit_warn);
 
1041
  goto Ldone;
 
1042
 
 
1043
Lunable_to_submit:
 
1044
  whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1045
  HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_UNABLE_TO_SUBMIT);
 
1046
  HtmlRndrBr(whc->submit_warn);
 
1047
  goto Ldone;
 
1048
 
 
1049
Ldone:
 
1050
  if (aa_new_epasswd) {
 
1051
    xfree(aa_new_epasswd);
 
1052
  }
 
1053
  return WebHttpRender(whc, HTML_MGMT_LOGIN_FILE);
 
1054
}
 
1055
 
 
1056
 
 
1057
 
 
1058
 
 
1059
 
 
1060
 
 
1061
//-------------------------------------------------------------------------
 
1062
// handle_submit_snapshot
 
1063
//-------------------------------------------------------------------------
 
1064
 
 
1065
// Doesn't seem to be used.
 
1066
static int INK_UNUSED
 
1067
handle_submit_snapshot(WebHttpContext * whc, const char *file)
 
1068
{
 
1069
  NOWARN_UNUSED(file);
 
1070
  int err = 0;
 
1071
  SnapResult snap_result = SNAP_OK;
 
1072
  char *submit_from_page;
 
1073
  char *snap_action;
 
1074
  char *snap_name;
 
1075
  char *snap_location;
 
1076
  char *snap_directory;
 
1077
  char *ftp_server_name;
 
1078
  char *ftp_remote_dir;
 
1079
  char *ftp_login;
 
1080
  char *ftp_password;
 
1081
  char *snapDirFromRecordsConf;
 
1082
  bool found = false;
 
1083
  struct stat snapDirStat;
 
1084
  char config_dir[PATH_NAME_MAX];
 
1085
  struct stat s;
 
1086
 
 
1087
  if (varStrFromName("proxy.config.config_dir", config_dir, PATH_NAME_MAX) == false)
 
1088
    mgmt_fatal(stderr,
 
1089
               "[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
 
1090
 
 
1091
  if ((err = stat(config_dir, &s)) < 0) {
 
1092
    ink_strncpy(config_dir, system_config_directory,sizeof(config_dir));
 
1093
    if ((err = stat(config_dir, &s)) < 0) {
 
1094
        mgmt_elog("[WebHttp::handle_submit_snapshot] unable to stat() directory '%s': %d %d, %s\n",
 
1095
                config_dir, err, errno, strerror(errno));
 
1096
        mgmt_fatal("[WebHttp::handle_submit_snapshot] please set config path via command line '-path <path>' or 'proxy.config.config_dir' \n");
 
1097
    }
 
1098
  }
 
1099
  // check for submit_from_page
 
1100
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
1101
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
1102
    whc->top_level_render_file = xstrdup(submit_from_page);
 
1103
  } else {
 
1104
    submit_from_page = NULL;
 
1105
  }
 
1106
 
 
1107
#ifndef _WIN32
 
1108
 
 
1109
  // FIXME: button names here are going to be hard to
 
1110
  // internationalize.  we should put the button names into the
 
1111
  // dictionary.
 
1112
 
 
1113
  // handle snapshot
 
1114
  if (ink_hash_table_lookup(whc->post_data_ht, "snap_action", (void **) &snap_action)) {
 
1115
    // take the snapshot action
 
1116
    if (strcmp(snap_action, "  Change  ") == 0) {
 
1117
      if (ink_hash_table_lookup(whc->post_data_ht, "Change Directory", (void **) &snap_directory)) {
 
1118
        if (snap_directory == NULL) {
 
1119
          mgmt_log(stderr, "Change Directory not specified.");
 
1120
        } else {
 
1121
          ink_assert(RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf)
 
1122
                     == REC_ERR_OKAY);
 
1123
          if (snapDirFromRecordsConf == NULL) {
 
1124
            // coverity[size_is_strlen]
 
1125
            snapDirFromRecordsConf = new char[strlen("snapshots")];
 
1126
            snprintf(snapDirFromRecordsConf, strlen("snapshots"), "%s", "snapshots");
 
1127
            ink_assert(RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf)
 
1128
                       == REC_ERR_OKAY);
 
1129
            ink_assert(RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf)
 
1130
                       == REC_ERR_OKAY);
 
1131
            RecSetRecordString("proxy.config.snapshot_dir", (RecString) snapDirFromRecordsConf);
 
1132
          }
 
1133
          if (strcasecmp(snapDirFromRecordsConf, snap_directory)) {
 
1134
            RecSetRecordString("proxy.config.snapshot_dir", snap_directory);
 
1135
            // Create a directory for the snap shot
 
1136
            if (snap_directory[0] != '/') {
 
1137
              // coverity[alloc_fn][var_assign]
 
1138
              char *snap_dir_cpy = strdup(snap_directory);
 
1139
              int newLen;
 
1140
 
 
1141
              // coverity[noescape]
 
1142
              newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1143
              snap_directory = new char[newLen];
 
1144
              ink_assert(snap_directory != NULL);
 
1145
              // coverity[noescape]
 
1146
              snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1147
              //snap_directory = newPathString(config_dir, snap_dir_cpy);
 
1148
              RecSetRecordString("proxy.config.snapshot_dir", snap_dir_cpy);
 
1149
              if (snap_dir_cpy)
 
1150
                free(snap_dir_cpy);
 
1151
            }
 
1152
 
 
1153
            if (stat(snap_directory, &snapDirStat)) {
 
1154
              SimpleTokenizer snapDirPathTok(snap_directory, '/');
 
1155
              int dirDepth = snapDirPathTok.getNumTokensRemaining();
 
1156
 
 
1157
              for (int i = 1; i <= dirDepth; i++) {
 
1158
                if (snap_directory[0] == '/') {
 
1159
                  int newLen;
 
1160
                  char *absoluteDir;
 
1161
                  const char *tok = snapDirPathTok.getNext(i);
 
1162
 
 
1163
                  newLen = strlen(tok) + 2;
 
1164
                  absoluteDir = new char[newLen];
 
1165
                  ink_assert(absoluteDir != NULL);
 
1166
                  snprintf(absoluteDir, newLen, "/%s", tok);
 
1167
 
 
1168
                  if (mkdir(absoluteDir, DIR_MODE) < 0) {
 
1169
                    perror("Absolute snapPath Directory creation:");
 
1170
                  }
 
1171
                  delete[]absoluteDir;
 
1172
                } else {
 
1173
                  const char *tok = snapDirPathTok.getNext(i);
 
1174
                  // These weren't used, so moved. /leif
 
1175
                  //int newLen;
 
1176
                  //char* absoluteDir;
 
1177
                  //const char *config_dir = lmgmt->record_data ->readString("proxy.config.config_dir", &found);
 
1178
 
 
1179
                  //newLen = strlen(tok) + strlen(config_dir) + 2;
 
1180
                  //absoluteDir = new char[newLen];
 
1181
                  //ink_assert(absoluteDir != NULL);
 
1182
                  //sprintf(absoluteDir, "%s%s%s",config_dir, DIR_SEP, tok);
 
1183
 
 
1184
                  //if ((ret_val = mkdir(absoluteDir, DIR_MODE)) < 0) {
 
1185
                  //perror("Absolute snapPath Directory creation:");
 
1186
                  //}
 
1187
                  //delete [] absoluteDir;
 
1188
                  if (mkdir(tok, DIR_MODE) < 0) {
 
1189
                    perror("Relative snapPath Directory creation:");
 
1190
                  }
 
1191
                }
 
1192
                snapDirPathTok.setString(snap_directory);
 
1193
              }
 
1194
            }                   //else {
 
1195
            //if(snap_directory[0] == '/') {
 
1196
            //lmgmt->record_data ->setString("proxy.config.snapshot_dir", snap_directory);
 
1197
            //} else {
 
1198
            //int newLen;
 
1199
            //char* relativeDir;
 
1200
            //const char *config_dir = lmgmt->record_data ->readString("proxy.config.config_dir", &found);
 
1201
 
 
1202
            //newLen = strlen(snap_directory) + strlen(config_dir) + 2;
 
1203
            //relativeDir = new char[newLen];
 
1204
            //ink_assert(relativeDir != NULL);
 
1205
            //sprintf(relativeDir, "%s%s%s",config_dir, DIR_SEP, snap_directory);
 
1206
            //lmgmt->record_data ->setString("proxy.config.snapshot_dir", relativeDir);
 
1207
            //}
 
1208
            //}
 
1209
          }
 
1210
        }
 
1211
      }
 
1212
    } else if (strcmp(snap_action, "   Take   ") == 0) {
 
1213
      if (ink_hash_table_lookup(whc->post_data_ht, "new_snap", (void **) &snap_name)) {
 
1214
        if (snap_name == NULL) {
 
1215
          mgmt_log(stderr, "Snapshots name on disk not specified.");
 
1216
        }
 
1217
      }
 
1218
      if (ink_hash_table_lookup(whc->post_data_ht, "Snapshots Location", (void **) &snap_location)) {
 
1219
        // coverity[var_compare_op]
 
1220
        if (snap_location == NULL) {
 
1221
          mgmt_log(stderr, "Snapshots Location not specified.");
 
1222
        }
 
1223
      }
 
1224
      if (snap_location && strcmp(snap_location, "OnDisk") == 0) {
 
1225
        RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snap_directory);
 
1226
 
 
1227
        if (snap_directory[0] != '/') {
 
1228
          // coverity[alloc_fn][var_assign]
 
1229
          char *snap_dir_cpy = strdup(snap_directory);
 
1230
          int newLen;
 
1231
 
 
1232
          // coverity[noescape]
 
1233
          newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1234
          snap_directory = new char[newLen];
 
1235
          ink_assert(snap_directory != NULL);
 
1236
          // coverity[noescape]
 
1237
          snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1238
          if (snap_dir_cpy)
 
1239
            free(snap_dir_cpy);
 
1240
        }
 
1241
        snap_result = configFiles->takeSnap(snap_name, snap_directory);
 
1242
      } else if (!(strcmp(snap_location, "FTPServerUpload")) || !(strcmp(snap_location, "FTPServerDownload"))) {
 
1243
        if (ink_hash_table_lookup(whc->post_data_ht, "FTPServerName", (void **) &ftp_server_name)) {
 
1244
          if (ftp_server_name == NULL) {
 
1245
            mgmt_log(stderr, "FTPServerName not specified.");
 
1246
          }
 
1247
        }
 
1248
        if (ink_hash_table_lookup(whc->post_data_ht, "FTPRemoteDir", (void **) &ftp_remote_dir)) {
 
1249
          if (ftp_server_name == NULL) {
 
1250
            mgmt_log(stderr, "FTPRemoteDir not specified.");
 
1251
          }
 
1252
        }
 
1253
        if (ink_hash_table_lookup(whc->post_data_ht, "FTPLogin", (void **) &ftp_login)) {
 
1254
          if (ftp_login == NULL) {
 
1255
            mgmt_log(stderr, "FTPLogin not specified.");
 
1256
          }
 
1257
        }
 
1258
        if (ink_hash_table_lookup(whc->post_data_ht, "FTPPassword", (void **) &ftp_password)) {
 
1259
          if (ftp_password == NULL) {
 
1260
            mgmt_log(stderr, "FTPPassword not specified.");
 
1261
          }
 
1262
        }
 
1263
        if (!(strcmp(snap_location, "FTPServerUpload")) && snap_name) {
 
1264
          int localDirLength, remoteDirLength;
 
1265
          char *newStr;
 
1266
          char *ftp_remote_dir_name;
 
1267
 
 
1268
          localDirLength = strlen(snap_name) + strlen("/tmp") + 2;
 
1269
          remoteDirLength = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
 
1270
 
 
1271
          newStr = new char[localDirLength];
 
1272
          ink_assert(newStr != NULL);
 
1273
          ftp_remote_dir_name = new char[remoteDirLength];
 
1274
          ink_assert(ftp_remote_dir_name != NULL);
 
1275
          snprintf(newStr, localDirLength, "/tmp%s%s", DIR_SEP, snap_name);
 
1276
          snprintf(ftp_remote_dir_name, remoteDirLength, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
 
1277
          snap_result = configFiles->takeSnap(snap_name, "/tmp");
 
1278
          INKMgmtFtp("put", ftp_server_name, ftp_login, ftp_password, newStr, ftp_remote_dir_name, NULL);
 
1279
        } else {
 
1280
          RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1281
          ink_release_assert(found);
 
1282
 
 
1283
          if (snapDirFromRecordsConf[0] != '/') {
 
1284
            char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1285
            int newLen;
 
1286
 
 
1287
            newLen = strlen(snap_dir_cpy) + strlen(config_dir) + strlen(snap_name) + 3;
 
1288
            snapDirFromRecordsConf = new char[newLen];
 
1289
            ink_assert(snapDirFromRecordsConf != NULL);
 
1290
            snprintf(snapDirFromRecordsConf, newLen, "%s%s%s%s%s", config_dir, DIR_SEP, snap_dir_cpy, DIR_SEP,
 
1291
                         snap_name);
 
1292
            if (snap_dir_cpy)
 
1293
              free(snap_dir_cpy);
 
1294
          } else {
 
1295
 
 
1296
            char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1297
            int newLen;
 
1298
 
 
1299
            newLen = strlen(snap_dir_cpy) + strlen(config_dir) + strlen(snap_name) + 3;
 
1300
            snapDirFromRecordsConf = new char[newLen];
 
1301
            ink_assert(snapDirFromRecordsConf != NULL);
 
1302
            snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", snap_dir_cpy, DIR_SEP, snap_name);
 
1303
            if (snap_dir_cpy)
 
1304
              free(snap_dir_cpy);
 
1305
          }
 
1306
          int newLen;
 
1307
          char *newStr;
 
1308
          //const char *config_dir = lmgmt->record_data ->readString("proxy.config.config_dir", &found);
 
1309
 
 
1310
          newLen = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
 
1311
          newStr = new char[newLen];
 
1312
          ink_assert(newStr != NULL);
 
1313
          snprintf(newStr, newLen, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
 
1314
 
 
1315
          if (mkdir(snapDirFromRecordsConf, DIR_MODE) < 0) {
 
1316
            mgmt_log(stderr, "Cannot create %s\n", snapDirFromRecordsConf);
 
1317
          }
 
1318
          INKMgmtFtp("get", ftp_server_name, ftp_login, ftp_password, snapDirFromRecordsConf, newStr, NULL);
 
1319
 
 
1320
        }
 
1321
      } else if (!(strcmp(snap_location, "FloppySave")) || !(strcmp(snap_location, "FloppyCopy"))) {
 
1322
        char *floppyMountPoint;
 
1323
        if (ink_hash_table_lookup(whc->post_data_ht, "FloppyDrive", (void **) &floppyMountPoint)) {
 
1324
          //coverity [var_compare_op]
 
1325
          if (floppyMountPoint == NULL)
 
1326
            mgmt_log(stderr, "FloppyMountPoint not found.");
 
1327
        }
 
1328
        if (snap_location && strcmp(snap_location, "FloppySave") == 0) {
 
1329
          snap_result = configFiles->takeSnap(snap_name, floppyMountPoint);
 
1330
        } else {
 
1331
          char args[256];
 
1332
          RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1333
          snprintf(args, sizeof(args), "cp -fr %s/%s %s", floppyMountPoint, snap_name, snapDirFromRecordsConf);
 
1334
          const char *argv[] = { args,
 
1335
            NULL
 
1336
          };
 
1337
          processSpawn(argv, NULL, NULL, NULL, false, false);
 
1338
        }
 
1339
      } else {
 
1340
        mgmt_log(stderr, "Illegal value for snapshot location.");
 
1341
      }
 
1342
      // take a snapshot for the current configuration files
 
1343
    } else if (strcmp(snap_action, " Restore ") == 0) {
 
1344
      // restore the selected snapshot
 
1345
      if (ink_hash_table_lookup(whc->post_data_ht, "snap_name", (void **) &snap_name)) {
 
1346
        if (strcmp(snap_name, "- select a snapshot -")) {
 
1347
          RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1348
          ink_release_assert(found);
 
1349
          if (snapDirFromRecordsConf[0] != '/') {
 
1350
            char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1351
            ink_assert(snap_dir_cpy);
 
1352
            int newLen;
 
1353
 
 
1354
            newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1355
            snapDirFromRecordsConf = new char[newLen];
 
1356
            ink_assert(snapDirFromRecordsConf != NULL);
 
1357
            snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1358
            if (snap_dir_cpy)
 
1359
              free(snap_dir_cpy);
 
1360
          }
 
1361
          snap_result = configFiles->restoreSnap(snap_name, snapDirFromRecordsConf);
 
1362
        }
 
1363
      }
 
1364
    } else if (strcmp(snap_action, "  Delete  ") == 0) {
 
1365
      // delete the selected snapshot
 
1366
      if (ink_hash_table_lookup(whc->post_data_ht, "snap_name", (void **) &snap_name)) {
 
1367
        if (strcmp(snap_name, "- select a snapshot -")) {
 
1368
          RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1369
          ink_release_assert(found);
 
1370
          if (snapDirFromRecordsConf[0] != '/') {
 
1371
            char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1372
            ink_assert(snap_dir_cpy);
 
1373
            int newLen;
 
1374
 
 
1375
            newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1376
            snapDirFromRecordsConf = new char[newLen];
 
1377
            ink_assert(snapDirFromRecordsConf != NULL);
 
1378
            snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1379
            if (snap_dir_cpy)
 
1380
              free(snap_dir_cpy);
 
1381
          }
 
1382
          snap_result = configFiles->removeSnap(snap_name, snapDirFromRecordsConf);
 
1383
        }
 
1384
      }
 
1385
    } else {
 
1386
      // show alarm error
 
1387
      mgmt_log(stderr, "Unknown action is specified.");
 
1388
    }
 
1389
  } else {
 
1390
    snap_action = NULL;
 
1391
  }
 
1392
 
 
1393
#endif
 
1394
 
 
1395
  if (snap_result != SNAP_OK) {
 
1396
    // FIXME: show alarm error for snapshot!
 
1397
  }
 
1398
 
 
1399
  if (submit_from_page) {
 
1400
    err = WebHttpRender(whc, submit_from_page);
 
1401
    xfree(submit_from_page);
 
1402
  } else {
 
1403
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
1404
  }
 
1405
  return err;
 
1406
}
 
1407
 
 
1408
 
 
1409
//-------------------------------------------------------------------------
 
1410
// handle_submit_snapshot_to_filesystem
 
1411
//-------------------------------------------------------------------------
 
1412
 
 
1413
static int
 
1414
handle_submit_snapshot_to_filesystem(WebHttpContext * whc, const char *file)
 
1415
{
 
1416
  NOWARN_UNUSED(file);
 
1417
  int err = 0;
 
1418
  SnapResult snap_result = SNAP_OK;
 
1419
  char *submit_from_page;
 
1420
  char *snap_action;
 
1421
  char *snap_name;
 
1422
  char *snap_directory;
 
1423
  char *snapDirFromRecordsConf;
 
1424
  char *cancel;
 
1425
  bool found = false;
 
1426
  struct stat snapDirStat;
 
1427
  char config_dir[256];
 
1428
  char *record_version;
 
1429
  ExpandingArray snap_list(25, true);
 
1430
  int num_snaps;
 
1431
 
 
1432
  if (varStrFromName("proxy.config.config_dir", config_dir, 256) == false)
 
1433
    mgmt_fatal(stderr,
 
1434
               "[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
 
1435
 
 
1436
  // check for submit_from_page
 
1437
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
1438
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
1439
    whc->top_level_render_file = xstrdup(submit_from_page);
 
1440
  } else {
 
1441
    submit_from_page = NULL;
 
1442
  }
 
1443
 
 
1444
  // check for cancel
 
1445
  if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
 
1446
    whc->post_data_ht = NULL;
 
1447
    goto Ldone;
 
1448
  }
 
1449
  // check for record_version
 
1450
  if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
 
1451
    // TODO: Check return value?
 
1452
    record_version_valid(record_version);
 
1453
    ink_hash_table_delete(whc->post_data_ht, "record_version");
 
1454
    xfree(record_version);
 
1455
  }
 
1456
 
 
1457
  if (ink_hash_table_lookup(whc->post_data_ht, "Change Directory", (void **) &snap_directory)) {
 
1458
    if (snap_directory == NULL) {
 
1459
      mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_filesystem] Change Directory not specified.");
 
1460
      ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
 
1461
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1462
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
 
1463
        HtmlRndrBr(whc->submit_warn);
 
1464
      }
 
1465
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1466
      goto Ldone;
 
1467
    } else {
 
1468
#ifndef _WIN32
 
1469
      const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._-/\\";
 
1470
#else
 
1471
      const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._-/\\ ";
 
1472
#endif
 
1473
      int snapnameLength = strlen(snap_directory);
 
1474
      int validnameLength = strspn(snap_directory, valid_chars);
 
1475
      if (snapnameLength != validnameLength) {
 
1476
        ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
 
1477
        if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1478
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
 
1479
          HtmlRndrBr(whc->submit_warn);
 
1480
        }
 
1481
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1482
        goto Ldone;
 
1483
      }
 
1484
 
 
1485
      RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1486
      ink_release_assert(found);
 
1487
      if (snapDirFromRecordsConf == NULL) {
 
1488
        snapDirFromRecordsConf = new char[strlen("snapshots")];
 
1489
        snprintf(snapDirFromRecordsConf, strlen("snapshots"), "%s", "snapshots");
 
1490
        RecSetRecordString("proxy.config.snapshot_dir", snapDirFromRecordsConf);
 
1491
      }
 
1492
      if (strcasecmp(snapDirFromRecordsConf, snap_directory)) {
 
1493
        RecSetRecordString("proxy.config.snapshot_dir", snapDirFromRecordsConf);
 
1494
        // Create a directory for the snap shot
 
1495
        if (snap_directory[0] != '/') {
 
1496
          char *snap_dir_cpy = strdup(snap_directory);
 
1497
          int newLen;
 
1498
 
 
1499
          newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1500
          snap_directory = new char[newLen];
 
1501
          ink_assert(snap_directory != NULL);
 
1502
          snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1503
          RecSetRecordString("proxy.config.snapshot_dir", snap_dir_cpy);
 
1504
          if (snap_dir_cpy)
 
1505
            free(snap_dir_cpy);
 
1506
        }
 
1507
        if (!stat(snap_directory, &snapDirStat)) {
 
1508
          bool write_possible = true;
 
1509
          bool read_possible = true;
 
1510
#ifndef _WIN32
 
1511
          if (snapDirStat.st_uid != getuid()) {
 
1512
            if (snapDirStat.st_gid != getgid()) {
 
1513
              if (!(snapDirStat.st_mode & 00002)) {
 
1514
                write_possible = false;
 
1515
              } else {
 
1516
                write_possible = true;
 
1517
              }
 
1518
            } else {
 
1519
              if (!(snapDirStat.st_mode & 00020)) {
 
1520
                write_possible = false;
 
1521
              } else {
 
1522
                write_possible = true;
 
1523
              }
 
1524
            }
 
1525
          }
 
1526
 
 
1527
          if (snapDirStat.st_uid != getuid()) {
 
1528
            if (snapDirStat.st_gid != getgid()) {
 
1529
              if (!(snapDirStat.st_mode & 00004)) {
 
1530
                read_possible = false;
 
1531
              } else {
 
1532
                read_possible = true;
 
1533
              }
 
1534
            } else {
 
1535
              if (!(snapDirStat.st_mode & 00040)) {
 
1536
                read_possible = false;
 
1537
              } else {
 
1538
                read_possible = true;
 
1539
              }
 
1540
            }
 
1541
          }
 
1542
#else
 
1543
          DWORD attr;
 
1544
          attr = GetFileAttributes(snap_directory);
 
1545
          if ((attr & FILE_ATTRIBUTE_READONLY) != 0) {  // read only dir
 
1546
            write_possible = false;
 
1547
            read_possible = false;
 
1548
          } else {
 
1549
            write_possible = true;
 
1550
            read_possible = true;
 
1551
          }
 
1552
#endif // _WIN32
 
1553
          if (!write_possible) {
 
1554
            if (!read_possible) {
 
1555
              ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
 
1556
              if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1557
                HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_PERMISSION_DENIED);
 
1558
                HtmlRndrBr(whc->submit_warn);
 
1559
              }
 
1560
              whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1561
              RecSetRecordString("proxy.config.snapshot_dir", snap_directory);
 
1562
              goto Ldone;
 
1563
            }
 
1564
          }
 
1565
        }
 
1566
 
 
1567
        if (stat(snap_directory, &snapDirStat)) {
 
1568
          SimpleTokenizer snapDirPathTok(snap_directory, '/');
 
1569
          int dirDepth = snapDirPathTok.getNumTokensRemaining();
 
1570
 
 
1571
          for (int i = 1; i <= dirDepth; i++) {
 
1572
            if (snap_directory[0] == '/') {
 
1573
              int newLen;
 
1574
              char *absoluteDir;
 
1575
              const char *tok = snapDirPathTok.getNext(i);
 
1576
 
 
1577
              newLen = strlen(tok) + 2;
 
1578
              absoluteDir = new char[newLen];
 
1579
              ink_assert(absoluteDir != NULL);
 
1580
              snprintf(absoluteDir, newLen, "/%s", tok);
 
1581
 
 
1582
#ifndef _WIN32
 
1583
              if (mkdir(absoluteDir, DIR_MODE) < 0) {
 
1584
#else
 
1585
              if (mkdir(absoluteDir) < 0) {
 
1586
#endif
 
1587
                perror("[WebHttp::handle_submit_snapshot_to_filesystem] Absolute snapPath Directory creation:");
 
1588
              }
 
1589
              delete[]absoluteDir;
 
1590
            } else {
 
1591
              const char *tok = snapDirPathTok.getNext(i);
 
1592
#ifndef _WIN32
 
1593
              if (mkdir(tok, DIR_MODE) < 0) {
 
1594
#else
 
1595
              if (mkdir(tok) < 0) {
 
1596
#endif
 
1597
                perror("[WebHttp::handle_submit_snapshot_to_filesystem] Relative snapPath Directory creation:");
 
1598
              }
 
1599
            }
 
1600
            snapDirPathTok.setString(snap_directory);
 
1601
          }
 
1602
        }
 
1603
      }
 
1604
    }
 
1605
  }
 
1606
 
 
1607
  if (ink_hash_table_lookup(whc->post_data_ht, "SnapshotName", (void **) &snap_name)) {
 
1608
    if (snap_name != NULL) {
 
1609
#ifndef _WIN32
 
1610
      const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._";
 
1611
#else
 
1612
      const char *valid_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890._ ";
 
1613
#endif
 
1614
      int snapnameLength = strlen(snap_name);
 
1615
      int validnameLength = strspn(snap_name, valid_chars);
 
1616
      if (snapnameLength != validnameLength) {
 
1617
        ink_hash_table_insert(whc->submit_warn_ht, "SnapShotName", NULL);
 
1618
        if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1619
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
 
1620
          HtmlRndrBr(whc->submit_warn);
 
1621
        }
 
1622
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1623
        goto Ldone;
 
1624
      }
 
1625
 
 
1626
 
 
1627
      snap_result = configFiles->WalkSnaps(&snap_list);
 
1628
      if (snap_result == SNAP_OK) {
 
1629
        num_snaps = snap_list.getNumEntries();
 
1630
        if (num_snaps > 0) {
 
1631
          for (int i = 0; i < num_snaps; i++)
 
1632
            if (!strcmp((char *) snap_list[i], snap_name)) {
 
1633
              if (ink_hash_table_lookup(whc->post_data_ht, "Delete Snapshot", (void **) &snap_action)) {
 
1634
                if (ink_hash_table_lookup(whc->post_data_ht, "restore_delete_name", (void **) &snap_action)) {
 
1635
                  if (snap_action != NULL) {
 
1636
                    if (!strcmp(snap_name, snap_action))
 
1637
                      goto Ldelete;
 
1638
                  }
 
1639
                }
 
1640
              }
 
1641
              ink_hash_table_insert(whc->submit_warn_ht, "SnapShotName", NULL);
 
1642
              if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1643
                HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_DUPLICATE_ENTRY);
 
1644
                HtmlRndrBr(whc->submit_warn);
 
1645
              }
 
1646
              whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1647
              goto Ldone;
 
1648
            }
 
1649
        }
 
1650
        ink_hash_table_delete(whc->post_data_ht, "SnapshotName");
 
1651
      }
 
1652
 
 
1653
      RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snap_directory);
 
1654
      ink_release_assert(found);
 
1655
 
 
1656
      if (snap_directory[0] != '/') {
 
1657
        char *snap_dir_cpy = strdup(snap_directory);
 
1658
        int newLen;
 
1659
 
 
1660
        newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1661
        snap_directory = new char[newLen];
 
1662
        ink_assert(snap_directory != NULL);
 
1663
        snprintf(snap_directory, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1664
        if (snap_dir_cpy)
 
1665
          free(snap_dir_cpy);
 
1666
      }
 
1667
      snap_result = configFiles->takeSnap(snap_name, snap_directory);
 
1668
      if (snap_result == 3) {
 
1669
        ink_hash_table_insert(whc->submit_warn_ht, "proxy.config.snapshot_dir", snap_directory);
 
1670
        if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1671
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_PERMISSION_DENIED);
 
1672
          HtmlRndrBr(whc->submit_warn);
 
1673
        }
 
1674
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1675
        RecSetRecordString("proxy.config.snapshot_dir", snap_directory);
 
1676
        goto Ldone;
 
1677
      }
 
1678
    }
 
1679
  }
 
1680
 
 
1681
  if (ink_hash_table_lookup(whc->post_data_ht, "Restore Snapshot", (void **) &snap_action)) {
 
1682
    if (ink_hash_table_lookup(whc->post_data_ht, "restore_delete_name", (void **) &snap_name)) {
 
1683
      if (strcmp(snap_name, "- select a snapshot -")) {
 
1684
        RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1685
        ink_release_assert(found);
 
1686
        if (snapDirFromRecordsConf[0] != '/') {
 
1687
          char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1688
          ink_assert(snap_dir_cpy);
 
1689
          int newLen;
 
1690
          newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1691
          snapDirFromRecordsConf = new char[newLen];
 
1692
          ink_assert(snapDirFromRecordsConf != NULL);
 
1693
          snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1694
          if (snap_dir_cpy)
 
1695
            free(snap_dir_cpy);
 
1696
        }
 
1697
        snap_result = configFiles->restoreSnap(snap_name, snapDirFromRecordsConf);
 
1698
        if (snap_result < 0) {
 
1699
          mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_filesystem] Restore snapshot failed");
 
1700
        }
 
1701
      }
 
1702
    }
 
1703
  }
 
1704
 
 
1705
Ldelete:
 
1706
  if (ink_hash_table_lookup(whc->post_data_ht, "Delete Snapshot", (void **) &snap_action)) {
 
1707
    if (ink_hash_table_lookup(whc->post_data_ht, "restore_delete_name", (void **) &snap_name)) {
 
1708
      if (strcmp(snap_name, "- select a snapshot -")) {
 
1709
        RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1710
        ink_release_assert(found);
 
1711
        if (snapDirFromRecordsConf[0] != '/') {
 
1712
          char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1713
          ink_assert(snap_dir_cpy);
 
1714
          int newLen;
 
1715
          newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1716
          snapDirFromRecordsConf = new char[newLen];
 
1717
          ink_assert(snapDirFromRecordsConf != NULL);
 
1718
          snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1719
          if (snap_dir_cpy)
 
1720
            free(snap_dir_cpy);
 
1721
        }
 
1722
        snap_result = configFiles->removeSnap(snap_name, snapDirFromRecordsConf);
 
1723
        if (snap_result < 0) {
 
1724
          mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_filesystem] Remove snapshot failed");
 
1725
        }
 
1726
      }
 
1727
    }
 
1728
  }
 
1729
 
 
1730
 
 
1731
 
 
1732
Ldone:
 
1733
  if (submit_from_page) {
 
1734
    err = WebHttpRender(whc, submit_from_page);
 
1735
    xfree(submit_from_page);
 
1736
  } else {
 
1737
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
1738
  }
 
1739
  return err;
 
1740
}
 
1741
 
 
1742
 
 
1743
 
 
1744
 
 
1745
 
 
1746
 
 
1747
 
 
1748
//-------------------------------------------------------------------------
 
1749
// handle_submit_snapshot_to_ftpserver
 
1750
//-------------------------------------------------------------------------
 
1751
 
 
1752
static int
 
1753
handle_submit_snapshot_to_ftpserver(WebHttpContext * whc, const char *file)
 
1754
{
 
1755
  NOWARN_UNUSED(file);
 
1756
  int err = 0;
 
1757
  char *submit_from_page;
 
1758
  char *snap_name;
 
1759
  char *ftp_server_name;
 
1760
  char *ftp_remote_dir;
 
1761
  char *ftp_login;
 
1762
  char *ftp_password;
 
1763
  char *snapDirFromRecordsConf;
 
1764
  char *tempDirFromRecordsConf;
 
1765
  char *cancel;
 
1766
  bool found;
 
1767
  // Doesn't seem to be used.
 
1768
  //struct stat snapDirStat;
 
1769
  char config_dir[256];
 
1770
  char *record_version;
 
1771
  ExpandingArray snap_list(25, true);
 
1772
 
 
1773
  if (varStrFromName("proxy.config.config_dir", config_dir, 256) == false)
 
1774
    mgmt_fatal(stderr,
 
1775
               "[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
 
1776
 
 
1777
  // check for submit_from_page
 
1778
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
1779
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
1780
    whc->top_level_render_file = xstrdup(submit_from_page);
 
1781
  } else {
 
1782
    submit_from_page = NULL;
 
1783
  }
 
1784
 
 
1785
  // check for cancel
 
1786
  if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
 
1787
    whc->post_data_ht = NULL;
 
1788
    goto Ldone;
 
1789
  }
 
1790
  // check for record_version
 
1791
  if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
 
1792
    // TODO: Check return value?
 
1793
    record_version_valid(record_version);
 
1794
    ink_hash_table_delete(whc->post_data_ht, "record_version");
 
1795
    xfree(record_version);
 
1796
  }
 
1797
#ifndef _WIN32
 
1798
 
 
1799
  if (ink_hash_table_lookup(whc->post_data_ht, "FTPServerName", (void **) &ftp_server_name)) {
 
1800
    if (ftp_server_name == NULL) {
 
1801
      mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPServerName not specified.");
 
1802
      ink_hash_table_insert(whc->submit_warn_ht, "FTPServerNameError", NULL);
 
1803
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1804
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
 
1805
        HtmlRndrBr(whc->submit_warn);
 
1806
      }
 
1807
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1808
    }
 
1809
  }
 
1810
 
 
1811
 
 
1812
  if (ink_hash_table_lookup(whc->post_data_ht, "FTPUserName", (void **) &ftp_login)) {
 
1813
    if (ftp_login == NULL) {
 
1814
      mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPlogin not specified.");
 
1815
      ink_hash_table_insert(whc->submit_warn_ht, "FTPUserNameError", NULL);
 
1816
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1817
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
 
1818
        HtmlRndrBr(whc->submit_warn);
 
1819
      }
 
1820
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1821
    }
 
1822
  }
 
1823
 
 
1824
 
 
1825
  if (ink_hash_table_lookup(whc->post_data_ht, "FTPPassword", (void **) &ftp_password)) {
 
1826
    if (ftp_password == NULL) {
 
1827
      mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPpassword not specified.");
 
1828
      ink_hash_table_insert(whc->submit_warn_ht, "FTPPasswordError", NULL);
 
1829
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1830
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
 
1831
        HtmlRndrBr(whc->submit_warn);
 
1832
      }
 
1833
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1834
    }
 
1835
  }
 
1836
 
 
1837
 
 
1838
  if (ink_hash_table_lookup(whc->post_data_ht, "FTPRemoteDir", (void **) &ftp_remote_dir)) {
 
1839
    if (ftp_remote_dir == NULL) {
 
1840
      mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTPremote_dir not specified.");
 
1841
      ink_hash_table_insert(whc->submit_warn_ht, "FTPRemoteDirError", NULL);
 
1842
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1843
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
 
1844
        HtmlRndrBr(whc->submit_warn);
 
1845
      }
 
1846
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1847
    }
 
1848
  }
 
1849
 
 
1850
  if (ink_hash_table_lookup(whc->post_data_ht, "ftp_select", (void **) &snap_name)) {
 
1851
    if (strcmp(snap_name, "- select a snapshot -")) {
 
1852
      RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
1853
      /*
 
1854
         char *snap_dir;
 
1855
         snapDirFromRecordsConf = lmgmt->record_data ->readString("proxy.config.snapshot_dir", &found);
 
1856
         ink_assert(found);
 
1857
 
 
1858
         if(snapDirFromRecordsConf[0] != '/') {
 
1859
         const char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1860
         int newLen;
 
1861
 
 
1862
         newLen = strlen(snap_dir_cpy) + strlen(config_dir) + strlen(snap_name) + 3;
 
1863
         snapDirFromRecordsConf = new char[newLen];
 
1864
         ink_assert(snapDirFromRecordsConf != NULL);
 
1865
         sprintf(snapDirFromRecordsConf, "%s%s%s%s%s", config_dir, DIR_SEP, snap_dir_cpy, DIR_SEP, snap_name);
 
1866
 
 
1867
         newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
1868
         snap_dir = new char[newLen];
 
1869
         ink_assert(snap_dir != NULL);
 
1870
         sprintf(snap_dir, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
1871
         } else {
 
1872
 
 
1873
         char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
1874
         int newLen;
 
1875
 
 
1876
         newLen = strlen(snap_dir_cpy) + strlen(snap_name) + 2;
 
1877
         snapDirFromRecordsConf = new char[newLen];
 
1878
         ink_assert(snapDirFromRecordsConf != NULL);
 
1879
         sprintf(snapDirFromRecordsConf, "%s%s%s", snap_dir_cpy, DIR_SEP, snap_name);
 
1880
 
 
1881
         snap_dir = snap_dir_cpy;
 
1882
         } */
 
1883
 
 
1884
      found = (RecGetRecordString_Xmalloc("proxy.config.temp_dir", &tempDirFromRecordsConf)
 
1885
               == REC_ERR_OKAY);
 
1886
 
 
1887
      ink_release_assert(found);
 
1888
 
 
1889
      int newLen;
 
1890
      char *newStr;
 
1891
 
 
1892
      newLen = strlen(tempDirFromRecordsConf) + strlen(snap_name) + 2;
 
1893
      char *tmp_ftp_snap = new char[newLen];
 
1894
      ink_assert(tmp_ftp_snap != NULL);
 
1895
      snprintf(tmp_ftp_snap, newLen, "%s%s%s", tempDirFromRecordsConf, DIR_SEP, snap_name);
 
1896
 
 
1897
      newLen = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
 
1898
      newStr = new char[newLen];
 
1899
      ink_assert(newStr != NULL);
 
1900
      snprintf(newStr, newLen, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
 
1901
 
 
1902
      if (mkdir(tmp_ftp_snap, DIR_MODE) < 0) {
 
1903
        mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] Cannot create %s\n", tmp_ftp_snap);
 
1904
      }
 
1905
      char ftpOutput[4096];
 
1906
      INKMgmtFtp("get", ftp_server_name, ftp_login, ftp_password, tmp_ftp_snap, newStr, ftpOutput);
 
1907
      if (!strncmp(ftpOutput, "ERROR:", 6)) {
 
1908
        mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTP get failed : %s", ftpOutput);
 
1909
        goto Ldone;
 
1910
      }
 
1911
      // TODO: Check return values?
 
1912
      configFiles->restoreSnap(snap_name, tempDirFromRecordsConf);
 
1913
      configFiles->removeSnap(snap_name, tempDirFromRecordsConf);
 
1914
    }
 
1915
  }
 
1916
 
 
1917
 
 
1918
  if (ink_hash_table_lookup(whc->post_data_ht, "FTPSaveName", (void **) &snap_name)) {
 
1919
    if (snap_name != NULL) {
 
1920
      int localDirLength, remoteDirLength;
 
1921
      char *newStr;
 
1922
      char *ftp_remote_dir_name;
 
1923
 
 
1924
      localDirLength = strlen(snap_name) + strlen("/tmp") + 2;
 
1925
      remoteDirLength = strlen(snap_name) + strlen(ftp_remote_dir) + 2;
 
1926
 
 
1927
      newStr = new char[localDirLength];
 
1928
      ink_assert(newStr != NULL);
 
1929
      ftp_remote_dir_name = new char[remoteDirLength];
 
1930
      ink_assert(ftp_remote_dir_name != NULL);
 
1931
      snprintf(newStr, localDirLength, "/tmp%s%s", DIR_SEP, snap_name);
 
1932
      snprintf(ftp_remote_dir_name, remoteDirLength, "%s%s%s", ftp_remote_dir, DIR_SEP, snap_name);
 
1933
      configFiles->takeSnap(snap_name, "/tmp");
 
1934
      char ftpOutput[4096];
 
1935
      INKMgmtFtp("put", ftp_server_name, ftp_login, ftp_password, newStr, ftp_remote_dir_name, ftpOutput);
 
1936
      if (!strncmp(ftpOutput, "ERROR:", 6)) {
 
1937
        //mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTP put failed : %s", ftpOutput);
 
1938
        fprintf(stderr, "[WebHttp::handle_submit_snapshot_to_ftpsystem] FTP put failed : %s", ftpOutput);
 
1939
        if (!strncmp(ftpOutput, "ERROR: FTP Put:: permission", 27)) {
 
1940
          ink_hash_table_insert(whc->submit_warn_ht, "FTPRemoteDirError", NULL);
 
1941
          if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
1942
            HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_PERMISSION_DENIED);
 
1943
            HtmlRndrBr(whc->submit_warn);
 
1944
          }
 
1945
          whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
1946
        }
 
1947
        goto Ldone;
 
1948
      }
 
1949
    }
 
1950
  }
 
1951
#endif
 
1952
 
 
1953
Ldone:
 
1954
  if (submit_from_page) {
 
1955
    err = WebHttpRender(whc, submit_from_page);
 
1956
    xfree(submit_from_page);
 
1957
  } else {
 
1958
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
1959
  }
 
1960
  return err;
 
1961
}
 
1962
 
 
1963
 
 
1964
 
 
1965
 
 
1966
//-------------------------------------------------------------------------
 
1967
// handle_submit_snapshot_to_floppy
 
1968
//-------------------------------------------------------------------------
 
1969
 
 
1970
static int
 
1971
handle_submit_snapshot_to_floppy(WebHttpContext * whc, const char *file)
 
1972
{
 
1973
  NOWARN_UNUSED(file);
 
1974
  int err = 0;
 
1975
  SnapResult snap_result = SNAP_OK;
 
1976
  char *submit_from_page;
 
1977
  char *snapDirFromRecordsConf;
 
1978
  char *cancel;
 
1979
  char *floppy_drive_mount_point;
 
1980
  char *floppy_selected_snap_name;
 
1981
  char *floppy_snap_name;
 
1982
  // Not used here.
 
1983
  //struct stat snapDirStat;
 
1984
  char config_dir[256];
 
1985
  char *record_version;
 
1986
  char *UnmountFloppy;
 
1987
  int old_euid;
 
1988
  const char *linkFile;
 
1989
  ExpandingArray snap_list(25, true);
 
1990
 
 
1991
  if (varStrFromName("proxy.config.config_dir", config_dir, 256) == false)
 
1992
    mgmt_fatal(stderr,
 
1993
               "[WebHttp::handle_submit_snapshot] Unable to find configuration directory from proxy.config.config_dir\n");
 
1994
 
 
1995
  // check for submit_from_page
 
1996
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
1997
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
1998
    whc->top_level_render_file = xstrdup(submit_from_page);
 
1999
  } else {
 
2000
    submit_from_page = NULL;
 
2001
  }
 
2002
 
 
2003
  // check for cancel
 
2004
  if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
 
2005
    whc->post_data_ht = NULL;
 
2006
    goto Ldone;
 
2007
  }
 
2008
  // check for record_version
 
2009
  if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
 
2010
    // TODO: Check return value?
 
2011
    record_version_valid(record_version);
 
2012
    ink_hash_table_delete(whc->post_data_ht, "record_version");
 
2013
    xfree(record_version);
 
2014
  }
 
2015
#ifndef _WIN32
 
2016
 
 
2017
   /**
 
2018
     Unmount Floppy
 
2019
    **/
 
2020
  if (ink_hash_table_lookup(whc->post_data_ht, "Unmount Floppy", (void **) &UnmountFloppy)) {
 
2021
    if (UnmountFloppy != NULL) {
 
2022
      int ret = 0;
 
2023
 
 
2024
      if (strcmp(UnmountFloppy, "Unmount Floppy") == 0) {
 
2025
        char unmountPath[1024];
 
2026
 
 
2027
        if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
 
2028
          if (floppy_drive_mount_point != NULL)
 
2029
            snprintf(unmountPath, sizeof(unmountPath), "/bin/umount %s", floppy_drive_mount_point);
 
2030
          else {
 
2031
            NOWARN_UNUSED_RETURN(system("sync;sync;sync"));
 
2032
            linkFile = "/configure/c_snapshot_floppy.ink";
 
2033
            ink_hash_table_insert(whc->submit_warn_ht, "CouldnotUnmount", NULL);
 
2034
            if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2035
              HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_FLOPPY_UNMOUNT_ERR);
 
2036
              HtmlRndrBr(whc->submit_warn);
 
2037
            }
 
2038
            whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2039
            if (submit_from_page)
 
2040
              xfree(submit_from_page);
 
2041
            submit_from_page = xstrdup(linkFile);
 
2042
            goto Ldone;
 
2043
          }
 
2044
        }
 
2045
        pid_t pid;
 
2046
        if ((pid = fork()) < 0) {
 
2047
          goto Ldone;
 
2048
        } else if (pid == 0) {
 
2049
          old_euid = getuid();
 
2050
          seteuid(0);
 
2051
          setreuid(0, 0);
 
2052
          ret = system(unmountPath);
 
2053
          setreuid(old_euid, old_euid);
 
2054
          exit(ret / 256);
 
2055
        } else {
 
2056
          wait(&ret);
 
2057
        }
 
2058
      }
 
2059
      if ((ret / 256)) {
 
2060
        linkFile = "/configure/c_snapshot_floppy.ink";
 
2061
        ink_hash_table_insert(whc->submit_warn_ht, "CouldnotUnmount", NULL);
 
2062
        if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2063
          HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_FLOPPY_UNMOUNT_ERR);
 
2064
          HtmlRndrBr(whc->submit_warn);
 
2065
        }
 
2066
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2067
        if (submit_from_page)
 
2068
          xfree(submit_from_page);
 
2069
        submit_from_page = xstrdup(linkFile);
 
2070
        goto Ldone;
 
2071
      } else {
 
2072
        linkFile = "/configure/c_basic.ink";
 
2073
      }
 
2074
 
 
2075
#ifndef NO_WEBUI
 
2076
      char *link = WebHttpGetLink_Xmalloc(linkFile);
 
2077
      whc->response_hdr->setRefreshURL(link);
 
2078
      xfree(link);
 
2079
#endif
 
2080
      whc->response_hdr->setRefresh(0);
 
2081
      if (submit_from_page)
 
2082
        xfree(submit_from_page);
 
2083
      submit_from_page = xstrdup(linkFile);
 
2084
      goto Ldone;
 
2085
    }
 
2086
  }
 
2087
 
 
2088
  if (ink_hash_table_lookup(whc->post_data_ht, "floppy_select", (void **) &floppy_selected_snap_name)) {
 
2089
    if (floppy_selected_snap_name != NULL) {
 
2090
      if (strcmp(floppy_selected_snap_name, "- select a snapshot -")) {
 
2091
        if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
 
2092
 
 
2093
          RecGetRecordString_Xmalloc("proxy.config.snapshot_dir", &snapDirFromRecordsConf);
 
2094
 
 
2095
          if (snapDirFromRecordsConf[0] != '/') {
 
2096
            // coverity[alloc_fn][var_assign]
 
2097
            char *snap_dir_cpy = strdup(snapDirFromRecordsConf);
 
2098
            int newLen;
 
2099
 
 
2100
            // coverity[noescape]
 
2101
            newLen = strlen(snap_dir_cpy) + strlen(config_dir) + 2;
 
2102
            snapDirFromRecordsConf = new char[newLen];
 
2103
            ink_assert(snapDirFromRecordsConf != NULL);
 
2104
            // coverity[noescape]
 
2105
            snprintf(snapDirFromRecordsConf, newLen, "%s%s%s", config_dir, DIR_SEP, snap_dir_cpy);
 
2106
            if (snap_dir_cpy)
 
2107
              free(snap_dir_cpy);
 
2108
          }
 
2109
          if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
 
2110
            snap_result = configFiles->restoreSnap(floppy_selected_snap_name, floppy_drive_mount_point);
 
2111
            if (snap_result < 0) {
 
2112
              mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_floppy] Restore snap failed");
 
2113
            }
 
2114
 
 
2115
          }
 
2116
        }
 
2117
      }
 
2118
    }
 
2119
  }
 
2120
 
 
2121
 
 
2122
  if (ink_hash_table_lookup(whc->post_data_ht, "FloppySnapName", (void **) &floppy_snap_name)) {
 
2123
    if (floppy_snap_name != NULL) {
 
2124
      if (ink_hash_table_lookup(whc->post_data_ht, "FloppyPath", (void **) &floppy_drive_mount_point)) {
 
2125
 
 
2126
        struct dirent *dirEntry;
 
2127
        DIR *dir;
 
2128
        char *fileName;
 
2129
        // Doesn't seem to be used.
 
2130
        //struct stat fileInfo;
 
2131
        //struct stat records_config_fileInfo;
 
2132
        //fileEntry* fileListEntry;
 
2133
 
 
2134
        dir = opendir(floppy_drive_mount_point);
 
2135
 
 
2136
        if (dir == NULL) {
 
2137
          mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_floppy] Unable to open %s directory: %s\n",
 
2138
                   floppy_drive_mount_point, strerror(errno));
 
2139
          return -1;
 
2140
        }
 
2141
        // The fun of Solaris - readdir_r requires a buffer passed into it
 
2142
        //   The man page says this obscene expression gives us the proper
 
2143
        //     size
 
2144
        dirEntry = (struct dirent *) xmalloc(sizeof(struct dirent) + pathconf(".", _PC_NAME_MAX) + 1);
 
2145
        struct dirent *result;
 
2146
        while (readdir_r(dir, dirEntry, &result) == 0) {
 
2147
          if (!result)
 
2148
            break;
 
2149
          fileName = dirEntry->d_name;
 
2150
          if (!strcmp(fileName, floppy_snap_name)) {
 
2151
            ink_hash_table_insert(whc->submit_warn_ht, "FloppyError", NULL);
 
2152
            if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2153
              HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_DUPLICATE_ENTRY);
 
2154
              HtmlRndrBr(whc->submit_warn);
 
2155
            }
 
2156
            whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2157
            xfree(dirEntry);
 
2158
            closedir(dir);
 
2159
            goto Ldone;
 
2160
          }
 
2161
        }
 
2162
 
 
2163
        xfree(dirEntry);
 
2164
        closedir(dir);
 
2165
 
 
2166
 
 
2167
        snap_result = configFiles->takeSnap(floppy_snap_name, floppy_drive_mount_point);
 
2168
        if (snap_result < 0) {
 
2169
          mgmt_log(stderr, "[WebHttp::handle_submit_snapshot_to_floppy] Take snap failed");
 
2170
        } else if (snap_result == 6) {
 
2171
          // BZ50256
 
2172
          ink_hash_table_insert(whc->submit_warn_ht, "FloppySaveFailed", NULL);
 
2173
          if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2174
            HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_FLOPPY_NO_SPACE);
 
2175
            HtmlRndrBr(whc->submit_warn);
 
2176
          }
 
2177
          whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2178
          goto Ldone;
 
2179
        }
 
2180
        ink_hash_table_delete(whc->post_data_ht, "FloppySnapName");
 
2181
      }
 
2182
    }
 
2183
  }
 
2184
#endif
 
2185
 
 
2186
Ldone:
 
2187
  if (submit_from_page) {
 
2188
    err = WebHttpRender(whc, submit_from_page);
 
2189
    xfree(submit_from_page);
 
2190
  } else {
 
2191
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
2192
  }
 
2193
  return err;
 
2194
}
 
2195
 
 
2196
 
 
2197
 
 
2198
//-------------------------------------------------------------------------
 
2199
// handle_submit_inspector
 
2200
//-------------------------------------------------------------------------
 
2201
static int
 
2202
handle_submit_inspector(WebHttpContext * whc, const char *file)
 
2203
{
 
2204
  NOWARN_UNUSED(file);
 
2205
  int err = 0;
 
2206
  char *submit_from_page;
 
2207
  char *regex;
 
2208
  char *regex_action;
 
2209
  char *list;
 
2210
 
 
2211
  // check for submit_from_page
 
2212
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
2213
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
2214
    whc->top_level_render_file = xstrdup(submit_from_page);
 
2215
  } else {
 
2216
    submit_from_page = NULL;
 
2217
  }
 
2218
 
 
2219
  // FIXME: button names here are going to be hard to
 
2220
  // internationalize.  we should put the button names into the
 
2221
  // dictionary.
 
2222
 
 
2223
  // handle URL Regex operation
 
2224
  if (ink_hash_table_lookup(whc->post_data_ht, "regex_op", (void **) &regex_action)) {
 
2225
    if (strcmp(regex_action, "Lookup") == 0) {
 
2226
      // handle regex lookup
 
2227
      if (ink_hash_table_lookup(whc->post_data_ht, "regex", (void **) &regex)) {
 
2228
        if ((err = INKLookupFromCacheUrlRegex(regex, &list)) == INK_ERR_OKAY) {
 
2229
          whc->cache_query_result = list;
 
2230
        }
 
2231
      }
 
2232
    } else if (strcmp(regex_action, "Delete") == 0) {
 
2233
      // handle regex delete
 
2234
      if (ink_hash_table_lookup(whc->post_data_ht, "regex", (void **) &regex)) {
 
2235
        if ((err = INKDeleteFromCacheUrlRegex(regex, &list)) == INK_ERR_OKAY) {
 
2236
          whc->cache_query_result = list;
 
2237
        }
 
2238
      }
 
2239
    } else if (strcmp(regex_action, "Invalidate") == 0) {
 
2240
      // handle regex invalidate
 
2241
      if (ink_hash_table_lookup(whc->post_data_ht, "regex", (void **) &regex)) {
 
2242
        if ((err = INKInvalidateFromCacheUrlRegex(regex, &list)) == INK_ERR_OKAY) {
 
2243
          whc->cache_query_result = list;
 
2244
        }
 
2245
      }
 
2246
    }
 
2247
  }
 
2248
  // Error: unknown action
 
2249
  else {
 
2250
    mgmt_log(stderr, "Unknown action is specified.");
 
2251
  }
 
2252
 
 
2253
  if (err != INK_ERR_OKAY) {
 
2254
    // FIXME: show alarm error for cache inspector!
 
2255
  }
 
2256
 
 
2257
  if (submit_from_page) {
 
2258
    err = WebHttpRender(whc, submit_from_page);
 
2259
    xfree(submit_from_page);
 
2260
  } else {
 
2261
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
2262
  }
 
2263
  return err;
 
2264
}
 
2265
 
 
2266
 
 
2267
//-------------------------------------------------------------------------
 
2268
// handle_submit_inspector_display
 
2269
//-------------------------------------------------------------------------
 
2270
 
 
2271
static int
 
2272
handle_submit_inspector_display(WebHttpContext * whc, const char *file)
 
2273
{
 
2274
  NOWARN_UNUSED(file);
 
2275
  int err = 0;
 
2276
  char *url;
 
2277
  char *url_action;
 
2278
  char *buf;
 
2279
  InkHashTable *ht;
 
2280
  InkHashTable *query_ht;
 
2281
 
 
2282
  // processFormSubmission will substituteUnsafeChars()
 
2283
  ht = whc->query_data_ht;
 
2284
  // extract some basic info for easier access later
 
2285
  if (ink_hash_table_lookup(ht, "url_op", (void **) &url_action)) {
 
2286
    // handle URL operation
 
2287
    if (strcmp(url_action, "Lookup") == 0) {
 
2288
      // handle url lookup
 
2289
      if (ink_hash_table_lookup(ht, "url", (void **) &url)) {
 
2290
        if ((err = INKLookupFromCacheUrl(url, &buf)) == INK_ERR_OKAY) {
 
2291
          whc->cache_query_result = buf;
 
2292
        }
 
2293
      }
 
2294
    } else if (strcmp(url_action, "Delete") == 0) {
 
2295
      // the url that cache_inspector takes has to be w/o substituteUnsafeChars()
 
2296
      if ((query_ht = processFormSubmission_noSubstitute((char *) (whc->request->getQuery()))) != NULL) {
 
2297
        if (ink_hash_table_lookup(query_ht, "url", (void **) &url)) {
 
2298
          // handle url delete
 
2299
          if ((err = INKDeleteFromCacheUrl(url, &buf)) == INK_ERR_OKAY) {
 
2300
            whc->cache_query_result = buf;
 
2301
          }
 
2302
        }
 
2303
        ink_hash_table_destroy_and_xfree_values(query_ht);
 
2304
      }
 
2305
    }
 
2306
  }
 
2307
  // Error: unknown action
 
2308
  else {
 
2309
    mgmt_log(stderr, "Unknown action is specified.");
 
2310
  }
 
2311
 
 
2312
  err = WebHttpRender(whc, HTML_INSPECTOR_DISPLAY_FILE);
 
2313
  return err;
 
2314
}
 
2315
 
 
2316
//-------------------------------------------------------------------------
 
2317
// handle_submit_view_logs
 
2318
//-------------------------------------------------------------------------
 
2319
static int
 
2320
handle_submit_view_logs(WebHttpContext * whc, const char *file)
 
2321
{
 
2322
  NOWARN_UNUSED(file);
 
2323
  int err;
 
2324
  char *submit_from_page;
 
2325
  char *nlines;
 
2326
  char *substring;
 
2327
  char *action = NULL;
 
2328
  char *logfile = NULL;
 
2329
  char tmp[MAX_TMP_BUF_LEN + 1];
 
2330
  int file_size;
 
2331
  time_t file_date_gmt;
 
2332
 
 
2333
  // check for submit_from_page
 
2334
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
2335
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
2336
    whc->top_level_render_file = xstrdup(submit_from_page);
 
2337
  } else {
 
2338
    submit_from_page = NULL;
 
2339
  }
 
2340
 
 
2341
#if !defined(_WIN32)
 
2342
 
 
2343
  // handle remove/save file action before rendering
 
2344
  if (!ink_hash_table_lookup(whc->post_data_ht, "logfile", (void **) &logfile))
 
2345
    goto Ldone;
 
2346
  if (!ink_hash_table_lookup(whc->post_data_ht, "action", (void **) &action))
 
2347
    goto Ldone;
 
2348
  if (!logfile || !action)
 
2349
    goto Ldone;
 
2350
  if (strcmp(logfile, "default") == 0)
 
2351
    goto Ldone;
 
2352
 
 
2353
  if (strcmp(action, "view_last") == 0) {
 
2354
    if (!ink_hash_table_lookup(whc->post_data_ht, "nlines", (void **) &nlines))
 
2355
      goto Ldone;
 
2356
    // 'nlines' entry is missing
 
2357
    if (nlines == NULL) {
 
2358
      ink_hash_table_insert(whc->submit_warn_ht, "view_last", NULL);
 
2359
      goto Lmiss;
 
2360
    }
 
2361
 
 
2362
  } else if (strcmp(action, "view_subset") == 0) {
 
2363
    if (!ink_hash_table_lookup(whc->post_data_ht, "substring", (void **) &substring))
 
2364
      goto Ldone;
 
2365
    // 'substring' entry is missing
 
2366
    if (substring == NULL) {
 
2367
      ink_hash_table_insert(whc->submit_warn_ht, "view_subset", NULL);
 
2368
      goto Lmiss;
 
2369
    }
 
2370
 
 
2371
  } else if (strcmp(action, "remove") == 0) {
 
2372
 
 
2373
    snprintf(tmp, MAX_TMP_BUF_LEN, "/bin/rm -f %s", logfile);
 
2374
    if (system(tmp)) {
 
2375
      Debug("web2", "[handle_submit_view_logs] unable to execute \"%s\"", tmp);
 
2376
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2377
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2378
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_LOG_REMOVE_FAILED);
 
2379
        HtmlRndrBr(whc->submit_warn);
 
2380
      }
 
2381
    } else {
 
2382
      // done removal - remove from post_data_ht not to display previous action
 
2383
      ink_hash_table_delete(whc->post_data_ht, "action");
 
2384
      ink_hash_table_delete(whc->post_data_ht, "logfile");
 
2385
      xfree(logfile);
 
2386
      xfree(action);
 
2387
    }
 
2388
  } else if (strcmp(action, "save") == 0) {
 
2389
    WebHandle h_file;
 
2390
    if ((h_file = WebFileOpenR(logfile)) == WEB_HANDLE_INVALID) {
 
2391
      Debug("web2", "[handle_submit_view_logs] unable to open logfile \"%s\"", logfile);
 
2392
 
 
2393
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2394
        whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2395
        HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_LOG_SAVE_FAILED);
 
2396
        HtmlRndrBr(whc->submit_warn);
 
2397
      }
 
2398
    } else {
 
2399
      file_size = WebFileGetSize(h_file);
 
2400
      file_date_gmt = WebFileGetDateGmt(h_file);
 
2401
      whc->response_hdr->setStatus(STATUS_OK);
 
2402
      whc->response_hdr->setLength(file_size);
 
2403
      whc->response_hdr->setLastMod(file_date_gmt);
 
2404
      whc->response_hdr->setContentType(TEXT_UNKNOWN);
 
2405
      while (whc->response_bdy->rawReadFromFile(h_file) > 0);
 
2406
      WebFileClose(h_file);
 
2407
      return WEB_HTTP_ERR_OKAY;
 
2408
    }
 
2409
  } else {
 
2410
    Debug("web2", "[handle_submit_view_logs] unknown action '%s' on '%s'", action, logfile);
 
2411
  }
 
2412
  goto Ldone;
 
2413
 
 
2414
#endif
 
2415
 
 
2416
Lmiss:
 
2417
  if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2418
    whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2419
    HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_MISSING_ENTRY);
 
2420
    HtmlRndrBr(whc->submit_warn);
 
2421
  }
 
2422
 
 
2423
Ldone:
 
2424
  // nothing needs to be done, just start rendering
 
2425
  if (submit_from_page) {
 
2426
    err = WebHttpRender(whc, submit_from_page);
 
2427
    xfree(submit_from_page);
 
2428
  } else {
 
2429
    err = WebHttpRender(whc, HTML_DEFAULT_MONITOR_FILE);
 
2430
  }
 
2431
  return err;
 
2432
}
 
2433
 
 
2434
//-------------------------------------------------------------------------
 
2435
// handle_submit_update
 
2436
//-------------------------------------------------------------------------
 
2437
 
 
2438
static int
 
2439
handle_submit_update(WebHttpContext * whc, const char *file)
 
2440
{
 
2441
  NOWARN_UNUSED(file);
 
2442
  int err;
 
2443
  char *submit_from_page;
 
2444
  bool recs_out_of_date;
 
2445
  bool file_out_of_date;
 
2446
  char *record_version;
 
2447
  char *file_version;
 
2448
  char *file_contents;
 
2449
  char *file_checksum;
 
2450
  char *apply;
 
2451
  char *cancel;
 
2452
  char *clear;
 
2453
  char *clear_cluster;
 
2454
  bool use_ssl_updated;
 
2455
 
 
2456
  // check for submit_from_page
 
2457
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
2458
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
2459
    whc->top_level_render_file = xstrdup(submit_from_page);
 
2460
  } else {
 
2461
    submit_from_page = NULL;
 
2462
  }
 
2463
 
 
2464
  // check for cancel
 
2465
  if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel)) {
 
2466
    goto Ldone;
 
2467
  }
 
2468
  // check for restart
 
2469
  if (ink_hash_table_lookup(whc->post_data_ht, "restart", (void **) &cancel)) {
 
2470
#ifndef NO_WEBUI
 
2471
    char *link = WebHttpGetLink_Xmalloc(HTML_DEFAULT_CONFIGURE_FILE);
 
2472
    whc->response_hdr->setRefreshURL(link);
 
2473
    xfree(link);
 
2474
#endif
 
2475
    lmgmt->ccom->sendClusterMessage(CLUSTER_MSG_SHUTDOWN_MANAGER);
 
2476
    whc->response_hdr->setRefresh(15);
 
2477
    if (submit_from_page)
 
2478
      xfree(submit_from_page);
 
2479
    submit_from_page = xstrdup("/restart.ink");
 
2480
    goto Ldone;
 
2481
  }
 
2482
  // check for clear statistics
 
2483
  if (ink_hash_table_lookup(whc->post_data_ht, "clear_stats", (void **) &clear)) {
 
2484
    lmgmt->clearStats();
 
2485
    goto Ldone;
 
2486
  }
 
2487
  // check for cluster clear statistics
 
2488
  if (ink_hash_table_lookup(whc->post_data_ht, "clear_cluster_stats", (void **) &clear_cluster)) {
 
2489
    lmgmt->clearStats();
 
2490
    lmgmt->ccom->sendClusterMessage(CLUSTER_MSG_CLEAR_STATS);
 
2491
    goto Ldone;
 
2492
  }
 
2493
  // check for roll_logs
 
2494
  if (ink_hash_table_lookup(whc->post_data_ht, "roll_logs", (void **) &cancel)) {
 
2495
    lmgmt->rollLogFiles();
 
2496
    goto Ldone;
 
2497
  }
 
2498
  // check for apply
 
2499
  if (ink_hash_table_lookup(whc->post_data_ht, "apply", (void **) &apply)) {
 
2500
    ink_hash_table_delete(whc->post_data_ht, "apply");
 
2501
    xfree(apply);
 
2502
  }
 
2503
  // check for record_version
 
2504
  recs_out_of_date = true;
 
2505
  if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
 
2506
    // TODO: Check return value?
 
2507
    recs_out_of_date = !record_version_valid(record_version);
 
2508
    ink_hash_table_delete(whc->post_data_ht, "record_version");
 
2509
    xfree(record_version);
 
2510
  }
 
2511
  // check for a file_version and file_contents
 
2512
  file_out_of_date = false;
 
2513
  if (ink_hash_table_lookup(whc->post_data_ht, "file_version", (void **) &file_version)) {
 
2514
    if (ink_hash_table_lookup(whc->post_data_ht, "file_contents", (void **) &file_contents)) {
 
2515
      file_out_of_date = true;
 
2516
      if (ink_hash_table_lookup(whc->post_data_ht, "file_checksum", (void **) &file_checksum)) {
 
2517
        if (!file_version) {
 
2518
          file_version = (char *) xstrdup("");
 
2519
        }
 
2520
        if (!file_contents) {
 
2521
          file_contents = (char *) xstrdup("");
 
2522
        }
 
2523
        if (!file_checksum) {
 
2524
          file_checksum = (char *) xstrdup("");
 
2525
        }
 
2526
        file_out_of_date = !set_config_file(whc, file_version, file_contents, file_checksum);
 
2527
        ink_hash_table_delete(whc->post_data_ht, "file_checksum");
 
2528
        if (file_checksum)
 
2529
          xfree(file_checksum);
 
2530
      }
 
2531
      ink_hash_table_delete(whc->post_data_ht, "file_contents");
 
2532
      if (file_contents)
 
2533
        xfree(file_contents);
 
2534
    }
 
2535
    ink_hash_table_delete(whc->post_data_ht, "file_version");
 
2536
    if (file_version)
 
2537
      xfree(file_version);
 
2538
  }
 
2539
  // everything else should be records. if the user modifies the
 
2540
  // 'proxy.config.admin.use_ssl' variable, we'll have to redirect
 
2541
  // them appropriately.
 
2542
  use_ssl_updated = false;
 
2543
  if (!recs_out_of_date) {
 
2544
    InkHashTableIteratorState htis;
 
2545
    InkHashTableEntry *hte;
 
2546
    char *record;
 
2547
    char *value;
 
2548
    for (hte = ink_hash_table_iterator_first(whc->post_data_ht, &htis);
 
2549
         hte != NULL; hte = ink_hash_table_iterator_next(whc->post_data_ht, &htis)) {
 
2550
      record = (char *) ink_hash_table_entry_key(whc->post_data_ht, hte);
 
2551
      value = (char *) ink_hash_table_entry_value(whc->post_data_ht, hte);
 
2552
      // check for ssl redirect
 
2553
      if (strcasecmp(record, "proxy.config.admin.use_ssl") == 0) {
 
2554
        char use_ssl_value[MAX_VAL_LENGTH];     // The value of the current variable
 
2555
        if ((varStrFromName(record, use_ssl_value, MAX_VAL_LENGTH)) && (ink_atoi(value) != ink_atoi(use_ssl_value))
 
2556
          ) {
 
2557
          use_ssl_updated = true;
 
2558
        }
 
2559
      }
 
2560
    }
 
2561
  }
 
2562
  // warn if out of date submission
 
2563
  if (recs_out_of_date || file_out_of_date) {
 
2564
    HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_OUT_OF_DATE);
 
2565
    HtmlRndrBr(whc->submit_warn);
 
2566
    whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2567
  }
 
2568
 
 
2569
  if (use_ssl_updated) {
 
2570
    if (submit_from_page) {
 
2571
      xfree(submit_from_page);
 
2572
    }
 
2573
    submit_from_page = xstrdup("/ssl_redirect.ink");
 
2574
  }
 
2575
 
 
2576
#ifndef NO_WEBUI
 
2577
  if (submit_from_page && strcmp(submit_from_page, HTML_FEATURE_ON_OFF_FILE) == 0) {
 
2578
    WebHttpTreeRebuildJsTree();
 
2579
  }
 
2580
#endif
 
2581
 
 
2582
Ldone:
 
2583
  if (submit_from_page) {
 
2584
    err = WebHttpRender(whc, submit_from_page);
 
2585
    xfree(submit_from_page);
 
2586
  } else {
 
2587
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
2588
  }
 
2589
  return err;
 
2590
 
 
2591
}
 
2592
 
 
2593
//-------------------------------------------------------------------------
 
2594
// handle_submit_update_config
 
2595
//-------------------------------------------------------------------------
 
2596
// This handler is called when submit a post form for Configuration File Editor.
 
2597
// Uses the hidden tag values to construct and write  new config file.
 
2598
// If the user presses Cancel, then it should also close
 
2599
// the current window without committing any changes. If hit "Apply", then
 
2600
// commits the changes before closing editor window.
 
2601
//    Since the Configuration File Editor opens in a separate window,
 
2602
// each time a user hits "Apply", we need to also update the table listing all
 
2603
// the config rules on the original tab page from which the File Editor window
 
2604
// was launched - the orignal page is refreshed regularly in order to keep the
 
2605
// the values in sync with the Configuration File Editor page (is there a
 
2606
// better way to do this??)
 
2607
//    The file parameter is not used in this handler because a generic
 
2608
// c_config_display.ink is used for all files. We determine which file
 
2609
// is being revised by using the filename tag that's passed in with the
 
2610
// GET request.
 
2611
static int
 
2612
handle_submit_update_config(WebHttpContext * whc, const char *file)
 
2613
{
 
2614
  NOWARN_UNUSED(file);
 
2615
  char **rules = NULL;
 
2616
  char name[10];                // "rule#"
 
2617
  char *close;
 
2618
  char *apply;
 
2619
  char *filename;
 
2620
  char *frecord;
 
2621
  INKFileNameT type;
 
2622
  int i, numRules = 0;
 
2623
  int err = WEB_HTTP_ERR_OKAY;
 
2624
  char *errBuff = NULL;
 
2625
 
 
2626
  // check for close
 
2627
  if (ink_hash_table_lookup(whc->post_data_ht, "close", (void **) &close)) {
 
2628
    //goto Ldone;
 
2629
    return WEB_HTTP_ERR_OKAY;
 
2630
  }
 
2631
  // check for apply
 
2632
  if (ink_hash_table_lookup(whc->post_data_ht, "apply", (void **) &apply)) {
 
2633
    ink_hash_table_delete(whc->post_data_ht, "apply");
 
2634
    xfree(apply);
 
2635
  }
 
2636
  // This portion of the code handles parsing the hidden tags with all
 
2637
  // the current ruleList information; commits this information as new config file
 
2638
 
 
2639
  // get the filename to create the INKCfgContext; do NOT delete the
 
2640
  // HTML_CONFIG_FILE_TAG entry because we need to use the filename
 
2641
  // binding to refresh the page
 
2642
  if (!ink_hash_table_lookup(whc->post_data_ht, HTML_CONFIG_FILE_TAG, (void **) &filename)) {
 
2643
    // ERROR: no config file specified!!
 
2644
    whc->response_hdr->setStatus(STATUS_NOT_FOUND);
 
2645
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
2646
    goto Lerror;
 
2647
  }
 
2648
  // CONFIG-SPECIFIC
 
2649
  if (ink_hash_table_lookup(g_display_config_ht, filename, (void **) &type)) {
 
2650
 
 
2651
    int maxRules = 0;
 
2652
    INKCfgContext ctx = INKCfgContextCreate(type);
 
2653
    if (ctx && (INKCfgContextGet(ctx) == INK_ERR_OKAY)) {
 
2654
      maxRules = INKCfgContextGetCount(ctx) + MAX_ADD_RULES;
 
2655
      INKCfgContextDestroy(ctx);
 
2656
    }
 
2657
 
 
2658
    // read all the rules from the post form into an array of strings
 
2659
    numRules = 0;
 
2660
    if (maxRules > 0) {
 
2661
      rules = new char *[maxRules];
 
2662
      for (i = 0; i < maxRules; i++) {
 
2663
        memset(name, 0, 10);
 
2664
        snprintf(name, sizeof(name), "rule%d", i);
 
2665
 
 
2666
        if (ink_hash_table_lookup(whc->post_data_ht, name, (void **) &(rules[i]))) {
 
2667
          // do not delete entry from table yet
 
2668
          if (rules[i])
 
2669
            numRules++;
 
2670
          else
 
2671
            break;              // exit because no more valid rules to read
 
2672
        }
 
2673
      }
 
2674
    }
 
2675
 
 
2676
    switch (type) {
 
2677
    case INK_FNAME_CACHE_OBJ:
 
2678
      err = updateCacheConfig(rules, numRules, &errBuff);
 
2679
      break;
 
2680
    case INK_FNAME_HOSTING:
 
2681
      err = updateHostingConfig(rules, numRules, &errBuff);
 
2682
      break;
 
2683
    case INK_FNAME_ICP_PEER:
 
2684
      err = updateIcpConfig(rules, numRules, &errBuff);
 
2685
      break;
 
2686
    case INK_FNAME_IP_ALLOW:
 
2687
      err = updateIpAllowConfig(rules, numRules, &errBuff);
 
2688
      break;
 
2689
    case INK_FNAME_MGMT_ALLOW:
 
2690
      err = updateMgmtAllowConfig(rules, numRules, &errBuff);
 
2691
      break;
 
2692
    case INK_FNAME_PARENT_PROXY:
 
2693
      err = updateParentConfig(rules, numRules, &errBuff);
 
2694
      break;
 
2695
    case INK_FNAME_PARTITION:
 
2696
      err = updatePartitionConfig(rules, numRules, &errBuff);
 
2697
      break;
 
2698
    case INK_FNAME_REMAP:
 
2699
      err = updateRemapConfig(rules, numRules, &errBuff);
 
2700
      break;
 
2701
    case INK_FNAME_SOCKS:
 
2702
      err = updateSocksConfig(rules, numRules, &errBuff);
 
2703
      break;
 
2704
    case INK_FNAME_SPLIT_DNS:
 
2705
      err = updateSplitDnsConfig(rules, numRules, &errBuff);
 
2706
      break;
 
2707
    case INK_FNAME_UPDATE_URL:
 
2708
      err = updateUpdateConfig(rules, numRules, &errBuff);
 
2709
      break;
 
2710
    case INK_FNAME_VADDRS:
 
2711
      err = updateVaddrsConfig(rules, numRules, &errBuff);
 
2712
      break;
 
2713
    default:
 
2714
      err = WEB_HTTP_ERR_FAIL;
 
2715
      break;
 
2716
    }
 
2717
 
 
2718
    // do not delete the strings in the array because
 
2719
    // the binding still exists in the hashtable, so memory will
 
2720
    // be freed when post_data_ht destroyed
 
2721
    if (rules)
 
2722
      delete[]rules;
 
2723
 
 
2724
  } else {                      // missing binding from f_xx_config.ink to INKFileNameT
 
2725
    whc->response_hdr->setStatus(STATUS_NOT_FOUND);
 
2726
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
2727
    goto Lerror;
 
2728
  }
 
2729
 
 
2730
  if (err == WEB_HTTP_ERR_INVALID_CFG_RULE) {
 
2731
    whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2732
    HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_CFG_INVALID_RULE);
 
2733
    HtmlRndrBr(whc->submit_warn);
 
2734
 
 
2735
    if (errBuff) {
 
2736
      whc->submit_warn->copyFrom(errBuff, strlen(errBuff));
 
2737
      xfree(errBuff);
 
2738
    }
 
2739
  } else if (err != WEB_HTTP_ERR_OKAY) {
 
2740
    HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_CFG_COMMIT_ERROR);
 
2741
    HtmlRndrBr(whc->submit_warn);
 
2742
    whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2743
  }
 
2744
  // do not remove and free frecord from post_data_ht because
 
2745
  // the renderer fn will use it to write the hidden tag
 
2746
  if (ink_hash_table_lookup(whc->post_data_ht, "frecord", (void **) &frecord)) {
 
2747
    if (recordRestartCheck(frecord)) {
 
2748
      ink_hash_table_insert(whc->submit_note_ht, frecord, NULL);
 
2749
      if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_NOTE)) {
 
2750
        HtmlRndrText(whc->submit_note, whc->lang_dict_ht, HTML_ID_RESTART_REQUIRED_FILE);
 
2751
        HtmlRndrBr(whc->submit_note);
 
2752
      }
 
2753
      whc->request_state |= WEB_HTTP_STATE_SUBMIT_NOTE;
 
2754
    }
 
2755
  }
 
2756
 
 
2757
  err = WebHttpRender(whc, HTML_CONFIG_DISPLAY_FILE);
 
2758
  return err;
 
2759
 
 
2760
Lerror:
 
2761
  mgmt_log("[handle_submit_update_config] Error updating config file");
 
2762
  return WEB_HTTP_ERR_REQUEST_ERROR;
 
2763
 
 
2764
}
 
2765
 
 
2766
//-------------------------------------------------------------------------
 
2767
// handle_submit_config_display
 
2768
//-------------------------------------------------------------------------
 
2769
// This handler is called when user wants to open the Configuration Editor
 
2770
// window to edit a config file; so it main purpose is simply to
 
2771
// render the configurator.ink page
 
2772
static int
 
2773
handle_submit_config_display(WebHttpContext * whc, const char *file)
 
2774
{
 
2775
  NOWARN_UNUSED(file);
 
2776
  // same HTML_CONFIG_DISPLAY_FILE for all config files
 
2777
  return WebHttpRender(whc, HTML_CONFIG_DISPLAY_FILE);
 
2778
}
 
2779
 
 
2780
 
 
2781
//-------------------------------------------------------------------------
 
2782
// network configuration
 
2783
//-------------------------------------------------------------------------
 
2784
 
 
2785
 
 
2786
bool
 
2787
NICCheck(WebHttpContext * whc, char *updown, char *arg)
 
2788
{
 
2789
  bool result;
 
2790
 
 
2791
  result = true;
 
2792
 
 
2793
  if (strcmp(updown, "0") == 0) {
 
2794
    result = false;
 
2795
    ink_hash_table_insert(whc->submit_warn_ht, arg, NULL);
 
2796
    if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2797
      HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
 
2798
      HtmlRndrBr(whc->submit_warn);
 
2799
    }
 
2800
    whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2801
  }
 
2802
  return result;
 
2803
}
 
2804
 
 
2805
void
 
2806
SetWarning(WebHttpContext * whc, char *arg)
 
2807
{
 
2808
  ink_hash_table_insert(whc->submit_warn_ht, arg, NULL);
 
2809
  if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
2810
    HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_INVALID_ENTRY);
 
2811
    HtmlRndrBr(whc->submit_warn);
 
2812
  }
 
2813
  whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
2814
}
 
2815
 
 
2816
//-------------------------------------------------------------------------
 
2817
// handle_submit_net_config
 
2818
//-------------------------------------------------------------------------
 
2819
// This handler is called when user wants to setup network of the appliance
 
2820
 
 
2821
static int
 
2822
handle_submit_net_config(WebHttpContext * whc, const char *file)
 
2823
{
 
2824
  NOWARN_UNUSED(file);
 
2825
  char *cancel;
 
2826
  char *record_version;
 
2827
  char *submit_from_page;
 
2828
//  FILE* tmp;
 
2829
 
 
2830
//  tmp=fopen("tmp","a");
 
2831
//  fprintf(tmp,"enter submit\n");
 
2832
 
 
2833
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
2834
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
2835
    whc->top_level_render_file = xstrdup(submit_from_page);
 
2836
  } else {
 
2837
    submit_from_page = NULL;
 
2838
  }
 
2839
  // check for cancel
 
2840
  if (ink_hash_table_lookup(whc->post_data_ht, "cancel", (void **) &cancel))
 
2841
    return WebHttpRender(whc, submit_from_page);
 
2842
 
 
2843
  // check for record_version
 
2844
  if (ink_hash_table_lookup(whc->post_data_ht, "record_version", (void **) &record_version)) {
 
2845
    // TODO: Check return value?
 
2846
    record_version_valid(record_version);
 
2847
    ink_hash_table_delete(whc->post_data_ht, "record_version");
 
2848
    xfree(record_version);
 
2849
  }
 
2850
//  if (recs_out_of_date)
 
2851
//    goto Lout_of_date;
 
2852
 
 
2853
#if defined(linux) || defined(solaris)
 
2854
 
 
2855
  InkHashTableIteratorState htis;
 
2856
  InkHashTableEntry *hte;
 
2857
  char *key;
 
2858
  char *value;
 
2859
  int hn_change, gw_change, dn_change, dns_change;
 
2860
  int nic_change[5];
 
2861
  //  int nic_up[5];
 
2862
  char *dns_ip[3], old_value[265], old_hostname[80], old_gw_ip[80];
 
2863
  char nic_name[5][10], *nic[5][6], interface[80], *param;
 
2864
  char *hostname = 0, *gw_ip = 0;
 
2865
  const char *dn = 0;
 
2866
  int i, j, no;
 
2867
  char dns_ips[80];
 
2868
  bool warning, fail;
 
2869
 
 
2870
  //This will be used as flags to verify whether anything changed by the user
 
2871
  hn_change = 0;
 
2872
  gw_change = 0;
 
2873
  dn_change = 0;
 
2874
  dns_change = 0;
 
2875
  warning = (fail = false);
 
2876
  //FIXNOW - we need to use SysAPI to find the numver of NICs instead of just constant 5
 
2877
  for (i = 0; i < 5; i++) {
 
2878
    nic_change[i] = 0;
 
2879
    ink_strncpy(nic_name[i], "", 1);
 
2880
    for (j = 0; j < 6; j++) {
 
2881
      nic[i][j] = NULL;
 
2882
    }
 
2883
  }
 
2884
 
 
2885
  int old_euid;
 
2886
  Config_User_Root(&old_euid);
 
2887
  // Get the values the user entered
 
2888
  for (hte = ink_hash_table_iterator_first(whc->post_data_ht, &htis);
 
2889
       hte != NULL; hte = ink_hash_table_iterator_next(whc->post_data_ht, &htis)) {
 
2890
    key = (char *) ink_hash_table_entry_key(whc->post_data_ht, hte);
 
2891
    value = (char *) ink_hash_table_entry_value(whc->post_data_ht, hte);
 
2892
 
 
2893
//    fprintf(stderr,"key=%s, value=%s\n",key,value);
 
2894
 
 
2895
    if (strcmp(key, "HOSTNAME") == 0) {
 
2896
      hostname = value;
 
2897
      if (!Net_IsValid_Hostname(hostname)) {
 
2898
        SetWarning(whc, key);
 
2899
        warning = true;
 
2900
      } else {
 
2901
        if (!Config_GetHostname(old_value, sizeof(old_value))) {
 
2902
          if (hostname != NULL && strcmp(hostname, old_value) != 0) {
 
2903
            hn_change = 1;
 
2904
            ink_strncpy(old_hostname, old_value, sizeof(old_hostname)); //old hostname is used in MGMT API
 
2905
          }
 
2906
        } else if (hostname != NULL) {
 
2907
          hn_change = 1;
 
2908
        }
 
2909
      }
 
2910
    } else if (strcmp(key, "GATEWAY") == 0) {
 
2911
      gw_ip = value;
 
2912
      if (!Net_IsValid_IP(gw_ip)) {
 
2913
        SetWarning(whc, key);
 
2914
        warning = true;
 
2915
      } else {
 
2916
        if (!Config_GetDefaultRouter(old_value, sizeof(old_value))) {
 
2917
          if (gw_ip != NULL && strcmp(gw_ip, old_value) != 0) {
 
2918
            ink_strncpy(old_gw_ip, old_value, sizeof(old_gw_ip));
 
2919
            gw_change = 1;
 
2920
          }
 
2921
        } else if (gw_ip != NULL) {
 
2922
          gw_change = 1;
 
2923
        }
 
2924
      }
 
2925
    } else if (strcmp(key, "domain") == 0) {
 
2926
      dn = value;
 
2927
      if (!Config_GetDomain(old_value, sizeof(old_value))) {
 
2928
        if (dn != NULL && strcmp(dn, old_value) != 0) {
 
2929
          dn_change = 1;
 
2930
        } else if (dn == NULL) {
 
2931
          dn_change = 1;
 
2932
          dn = "";
 
2933
        }
 
2934
      } else if (dn != NULL) {
 
2935
        dn_change = 1;
 
2936
      }
 
2937
    } else if (strstr(key, "DNS") != NULL) {
 
2938
      no = atoi(key + 3) - 1;
 
2939
      dns_ip[no] = value;
 
2940
      if (!Net_IsValid_IP(dns_ip[no])) {
 
2941
        SetWarning(whc, key);
 
2942
        warning = true;
 
2943
      } else {
 
2944
        if (Config_GetDNS_Server(old_value, sizeof(old_value), no)) {
 
2945
          if (dns_ip[no] != NULL && strcmp(dns_ip[no], old_value) != 0) {
 
2946
            dns_change = 1;
 
2947
          } else if (dns_ip[no] == NULL) {
 
2948
            dns_change = 1;
 
2949
          }
 
2950
        } else if (dns_ip[no] != NULL) {
 
2951
          dns_change = 1;
 
2952
        }
 
2953
      }
 
2954
    } else if (strstr(key, "NIC") != NULL) {
 
2955
      ink_strncpy(interface, key + 4, sizeof(interface));
 
2956
      param = strchr(interface, '_');
 
2957
      *param = '\0';
 
2958
      param++;
 
2959
      no = atoi(interface + 3);
 
2960
      ink_strncpy(nic_name[no], interface, sizeof(nic_name[no]));
 
2961
 
 
2962
      //No DHCP support any more, hacking way is set it be static always
 
2963
      nic[no][2] = xstrdup("1");
 
2964
      if (strcmp(param, "enabled") == 0) {
 
2965
        nic[no][0] = value;
 
2966
 
 
2967
        if (no == 0) {
 
2968
          //FIXNOW use SysAPI
 
2969
          if (strcmp(nic[no][0], "0") == 0) {
 
2970
            SetWarning(whc, key);
 
2971
            warning = true;
 
2972
          }
 
2973
        }
 
2974
        //FIXNOW - Use SysAPI
 
2975
        Config_GetNIC_Status(interface, old_value, sizeof(old_value));
 
2976
        if (strcmp(old_value, "up") == 0 && strcmp(nic[no][0], "0") == 0) {
 
2977
          nic_change[no] = 1;
 
2978
        } else if (strcmp(old_value, "down") == 0 && strcmp(nic[no][0], "1") == 0) {
 
2979
          nic_change[no] = 1;
 
2980
        }
 
2981
      } else if (strcmp(param, "ONBOOT") == 0) {
 
2982
        nic[no][1] = value;
 
2983
 
 
2984
        if (no == 0) {
 
2985
          //FIXNOW use SysAPI
 
2986
          if (strcmp(nic[no][1], "0") == 0) {
 
2987
            SetWarning(whc, key);
 
2988
            warning = true;
 
2989
          }
 
2990
        }
 
2991
        //FIXNOW - Use SysAPI
 
2992
        if (!Config_GetNIC_Start(interface, old_value, sizeof(old_value))) {
 
2993
          if (strcmp(nic[no][1], "1") == 0 && strcmp(old_value, "not-onboot") == 0) {
 
2994
            nic_change[no] = 1;
 
2995
          } else if (strcmp(nic[no][1], "0") == 0 && strcmp(old_value, "onboot") == 0) {
 
2996
            nic_change[no] = 1;
 
2997
          }
 
2998
        } else {
 
2999
          nic_change[no] = 1;
 
3000
        }
 
3001
      } else if (strcmp(param, "BOOTPROTO") == 0) {
 
3002
        nic[no][2] = value;
 
3003
        //FIXNOW - Use SysAPI
 
3004
        if (!Config_GetNIC_Protocol(interface, old_value, sizeof(old_value))) {
 
3005
          if (strcmp(nic[no][2], "0") == 0 && (strcmp(old_value, "none") == 0 || strcmp(old_value, "static") == 0)) {
 
3006
            nic_change[no] = 1;
 
3007
          } else if (strcmp(nic[no][2], "1") == 0 && strcmp(old_value, "dhcp") == 0) {
 
3008
            nic_change[no] = 1;
 
3009
          }
 
3010
        } else {
 
3011
          nic_change[no] = 1;
 
3012
        }
 
3013
 
 
3014
        //currently, force the protocol to become static if the old one is dhcp
 
3015
        if (strcmp(old_value, "dhcp") == 0) {
 
3016
          // XXX - changed it so we don't change value and instead duplicate the string
 
3017
          nic[no][2] = xstrdup("1");
 
3018
          nic_change[no] = 1;
 
3019
        }
 
3020
      } else if (strcmp(param, "IPADDR") == 0) {
 
3021
        nic[no][3] = value;
 
3022
        //FIXNOW - Use SysAPI
 
3023
        if (!Net_IsValid_IP(nic[no][3])) {
 
3024
          SetWarning(whc, key);
 
3025
          warning = true;
 
3026
        }
 
3027
        //FIXNOW - Use SysAPI
 
3028
        if (!Config_GetNIC_IP(interface, old_value, sizeof(old_value))) {
 
3029
          if (nic[no][3] != NULL && strcmp(nic[no][3], old_value) != 0) {
 
3030
            nic_change[no] = 1;
 
3031
          }
 
3032
          //For dhcp start, the static IP maybe same with the dhcp value
 
3033
          else {
 
3034
            char protocol[80];
 
3035
            Config_GetNIC_Protocol(interface, protocol, sizeof(protocol));
 
3036
            if (strcmp(protocol, "dhcp") == 0) {
 
3037
              nic_change[no] = 1;
 
3038
            }
 
3039
 
 
3040
            if (nic[no][3] == NULL) {
 
3041
              nic_change[no] = 1;
 
3042
            }
 
3043
          }
 
3044
        } else if (nic[no][3] != NULL) {
 
3045
          nic_change[no] = 1;
 
3046
        }
 
3047
      } else if (strcmp(param, "NETMASK") == 0) {
 
3048
        nic[no][4] = value;
 
3049
        //FIXNOW - Use SysAPI
 
3050
        if (!Net_IsValid_IP(nic[no][4])) {
 
3051
          SetWarning(whc, key);
 
3052
          warning = true;
 
3053
        }
 
3054
        //FIXNOW - Use SysAPI
 
3055
        if (!Config_GetNIC_Netmask(interface, old_value, sizeof(old_value))) {
 
3056
          if (nic[no][4] != NULL && strcmp(nic[no][4], old_value) != 0) {
 
3057
            nic_change[no] = 1;
 
3058
          }
 
3059
          //For dhcp start, the static netmask maybe same with the dhcp value
 
3060
          else {
 
3061
            char protocol[80];
 
3062
            Config_GetNIC_Protocol(interface, protocol, sizeof(protocol));
 
3063
            if (strcmp(protocol, "dhcp") == 0) {
 
3064
              nic_change[no] = 1;
 
3065
            }
 
3066
 
 
3067
            if (nic[no][4] == NULL) {
 
3068
              nic_change[no] = 1;
 
3069
            }
 
3070
          }
 
3071
        } else if (nic[no][4] != NULL) {
 
3072
          nic_change[no] = 1;
 
3073
        }
 
3074
      } else if (strcmp(param, "GATEWAY") == 0) {
 
3075
        nic[no][5] = value;
 
3076
        //FIXNOW - Use SysAPI
 
3077
        if (!Net_IsValid_IP(nic[no][5])) {
 
3078
          SetWarning(whc, key);
 
3079
          warning = true;
 
3080
        }
 
3081
        //FIXNOW - Use SysAPI
 
3082
        if (!Config_GetNIC_Gateway(interface, old_value, sizeof(old_value))) {
 
3083
          if (nic[no][5] != NULL && strcmp(nic[no][5], old_value) != 0) {
 
3084
            nic_change[no] = 1;
 
3085
          }
 
3086
          //For dhcp start, the gateway maybe same with the dhcp value
 
3087
          else {
 
3088
            char protocol[80];
 
3089
            Config_GetNIC_Protocol(interface, protocol, sizeof(protocol));
 
3090
            if (strcmp(protocol, "dhcp") == 0) {
 
3091
              nic_change[no] = 1;
 
3092
            }
 
3093
 
 
3094
            if (nic[no][5] == NULL) {
 
3095
              nic_change[no] = 1;
 
3096
            }
 
3097
          }
 
3098
        } else if (nic[no][5] != NULL) {
 
3099
          nic_change[no] = 1;
 
3100
        }
 
3101
      }
 
3102
    }
 
3103
  }
 
3104
  Config_User_Inktomi(old_euid);
 
3105
 
 
3106
  if (!warning) {
 
3107
    if (hn_change) {
 
3108
      if (Config_SetHostname(hostname) != 0) {
 
3109
        fail = true;
 
3110
      }
 
3111
    }
 
3112
    if (gw_change) {
 
3113
      if (Config_SetDefaultRouter(gw_ip) != 0) {
 
3114
        fail = true;
 
3115
      }
 
3116
    }
 
3117
    if (dn_change) {
 
3118
      if (Config_SetDomain(dn) != 0) {
 
3119
        fail = true;
 
3120
      }
 
3121
    }
 
3122
    if (dns_change) {
 
3123
      ink_strncpy(dns_ips, "", sizeof(dns_ips));
 
3124
      //FIXNOW - do we have no. of dns servers from SysAPI?
 
3125
      for (i = 0; i < 3; i++) {
 
3126
        if (dns_ip[i] != NULL) {
 
3127
          strncat(dns_ips, dns_ip[i], sizeof(dns_ips) - strlen(dns_ips) - 1);
 
3128
          strncat(dns_ips, " ", sizeof(dns_ips) - strlen(dns_ips) - 1);
 
3129
        }
 
3130
      }
 
3131
 
 
3132
      if (Config_SetDNS_Servers(dns_ips) != 0) {
 
3133
        fail = true;
 
3134
      }
 
3135
    }
 
3136
    //FIXNOW - get the no. from SysAPI
 
3137
    for (i = 0; i < 5; i++) {
 
3138
      if (strlen(nic_name[i]) != 0) {
 
3139
        if (nic_change[i]) {
 
3140
          if (nic[i][0] != NULL && strcmp(nic[i][0], "1") == 0) {
 
3141
            char onboot[20], protocol[20];
 
3142
            if (strcmp(nic[i][1], "1") == 0) {
 
3143
              ink_strncpy(onboot, "onboot", sizeof(onboot));
 
3144
            } else {
 
3145
              ink_strncpy(onboot, "not-onboot", sizeof(onboot));
 
3146
            }
 
3147
 
 
3148
            if (strcmp(nic[i][2], "1") == 0) {
 
3149
              ink_strncpy(protocol, "static", sizeof(protocol));
 
3150
            } else {
 
3151
              ink_strncpy(protocol, "dhcp", sizeof(protocol));
 
3152
            }
 
3153
            if (Config_SetNIC_Up(nic_name[i], onboot, protocol, nic[i][3], nic[i][4], nic[i][5]) != 0) {
 
3154
              fail = true;
 
3155
            }
 
3156
          } else {
 
3157
            char status[80];
 
3158
            Config_GetNIC_Status(nic_name[i], status, sizeof(status));
 
3159
            if (strcmp(status, "up") == 0) {    //NIC is disabled
 
3160
              if (Config_SetNIC_Down(nic_name[i]) != 0) {
 
3161
                fail = true;
 
3162
              }
 
3163
            } else {            //NIC is down&changed, such changes are disallowed.
 
3164
              if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
3165
                HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NETWORK_CONFIG_DISALLOW);
 
3166
                HtmlRndrBr(whc->submit_warn);
 
3167
              }
 
3168
              whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
3169
            }
 
3170
          }                     //nic[i][0]
 
3171
        }                       //nic_change
 
3172
      }                         //nic_name
 
3173
    }                           //for
 
3174
  }                             //warning
 
3175
//FIXME, need a complete fail message system
 
3176
  if (fail == true) {
 
3177
    if (!(whc->request_state & WEB_HTTP_STATE_SUBMIT_WARN)) {
 
3178
      HtmlRndrText(whc->submit_warn, whc->lang_dict_ht, HTML_ID_NETWORK_CONFIG_FAIL);
 
3179
      HtmlRndrBr(whc->submit_warn);
 
3180
    }
 
3181
    whc->request_state |= WEB_HTTP_STATE_SUBMIT_WARN;
 
3182
  }
 
3183
 
 
3184
  if (hn_change) {
 
3185
    if (submit_from_page)
 
3186
      xfree(submit_from_page);
 
3187
    submit_from_page = xstrdup("/rename.ink");
 
3188
  }
 
3189
#endif
 
3190
  return WebHttpRender(whc, submit_from_page);
 
3191
}
 
3192
 
 
3193
//-------------------------------------------------------------------------
 
3194
// handle_submit_otw_upgrade
 
3195
//-------------------------------------------------------------------------
 
3196
static int
 
3197
handle_submit_otw_upgrade(WebHttpContext * whc, const char *file)
 
3198
{
 
3199
  NOWARN_UNUSED(file);
 
3200
  int err = WEB_HTTP_ERR_OKAY;
 
3201
  char *action;
 
3202
  char *working_dir;
 
3203
  char *submit_from_page;
 
3204
  char tmp[MAX_TMP_BUF_LEN];
 
3205
#ifndef NO_WEBUI
 
3206
  char *link;
 
3207
#endif
 
3208
  const char *cgi_path;
 
3209
 
 
3210
  if (ink_hash_table_lookup(whc->post_data_ht, "submit_from_page", (void **) &submit_from_page)) {
 
3211
    ink_hash_table_delete(whc->post_data_ht, "submit_from_page");
 
3212
    whc->top_level_render_file = xstrdup(submit_from_page);
 
3213
  } else {
 
3214
    submit_from_page = NULL;
 
3215
  }
 
3216
 
 
3217
#ifndef _WIN32
 
3218
 
 
3219
  if (ink_hash_table_lookup(whc->post_data_ht, "action", (void **) &action)) {
 
3220
    if (strcmp(action, "Cancel") == 0) {
 
3221
      // upgrade cancelled = return to HTML_OTW_UPGRADE_FILE
 
3222
      if (ink_hash_table_lookup(whc->post_data_ht, "working_dir", (void **) &working_dir)) {
 
3223
        // cleanup
 
3224
        snprintf(tmp, MAX_TMP_BUF_LEN, "/bin/rm -rf %s", working_dir);
 
3225
        NOWARN_UNUSED_RETURN(system(tmp));
 
3226
      }
 
3227
      if (submit_from_page)
 
3228
        xfree(submit_from_page);
 
3229
      submit_from_page = xstrdup(HTML_OTW_UPGRADE_FILE);
 
3230
      if (whc->top_level_render_file)
 
3231
        xfree(whc->top_level_render_file);
 
3232
      whc->top_level_render_file = xstrdup(submit_from_page);
 
3233
 
 
3234
    } else {
 
3235
      // start upgrade = render upgrade page + spawn traffic_shell.cgi script
 
3236
#ifndef NO_WEBUI
 
3237
      link = WebHttpGetLink_Xmalloc(HTML_DEFAULT_MONITOR_FILE);
 
3238
      xfree(link);
 
3239
#endif
 
3240
      cgi_path = WebHttpAddDocRoot_Xmalloc(whc, HTML_OTW_UPGRADE_CGI_FILE);
 
3241
      int old_euid, old_egid;
 
3242
      Config_User_Root(&old_euid);
 
3243
      Config_Grp_Root(&old_egid);
 
3244
      spawn_cgi(whc, cgi_path, NULL, true, true);
 
3245
      Config_User_Inktomi(old_euid);
 
3246
      Config_Grp_Inktomi(old_egid);
 
3247
      if (submit_from_page)
 
3248
        xfree(submit_from_page);
 
3249
      submit_from_page = xstrdup("/upgrade.ink");
 
3250
      xfree((char *) cgi_path);
 
3251
    }
 
3252
  }
 
3253
#endif
 
3254
  if (submit_from_page) {
 
3255
    err = WebHttpRender(whc, submit_from_page);
 
3256
    xfree(submit_from_page);
 
3257
  } else {
 
3258
    err = WebHttpRender(whc, HTML_DEFAULT_CONFIGURE_FILE);
 
3259
  }
 
3260
  return err;
 
3261
}
 
3262
 
 
3263
//-------------------------------------------------------------------------
 
3264
// handle_default
 
3265
//-------------------------------------------------------------------------
 
3266
 
 
3267
static int
 
3268
handle_default(WebHttpContext * whc, const char *file)
 
3269
{
 
3270
 
 
3271
  char *doc_root_file;
 
3272
  int file_size;
 
3273
  time_t file_date_gmt;
 
3274
  WebHandle h_file;
 
3275
 
 
3276
  httpMessage *request = whc->request;
 
3277
  httpResponse *response_hdr = whc->response_hdr;
 
3278
  textBuffer *response_bdy = whc->response_bdy;
 
3279
 
 
3280
  const char *request_file = file;
 
3281
  time_t request_file_ims;
 
3282
  int request_file_len;
 
3283
 
 
3284
  // requests are supposed to begin with a "/"
 
3285
  if (*request_file != '/') {
 
3286
    response_hdr->setStatus(STATUS_NOT_FOUND);
 
3287
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
3288
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3289
  }
 
3290
  // first, make sure there are no ..'s in path or root directory
 
3291
  // access in name for security reasons
 
3292
  if (strstr(request_file, "..") != NULL || strncmp(request_file, "//", 2) == 0) {
 
3293
    response_hdr->setStatus(STATUS_FORBIDDEN);
 
3294
    WebHttpSetErrorResponse(whc, STATUS_FORBIDDEN);
 
3295
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3296
  }
 
3297
 
 
3298
  if (strcmp("/", request_file) == 0) {
 
3299
    request_file = whc->default_file;
 
3300
  }
 
3301
  // check file type and set document type if appropiate
 
3302
  request_file_len = strlen(request_file);
 
3303
  if (strcmp(request_file + (request_file_len - 4), ".htm") == 0) {
 
3304
    response_hdr->setContentType(TEXT_HTML);
 
3305
  } else if (strcmp(request_file + (request_file_len - 5), ".html") == 0) {
 
3306
    response_hdr->setContentType(TEXT_HTML);
 
3307
  } else if (strcmp(request_file + (request_file_len - 4), ".css") == 0) {
 
3308
    response_hdr->setContentType(TEXT_CSS);
 
3309
  } else if (strcmp(request_file + (request_file_len - 4), ".gif") == 0) {
 
3310
    response_hdr->setContentType(IMAGE_GIF);
 
3311
  } else if (strcmp(request_file + (request_file_len - 4), ".jpg") == 0) {
 
3312
    response_hdr->setContentType(IMAGE_JPEG);
 
3313
  } else if (strcmp(request_file + (request_file_len - 5), ".jpeg") == 0) {
 
3314
    response_hdr->setContentType(IMAGE_JPEG);
 
3315
  } else if (strcmp(request_file + (request_file_len - 4), ".png") == 0) {
 
3316
    response_hdr->setContentType(IMAGE_PNG);
 
3317
  } else if (strcmp(request_file + (request_file_len - 4), ".jar") == 0) {
 
3318
    response_hdr->setContentType(APP_JAVA);
 
3319
  } else if (strcmp(request_file + (request_file_len - 3), ".js") == 0) {
 
3320
    response_hdr->setContentType(APP_JAVASCRIPT);
 
3321
  } else if (strcmp(request_file + (request_file_len - 4), ".der") == 0) {
 
3322
    response_hdr->setContentType(APP_X509);
 
3323
  } else if (strcmp(request_file + (request_file_len - 4), ".dat") == 0) {
 
3324
    response_hdr->setContentType(APP_AUTOCONFIG);
 
3325
    response_hdr->setCachable(0);
 
3326
  } else if (strcmp(request_file + (request_file_len - 4), ".pac") == 0) {
 
3327
    response_hdr->setContentType(APP_AUTOCONFIG);
 
3328
    // Fixed INKqa04312 - 02/21/1999 elam
 
3329
    // We don't want anyone to cache .pac files.
 
3330
    response_hdr->setCachable(0);
 
3331
  } else if (strcmp(request_file + (request_file_len - 4), ".zip") == 0) {
 
3332
    response_hdr->setContentType(APP_ZIP);
 
3333
  } else {
 
3334
    // don't serve file types that we don't know about; helps to lock
 
3335
    // down the webserver.  for example, when serving files out the
 
3336
    // etc/trafficserver/plugins directory, we don't want to allow the users to
 
3337
    // access the .so/.dll plugin files.
 
3338
    response_hdr->setStatus(STATUS_NOT_FOUND);
 
3339
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
3340
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3341
  }
 
3342
 
 
3343
  // append the appropriate doc_root on to the file
 
3344
  doc_root_file = WebHttpAddDocRoot_Xmalloc(whc, request_file);
 
3345
 
 
3346
  // open the requested file
 
3347
  if ((h_file = WebFileOpenR(doc_root_file)) == WEB_HANDLE_INVALID) {
 
3348
    //could not find file
 
3349
    xfree(doc_root_file);
 
3350
    response_hdr->setStatus(STATUS_NOT_FOUND);
 
3351
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
3352
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3353
  }
 
3354
  // get the file
 
3355
  file_size = WebFileGetSize(h_file);
 
3356
  file_date_gmt = WebFileGetDateGmt(h_file);
 
3357
  request_file_ims = request->getModTime();
 
3358
 
 
3359
  // special logic for the autoconf port
 
3360
  if ((whc->server_state & WEB_HTTP_SERVER_STATE_AUTOCONF) && (file_size == 0)) {
 
3361
    response_hdr->setStatus(STATUS_NOT_FOUND);
 
3362
    WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
3363
    WebFileClose(h_file);
 
3364
    xfree(doc_root_file);
 
3365
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3366
  }
 
3367
  // Check to see if the clients copy is up to date.  Ignore the
 
3368
  // stupid content length that Netscape Navigator sends on the
 
3369
  // If-Modified-Since line since it not in the HTTP 1.0 standard
 
3370
 
 
3371
  // Since the client sends If-Modified-Since in GMT, make sure that
 
3372
  // we transform mtime to GMT
 
3373
  if (request_file_ims != -1 && request_file_ims >= file_date_gmt) {
 
3374
    response_hdr->setStatus(STATUS_NOT_MODIFIED);
 
3375
  } else {
 
3376
    // fetch the file from disk to memory
 
3377
    response_hdr->setStatus(STATUS_OK);
 
3378
    response_hdr->setLength(file_size);
 
3379
    while (response_bdy->rawReadFromFile(h_file) > 0);
 
3380
  }
 
3381
  // set the document last-modified header
 
3382
  response_hdr->setLastMod(file_date_gmt);
 
3383
 
 
3384
  WebFileClose(h_file);
 
3385
  xfree(doc_root_file);
 
3386
 
 
3387
  return WEB_HTTP_ERR_OKAY;
 
3388
 
 
3389
}
 
3390
 
 
3391
 
 
3392
 
 
3393
//-------------------------------------------------------------------------
 
3394
// read_request
 
3395
//-------------------------------------------------------------------------
 
3396
 
 
3397
int
 
3398
read_request(WebHttpContext * whc)
 
3399
{
 
3400
 
 
3401
  const int buffer_size = 2048;
 
3402
  char *buffer = (char *) alloca(buffer_size);
 
3403
 
 
3404
  httpMessage *request = whc->request;
 
3405
  httpResponse *response_hdr = whc->response_hdr;
 
3406
 
 
3407
  // first get the request line
 
3408
  if (sigfdrdln(whc->si, buffer, buffer_size) < 0) {
 
3409
    // if we can not get the request line, update the status code so
 
3410
    // it can get logged correctly but do not bother trying to send a
 
3411
    // response
 
3412
    response_hdr->setStatus(STATUS_BAD_REQUEST);
 
3413
    return WEB_HTTP_ERR_REQUEST_FATAL;
 
3414
  }
 
3415
 
 
3416
 
 
3417
  if (request->addRequestLine(buffer) != 0) {
 
3418
    response_hdr->setStatus(STATUS_BAD_REQUEST);
 
3419
    WebHttpSetErrorResponse(whc, STATUS_BAD_REQUEST);
 
3420
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3421
  }
 
3422
  // Check for a scheme we do not understand
 
3423
  //
 
3424
  //  If we undertand the scheme, it has
 
3425
  //   to be HTTP
 
3426
  if (request->getScheme() == SCHEME_UNKNOWN) {
 
3427
    response_hdr->setStatus(STATUS_NOT_IMPLEMENTED);
 
3428
    WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
 
3429
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3430
  }
 
3431
 
 
3432
  if (request->getMethod() != METHOD_GET && request->getMethod() != METHOD_POST && request->getMethod() != METHOD_HEAD) {
 
3433
    response_hdr->setStatus(STATUS_NOT_IMPLEMENTED);
 
3434
    WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
 
3435
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3436
  }
 
3437
  // Read the headers of http request line by line until
 
3438
  //   we get a line that is solely composed of "\r" (or
 
3439
  //   just "" since not everyone follows the HTTP standard
 
3440
  //
 
3441
  do {
 
3442
    if (sigfdrdln(whc->si, buffer, buffer_size) < 0) {
 
3443
      response_hdr->setStatus(STATUS_BAD_REQUEST);
 
3444
      return WEB_HTTP_ERR_REQUEST_FATAL;
 
3445
    }
 
3446
    request->addHeader(buffer);
 
3447
  } while (strcmp(buffer, "\r") != 0 && *buffer != '\0');
 
3448
 
 
3449
  // If there is a content body, read it in
 
3450
  if (request->addRequestBody(whc->si) < 0) {
 
3451
    // There was error on reading the response body
 
3452
    response_hdr->setStatus(STATUS_BAD_REQUEST);
 
3453
    WebHttpSetErrorResponse(whc, STATUS_NOT_IMPLEMENTED);
 
3454
    return WEB_HTTP_ERR_REQUEST_ERROR;
 
3455
  }
 
3456
 
 
3457
  // Drain read channel: In the case of Linux, OS sends reset to the
 
3458
  // socket if we close it when there is data left on it ot be read
 
3459
  // (in compliance with TCP). This causes problems with the "POST"
 
3460
  // method. (for example with update.html). With IE, we found ending
 
3461
  // "\r\n" were not read.  The following work around is to read all
 
3462
  // that is left in the socket before closing it.  The same problem
 
3463
  // applies for Windows 2000 as well.
 
3464
#if !defined(_WIN32)
 
3465
#define MAX_DRAIN_BYTES 32
 
3466
  // INKqa11524: If the user is malicious and keeps sending us data,
 
3467
  // we'll go into an infinite spin here.  Fix is to only drain up
 
3468
  // to 32 bytes to allow for funny browser behavior but to also
 
3469
  // prevent reading forever.
 
3470
  int drain_bytes = 0;
 
3471
  if (fcntl(whc->si.fd, F_SETFL, O_NONBLOCK) >= 0) {
 
3472
    char ch;
 
3473
    while ((read(whc->si.fd, &ch, 1) > 0) && (drain_bytes < MAX_DRAIN_BYTES)) {
 
3474
      drain_bytes++;
 
3475
    }
 
3476
  }
 
3477
#else
 
3478
  {
 
3479
    unsigned long i;
 
3480
    if (ioctlsocket(whc->si.fd, FIONREAD, &i) != SOCKET_ERROR) {
 
3481
      if (i) {
 
3482
        char *buf = (char *) alloca(i * sizeof(char));
 
3483
        read_socket(whc->si.fd, buf, i);
 
3484
      }
 
3485
    }
 
3486
  }
 
3487
#endif
 
3488
 
 
3489
  return WEB_HTTP_ERR_OKAY;
 
3490
 
 
3491
}
 
3492
 
 
3493
//-------------------------------------------------------------------------
 
3494
// write_response
 
3495
//-------------------------------------------------------------------------
 
3496
 
 
3497
int
 
3498
write_response(WebHttpContext * whc)
 
3499
{
 
3500
  char *buf_p;
 
3501
  int bytes_to_write;
 
3502
  int bytes_written;
 
3503
  // Make sure that we have a content length
 
3504
  if (whc->response_hdr->getLength() < 0) {
 
3505
    whc->response_hdr->setLength(whc->response_bdy->spaceUsed());
 
3506
  }
 
3507
  whc->response_hdr->writeHdr(whc->si);
 
3508
  if (whc->request->getMethod() != METHOD_HEAD) {
 
3509
    buf_p = whc->response_bdy->bufPtr();
 
3510
    bytes_to_write = whc->response_bdy->spaceUsed();
 
3511
    bytes_written = 0;
 
3512
    while (bytes_to_write) {
 
3513
      bytes_written = socket_write(whc->si, buf_p, bytes_to_write);
 
3514
      if (bytes_written < 0) {
 
3515
        if (errno == EINTR || errno == EAGAIN)
 
3516
          continue;
 
3517
        else
 
3518
          return WEB_HTTP_ERR_FAIL;
 
3519
      } else {
 
3520
        bytes_to_write -= bytes_written;
 
3521
        buf_p += bytes_written;
 
3522
      }
 
3523
    }
 
3524
  }
 
3525
  return WEB_HTTP_ERR_OKAY;
 
3526
}
 
3527
 
 
3528
//-------------------------------------------------------------------------
 
3529
// process_query
 
3530
//-------------------------------------------------------------------------
 
3531
 
 
3532
int
 
3533
process_query(WebHttpContext * whc)
 
3534
{
 
3535
  int err;
 
3536
  InkHashTable *ht;
 
3537
  char *value;
 
3538
  // processFormSubmission will substituteUnsafeChars()
 
3539
  if ((ht = processFormSubmission((char *) (whc->request->getQuery()))) != NULL) {
 
3540
    whc->query_data_ht = ht;
 
3541
    // extract some basic info for easier access later
 
3542
    if (ink_hash_table_lookup(ht, "mode", (void **) &value)) {
 
3543
      if (strcmp(value, "1") == 0)
 
3544
        whc->request_state |= WEB_HTTP_STATE_CONFIGURE;
 
3545
    }
 
3546
    if (ink_hash_table_lookup(ht, "detail", (void **) &value)) {
 
3547
      if (strcmp(value, "more") == 0)
 
3548
        whc->request_state |= WEB_HTTP_STATE_MORE_DETAIL;
 
3549
    }
 
3550
    err = WEB_HTTP_ERR_OKAY;
 
3551
  } else {
 
3552
    err = WEB_HTTP_ERR_FAIL;
 
3553
  }
 
3554
  return err;
 
3555
}
 
3556
 
 
3557
//-------------------------------------------------------------------------
 
3558
// process_post
 
3559
//-------------------------------------------------------------------------
 
3560
 
 
3561
int
 
3562
process_post(WebHttpContext * whc)
 
3563
{
 
3564
  int err;
 
3565
  InkHashTable *ht;
 
3566
  // processFormSubmission will substituteUnsafeChars()
 
3567
  if ((ht = processFormSubmission(whc->request->getBody())) != NULL) {
 
3568
    whc->post_data_ht = ht;
 
3569
    err = WEB_HTTP_ERR_OKAY;
 
3570
  } else {
 
3571
    err = WEB_HTTP_ERR_FAIL;
 
3572
  }
 
3573
  return err;
 
3574
}
 
3575
 
 
3576
//-------------------------------------------------------------------------
 
3577
// signal_handler_init
 
3578
//-------------------------------------------------------------------------
 
3579
 
 
3580
void
 
3581
signal_handler_do_nothing(int x)
 
3582
{
 
3583
  //  A small function thats whole purpose is to give the signal
 
3584
  //  handler for breaking out of a network read, somethng to call
 
3585
  x = x;
 
3586
}
 
3587
 
 
3588
int
 
3589
signal_handler_init()
 
3590
{
 
3591
  // Setup signal handling.  We want to able to unstick stuck socket
 
3592
  // connections.  This is accomplished by a watcher thread doing a
 
3593
  // half close on the incoming socket after a timeout.  To break, out
 
3594
  // the current read which is likely stuck we have a signal handler
 
3595
  // on SIGUSR1 which does nothing except by side effect of break the
 
3596
  // read.  All future reads from the socket should fail since
 
3597
  // incoming traffic is shutdown on the connection and thread should
 
3598
  // exit normally
 
3599
#if !defined(_WIN32)
 
3600
  sigset_t sigsToBlock;
 
3601
  // FreeBSD and Linux use SIGUSR1 internally in the threads library
 
3602
#if !defined(linux) && !defined(freebsd) && !defined(darwin)
 
3603
  // Set up the handler for SIGUSR1
 
3604
  struct sigaction sigHandler;
 
3605
  sigHandler.sa_handler = signal_handler_do_nothing;
 
3606
  sigemptyset(&sigHandler.sa_mask);
 
3607
  sigHandler.sa_flags = 0;
 
3608
  sigaction(SIGUSR1, &sigHandler, NULL);
 
3609
#endif
 
3610
  // Block all other signals
 
3611
  sigfillset(&sigsToBlock);
 
3612
  sigdelset(&sigsToBlock, SIGUSR1);
 
3613
  ink_thread_sigsetmask(SIG_SETMASK, &sigsToBlock, NULL);
 
3614
#endif // !_WIN32
 
3615
  return WEB_HTTP_ERR_OKAY;
 
3616
}
 
3617
 
 
3618
//-------------------------------------------------------------------------
 
3619
// ssl_init
 
3620
//-------------------------------------------------------------------------
 
3621
 
 
3622
int
 
3623
ssl_init(WebHttpContext * whc)
 
3624
{
 
3625
  SSL *SSL_con = NULL;
 
3626
  unsigned int sslErrno;
 
3627
  char ssl_Error[256];
 
3628
  SSL_con = SSL_new(whc->ssl_ctx);
 
3629
  SSL_set_fd(SSL_con, whc->si.fd);
 
3630
  if (SSL_accept(SSL_con) < 0) {
 
3631
    sslErrno = ERR_get_error();
 
3632
    ERR_error_string(sslErrno, ssl_Error);
 
3633
    mgmt_log(stderr, "[ssl_init] SSL_accept failed: %s", ssl_Error);
 
3634
    return WEB_HTTP_ERR_FAIL;
 
3635
  }
 
3636
  whc->si.SSLcon = SSL_con;
 
3637
 
 
3638
  return WEB_HTTP_ERR_OKAY;
 
3639
}
 
3640
 
 
3641
//-------------------------------------------------------------------------
 
3642
// ssl_free
 
3643
//-------------------------------------------------------------------------
 
3644
 
 
3645
int
 
3646
ssl_free(WebHttpContext * whc)
 
3647
{
 
3648
  if (whc->si.SSLcon != NULL) {
 
3649
    SSL_free((SSL *) whc->si.SSLcon);
 
3650
  }
 
3651
 
 
3652
  return WEB_HTTP_ERR_OKAY;
 
3653
}
 
3654
 
 
3655
//-------------------------------------------------------------------------
 
3656
// WebHttpInit
 
3657
//-------------------------------------------------------------------------
 
3658
 
 
3659
void
 
3660
WebHttpInit()
 
3661
{
 
3662
 
 
3663
  static int initialized = 0;
 
3664
 
 
3665
  if (initialized != 0) {
 
3666
    mgmt_log(stderr, "[WebHttpInit] error, initialized twice (%d)", initialized);
 
3667
  }
 
3668
  initialized++;
 
3669
 
 
3670
  // initialize autoconf allow files
 
3671
  g_autoconf_allow_ht = ink_hash_table_create(InkHashTableKeyType_String);
 
3672
  ink_hash_table_insert(g_autoconf_allow_ht, "/proxy.pac", NULL);
 
3673
  ink_hash_table_insert(g_autoconf_allow_ht, "/wpad.dat", NULL);
 
3674
  ink_hash_table_insert(g_autoconf_allow_ht, "/public_key.der", NULL);
 
3675
  ink_hash_table_insert(g_autoconf_allow_ht, "/synthetic.txt", NULL);
 
3676
 
 
3677
  // initialize submit bindings
 
3678
  g_submit_bindings_ht = ink_hash_table_create(InkHashTableKeyType_String);
 
3679
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_ALARM_FILE, (void *) handle_submit_alarm);
 
3680
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_MGMT_AUTH_FILE, (void *) handle_submit_mgmt_auth);
 
3681
  //ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FILE, handle_submit_snapshot);
 
3682
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FILESYSTEM,
 
3683
                        (void *) handle_submit_snapshot_to_filesystem);
 
3684
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FTPSERVER,
 
3685
                        (void *) handle_submit_snapshot_to_ftpserver);
 
3686
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_SNAPSHOT_FLOPPY, (void *) handle_submit_snapshot_to_floppy);
 
3687
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_INSPECTOR_FILE, (void *) handle_submit_inspector);
 
3688
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_INSPECTOR_DPY_FILE, (void *) handle_submit_inspector_display);
 
3689
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_VIEW_LOGS_FILE, (void *) handle_submit_view_logs);
 
3690
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_UPDATE_FILE, (void *) handle_submit_update);
 
3691
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_UPDATE_CONFIG, (void *) handle_submit_update_config);
 
3692
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_CONFIG_DISPLAY, (void *) handle_submit_config_display);
 
3693
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_NET_CONFIG, (void *) handle_submit_net_config);
 
3694
  ink_hash_table_insert(g_submit_bindings_ht, HTML_SUBMIT_OTW_UPGRADE_FILE, (void *) handle_submit_otw_upgrade);
 
3695
  // initialize file bindings
 
3696
  g_file_bindings_ht = ink_hash_table_create(InkHashTableKeyType_String);
 
3697
  ink_hash_table_insert(g_file_bindings_ht, HTML_CHART_FILE, (void *) handle_chart);
 
3698
  ink_hash_table_insert(g_file_bindings_ht, HTML_BACKDOOR_CONFIG_FILES, (void *) handle_config_files);
 
3699
  ink_hash_table_insert(g_file_bindings_ht, HTML_BACKDOOR_DEBUG_LOGS, (void *) handle_debug_logs);
 
3700
  ink_hash_table_insert(g_file_bindings_ht, HTML_SYNTHETIC_FILE, (void *) handle_synthetic);
 
3701
 
 
3702
  // initialize extension bindings
 
3703
  g_extn_bindings_ht = ink_hash_table_create(InkHashTableKeyType_String);
 
3704
  ink_hash_table_insert(g_extn_bindings_ht, ".cgi", (void *) handle_cgi_extn);
 
3705
  ink_hash_table_insert(g_extn_bindings_ht, ".ink", (void *) handle_ink_extn);
 
3706
 
 
3707
  // initialize the configurator editing bindings which binds
 
3708
  // configurator display filename (eg. f_cache_config.ink) to
 
3709
  // its mgmt API config file type (INKFileNameT)
 
3710
  g_display_config_ht = ink_hash_table_create(InkHashTableKeyType_String);
 
3711
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_CACHE_CONFIG, (void *) INK_FNAME_CACHE_OBJ);
 
3712
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_HOSTING_CONFIG, (void *) INK_FNAME_HOSTING);
 
3713
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_ICP_CONFIG, (void *) INK_FNAME_ICP_PEER);
 
3714
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_IP_ALLOW_CONFIG, (void *) INK_FNAME_IP_ALLOW);
 
3715
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_MGMT_ALLOW_CONFIG, (void *) INK_FNAME_MGMT_ALLOW);
 
3716
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_PARENT_CONFIG, (void *) INK_FNAME_PARENT_PROXY);
 
3717
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_PARTITION_CONFIG, (void *) INK_FNAME_PARTITION);
 
3718
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_REMAP_CONFIG, (void *) INK_FNAME_REMAP);
 
3719
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_SOCKS_CONFIG, (void *) INK_FNAME_SOCKS);
 
3720
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_SPLIT_DNS_CONFIG, (void *) INK_FNAME_SPLIT_DNS);
 
3721
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_UPDATE_CONFIG, (void *) INK_FNAME_UPDATE_URL);
 
3722
  ink_hash_table_insert(g_display_config_ht, HTML_FILE_VADDRS_CONFIG, (void *) INK_FNAME_VADDRS);
 
3723
 
 
3724
  // initialize other modules
 
3725
  WebHttpAuthInit();
 
3726
  WebHttpLogInit();
 
3727
  WebHttpSessionInit();
 
3728
#ifndef NO_WEBUI
 
3729
  WebHttpRenderInit();
 
3730
  WebHttpTreeInit();
 
3731
#endif
 
3732
 
 
3733
  return;
 
3734
}
 
3735
 
 
3736
//-------------------------------------------------------------------------
 
3737
// WebHttpHandleConnection
 
3738
//
 
3739
// Handles http requests across the web management port
 
3740
//-------------------------------------------------------------------------
 
3741
 
 
3742
void
 
3743
WebHttpHandleConnection(WebHttpConInfo * whci)
 
3744
{
 
3745
 
 
3746
  int err = WEB_HTTP_ERR_OKAY;
 
3747
 
 
3748
  WebHttpContext *whc;
 
3749
  WebHttpHandler handler;
 
3750
  char *file;
 
3751
  char *extn;
 
3752
  int drain_bytes;
 
3753
  char ch;
 
3754
 
 
3755
  // initialization
 
3756
  if ((whc = WebHttpContextCreate(whci)) == NULL)
 
3757
    goto Ltransaction_close;
 
3758
  if (signal_handler_init() != WEB_HTTP_ERR_OKAY)
 
3759
    goto Ltransaction_close;
 
3760
  if (whc->server_state & WEB_HTTP_SERVER_STATE_SSL_ENABLED)
 
3761
    if (ssl_init(whc) != WEB_HTTP_ERR_OKAY)
 
3762
      goto Ltransaction_close;
 
3763
 
 
3764
  // read request
 
3765
  if ((err = read_request(whc)) != WEB_HTTP_ERR_OKAY)
 
3766
    goto Lerror_switch;
 
3767
 
 
3768
  // authentication
 
3769
  if (whc->server_state & WEB_HTTP_SERVER_STATE_AUTH_ENABLED)
 
3770
    if (WebHttpAuthenticate(whc) != WEB_HTTP_ERR_OKAY)
 
3771
      goto Ltransaction_send;
 
3772
 
 
3773
  // get our file information
 
3774
  file = (char *) (whc->request->getFile());
 
3775
  if (strcmp("/", file) == 0) {
 
3776
    file = (char *) (whc->default_file);
 
3777
  }
 
3778
 
 
3779
  Debug("web2", "[WebHttpHandleConnection] request file: %s", file);
 
3780
 
 
3781
 
 
3782
  if (whc->server_state & WEB_HTTP_SERVER_STATE_AUTOCONF) {
 
3783
 
 
3784
    // security concern: special treatment if we're handling a request
 
3785
    // on the autoconf port.  can't have users downloading arbitrary
 
3786
    // files under the config directory!
 
3787
    if (!ink_hash_table_isbound(g_autoconf_allow_ht, file)) {
 
3788
      mgmt_elog(stderr,"[WebHttpHandleConnection] %s not valid autoconf file",file);
 
3789
      whc->response_hdr->setStatus(STATUS_NOT_FOUND);
 
3790
      WebHttpSetErrorResponse(whc, STATUS_NOT_FOUND);
 
3791
      goto Ltransaction_send;
 
3792
    }
 
3793
  } else {
 
3794
#ifndef NO_WEBUI
 
3795
    if (WebHttpTreeReturnRefresh(file)) {
 
3796
      // if we are handling a monitor/mrtg page, configure it to refresh
 
3797
      if (strncmp(file, "/monitor/", 9) == 0) {
 
3798
        whc->response_hdr->setRefresh(wGlobals.refreshRate);
 
3799
      } else if (strncmp(file, "/mrtg/", 6) == 0) {
 
3800
        whc->response_hdr->setRefresh(REFRESH_RATE_MRTG);
 
3801
      } else {                  // default
 
3802
        whc->response_hdr->setRefresh(wGlobals.refreshRate);
 
3803
      }
 
3804
    }
 
3805
#endif
 
3806
    // Make a note if we are a plugin.  Being a plugin will affect our
 
3807
    // doc_root and how request files and doc_roots are joined to
 
3808
    // generate an absolute path.  See WebHttpAddDocRoot_Xmalloc()
 
3809
    if (strncmp(file, "/plugins/", 9) == 0) {
 
3810
      whc->request_state |= WEB_HTTP_STATE_PLUGIN;
 
3811
    }
 
3812
 
 
3813
  }
 
3814
 
 
3815
  // process query
 
3816
  process_query(whc);
 
3817
 
 
3818
  // check submit_binding;
 
3819
  // if nothing, check file_binding;
 
3820
  // if nothing, check extn_binding;
 
3821
  // if still nothing, use the default handler;
 
3822
  if (ink_hash_table_lookup(g_submit_bindings_ht, file, (void **) &handler)) {
 
3823
    // workaround: sometimes we receive a GET for our submit cgi's
 
3824
    // (rather than a resubmitted POST).  In this case, just render
 
3825
    // the default page since we can't do much else
 
3826
    if (whc->request->getMethod() != METHOD_POST) {
 
3827
      if ((strcmp(file, HTML_SUBMIT_INSPECTOR_DPY_FILE) != 0) && (strcmp(file, HTML_SUBMIT_CONFIG_DISPLAY) != 0)) {
 
3828
        err = WebHttpRender(whc, HTML_DEFAULT_MONITOR_FILE);
 
3829
        goto Lerror_switch;
 
3830
      }
 
3831
    }
 
3832
    // process post
 
3833
    process_post(whc);
 
3834
    // only allow one submission at a time
 
3835
    ink_mutex_acquire(&wGlobals.submitLock);
 
3836
    err = handler(whc, file);
 
3837
    ink_mutex_release(&wGlobals.submitLock);
 
3838
  } else {
 
3839
    if (!ink_hash_table_lookup(g_file_bindings_ht, file, (void **) &handler)) {
 
3840
      extn = file;
 
3841
      while (*extn != '\0')
 
3842
        extn++;
 
3843
      while ((extn > file) && (*extn != '.'))
 
3844
        extn--;
 
3845
      if (!ink_hash_table_lookup(g_extn_bindings_ht, extn, (void **) &handler)) {
 
3846
        handler = handle_default;
 
3847
      }
 
3848
    }
 
3849
    err = handler(whc, file);
 
3850
  }
 
3851
 
 
3852
Lerror_switch:
 
3853
 
 
3854
  switch (err) {
 
3855
  case WEB_HTTP_ERR_OKAY:
 
3856
  case WEB_HTTP_ERR_REQUEST_ERROR:
 
3857
    goto Ltransaction_send;
 
3858
  case WEB_HTTP_ERR_FAIL:
 
3859
  case WEB_HTTP_ERR_REQUEST_FATAL:
 
3860
  default:
 
3861
    goto Ltransaction_close;
 
3862
  }
 
3863
 
 
3864
Ltransaction_send:
 
3865
 
 
3866
  // write response
 
3867
  if ((err = write_response(whc)) != WEB_HTTP_ERR_OKAY)
 
3868
    goto Ltransaction_close;
 
3869
 
 
3870
  // close the connection before logging it to reduce latency
 
3871
#ifndef _WIN32
 
3872
  shutdown(whc->si.fd, 1);
 
3873
  drain_bytes = 0;
 
3874
  if (fcntl(whc->si.fd, F_SETFL, O_NONBLOCK) >= 0) {
 
3875
    while ((read(whc->si.fd, &ch, 1) > 0) && (drain_bytes < MAX_DRAIN_BYTES)) {
 
3876
      drain_bytes++;
 
3877
    }
 
3878
  }
 
3879
#endif
 
3880
  close_socket(whc->si.fd);
 
3881
  whc->si.fd = -1;
 
3882
 
 
3883
  // log transaction
 
3884
  if (wGlobals.logFD >= 0)
 
3885
    WebHttpLogTransaction(whc);
 
3886
 
 
3887
Ltransaction_close:
 
3888
 
 
3889
  // if we didn't close already, close connection
 
3890
  if (whc->si.fd != -1) {
 
3891
#ifndef _WIN32
 
3892
    shutdown(whc->si.fd, 1);
 
3893
    drain_bytes = 0;
 
3894
    if (fcntl(whc->si.fd, F_SETFL, O_NONBLOCK) >= 0) {
 
3895
      while ((read(whc->si.fd, &ch, 1) > 0) && (drain_bytes < MAX_DRAIN_BYTES)) {
 
3896
        drain_bytes++;
 
3897
      }
 
3898
    }
 
3899
#endif
 
3900
    close_socket(whc->si.fd);
 
3901
  }
 
3902
  // clean up ssl
 
3903
  if (whc->server_state & WEB_HTTP_SERVER_STATE_SSL_ENABLED)
 
3904
    ssl_free(whc);
 
3905
 
 
3906
  // clean up memory
 
3907
  WebHttpContextDestroy(whc);
 
3908
 
 
3909
  return;
 
3910
 
 
3911
}
 
3912
 
 
3913
//-------------------------------------------------------------------------
 
3914
// WebHttpSetErrorResponse
 
3915
//
 
3916
// Formulates a page to return on an HttpStatus condition
 
3917
//-------------------------------------------------------------------------
 
3918
 
 
3919
void
 
3920
WebHttpSetErrorResponse(WebHttpContext * whc, HttpStatus_t error)
 
3921
{
 
3922
 
 
3923
  //-----------------------------------------------------------------------
 
3924
  // FIXME: HARD-CODED HTML HELL!!!
 
3925
  //-----------------------------------------------------------------------
 
3926
 
 
3927
  static const char a[] = "<HTML>\n<Head>\n<TITLE>";
 
3928
  static const char b[] = "</TITLE>\n</HEAD>\n<BODY bgcolor=\"#FFFFFF\"><h1>\n";
 
3929
  static const char c[] = "</h1>\n</BODY>\n</HTML>\n";
 
3930
  int errorMsgLen = strlen(httpStatStr[error]);
 
3931
 
 
3932
  // reset the buffer
 
3933
  whc->response_bdy->reUse();
 
3934
 
 
3935
  // fill in the buffer
 
3936
  whc->response_bdy->copyFrom(a, strlen(a));
 
3937
  whc->response_bdy->copyFrom(httpStatStr[error], errorMsgLen);
 
3938
  whc->response_bdy->copyFrom(b, strlen(b));
 
3939
  whc->response_bdy->copyFrom(httpStatStr[error], errorMsgLen);
 
3940
  whc->response_bdy->copyFrom(c, strlen(c));
 
3941
 
 
3942
}
 
3943
 
 
3944
//-------------------------------------------------------------------------
 
3945
// WebHttpAddDocRoot_Xmalloc
 
3946
//-------------------------------------------------------------------------
 
3947
 
 
3948
char *
 
3949
WebHttpAddDocRoot_Xmalloc(WebHttpContext * whc, const char *file)
 
3950
{
 
3951
 
 
3952
  int file_len = 0;
 
3953
  char *doc_root_file;
 
3954
  bool is_plugin;
 
3955
 
 
3956
  is_plugin = whc->request_state & WEB_HTTP_STATE_PLUGIN;
 
3957
 
 
3958
  file_len = strlen(file);
 
3959
  file_len += is_plugin ? strlen(whc->plugin_doc_root) : strlen(whc->doc_root);
 
3960
  doc_root_file = (char *) xmalloc(file_len + 1);
 
3961
 
 
3962
  if (is_plugin) {
 
3963
    ink_strncpy(doc_root_file, whc->plugin_doc_root, file_len);
 
3964
    strncat(doc_root_file, file + strlen("/plugins"), file_len - strlen(doc_root_file));
 
3965
  } else {
 
3966
    ink_strncpy(doc_root_file, whc->doc_root, file_len);
 
3967
    strncat(doc_root_file, file, file_len - strlen(doc_root_file));
 
3968
  }
 
3969
 
 
3970
  return doc_root_file;
 
3971
 
 
3972
}