671fe94d053be72ad4aa7996cb0b4a7a23e938ff
[racktables] / wwwroot / inc / ophandlers.php
1 <?php
2 /*
3 *
4 * This file is a library of operation handlers for RackTables.
5 *
6 */
7
8 // This array is deprecated. Please do not add new message constants to it.
9 // use the new showError, showWarning, showSuccess functions instead
10 global $msgcode;
11 $msgcode = array();
12
13 global $opspec_list;
14 $opspec_list = array();
15
16 $opspec_list['rackspace-edit-addRow'] = array
17 (
18 'table' => 'RackRow',
19 'action' => 'INSERT',
20 'arglist' => array
21 (
22 array ('url_argname' => 'name', 'assertion' => 'string')
23 ),
24 );
25 $opspec_list['rackspace-edit-delete'] = array
26 (
27 'table' => 'RackRow',
28 'action' => 'DELETE',
29 'arglist' => array
30 (
31 array ('url_argname' => 'row_id', 'table_colname' => 'id', 'assertion' => 'uint')
32 ),
33 );
34 $opspec_list['rackspace-edit-updateRow'] = array
35 (
36 'table' => 'RackRow',
37 'action' => 'UPDATE',
38 'set_arglist' => array
39 (
40 array ('url_argname' => 'name', 'assertion' => 'string')
41 ),
42 'where_arglist' => array
43 (
44 array ('url_argname' => 'row_id', 'table_colname' => 'id', 'assertion' => 'uint')
45 ),
46 );
47 $opspec_list['object-ports-delPort'] = array
48 (
49 'table' => 'Port',
50 'action' => 'DELETE',
51 'arglist' => array
52 (
53 array ('url_argname' => 'port_id', 'table_colname' => 'id', 'assertion' => 'uint'),
54 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
55 ),
56 );
57 $opspec_list['object-ports-deleteAll'] = array
58 (
59 'table' => 'Port',
60 'action' => 'DELETE',
61 'arglist' => array
62 (
63 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
64 ),
65 );
66 $opspec_list['object-ports-unlinkPort'] = array
67 (
68 'table' => 'Link',
69 'action' => 'DELETE',
70 'arglist' => array
71 (
72 array ('url_argname' => 'port_id', 'table_colname' => 'porta', 'assertion' => 'uint'),
73 array ('url_argname' => 'port_id', 'table_colname' => 'portb', 'assertion' => 'uint'),
74 ),
75 'conjunction' => 'OR',
76 );
77 $opspec_list['object-log-del'] = array
78 (
79 'table' => 'ObjectLog',
80 'action' => 'DELETE',
81 'arglist' => array
82 (
83 array ('url_argname' => 'logid', 'table_colname' => 'id', 'assertion' => 'uint'),
84 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
85 ),
86 );
87 $opspec_list['ipv4vs-editlblist-delLB'] =
88 $opspec_list['ipv4rspool-editlblist-delLB'] =
89 $opspec_list['object-editrspvs-delLB'] = array
90 (
91 'table' => 'IPv4LB',
92 'action' => 'DELETE',
93 'arglist' => array
94 (
95 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
96 array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
97 array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
98 ),
99 );
100 $opspec_list['ipv4vs-editlblist-updLB'] =
101 $opspec_list['ipv4rspool-editlblist-updLB'] =
102 $opspec_list['object-editrspvs-updLB'] = array
103 (
104 'table' => 'IPv4LB',
105 'action' => 'UPDATE',
106 'set_arglist' => array
107 (
108 array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
109 array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
110 array ('url_argname' => 'prio', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
111 ),
112 'where_arglist' => array
113 (
114 array ('url_argname' => 'object_id', 'assertion' => 'uint'),
115 array ('url_argname' => 'pool_id', 'table_colname' => 'rspool_id', 'assertion' => 'uint'),
116 array ('url_argname' => 'vs_id', 'assertion' => 'uint'),
117 ),
118 );
119 $opspec_list['ipv4net-properties-editRange'] = array
120 (
121 'table' => 'IPv4Network',
122 'action' => 'UPDATE',
123 'set_arglist' => array
124 (
125 array ('url_argname' => 'name', 'assertion' => 'string0'),
126 array ('url_argname' => 'comment', 'assertion' => 'string0'),
127 ),
128 'where_arglist' => array
129 (
130 array ('url_argname' => 'id', 'assertion' => 'uint')
131 ),
132 );
133 $opspec_list['ipv6net-properties-editRange'] = array
134 (
135 'table' => 'IPv6Network',
136 'action' => 'UPDATE',
137 'set_arglist' => array
138 (
139 array ('url_argname' => 'name', 'assertion' => 'string0'),
140 array ('url_argname' => 'comment', 'assertion' => 'string0'),
141 ),
142 'where_arglist' => array
143 (
144 array ('url_argname' => 'id', 'assertion' => 'uint')
145 ),
146 );
147 $opspec_list['ipv4rspool-editrslist-delRS'] = array
148 (
149 'table' => 'IPv4RS',
150 'action' => 'DELETE',
151 'arglist' => array
152 (
153 array ('url_argname' => 'id', 'assertion' => 'uint'),
154 ),
155 );
156 $opspec_list['ipv4rspool-edit-updIPv4RSP'] = array
157 (
158 'table' => 'IPv4RSPool',
159 'action' => 'UPDATE',
160 'set_arglist' => array
161 (
162 array ('url_argname' => 'name', 'assertion' => 'string0', 'if_empty' => 'NULL'),
163 array ('url_argname' => 'vsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
164 array ('url_argname' => 'rsconfig', 'assertion' => 'string0', 'if_empty' => 'NULL'),
165 ),
166 'where_arglist' => array
167 (
168 array ('url_argname' => 'pool_id', 'table_colname' => 'id', 'assertion' => 'uint')
169 ),
170 );
171 $opspec_list['file-edit-updateFile'] = array
172 (
173 'table' => 'File',
174 'action' => 'UPDATE',
175 'set_arglist' => array
176 (
177 array ('url_argname' => 'file_name', 'table_colname' => 'name', 'assertion' => 'string'),
178 array ('url_argname' => 'file_type', 'table_colname' => 'type', 'assertion' => 'string'),
179 array ('url_argname' => 'file_comment', 'table_colname' => 'comment', 'assertion' => 'string0', 'if_empty' => 'NULL'),
180 ),
181 'where_arglist' => array
182 (
183 array ('url_argname' => 'file_id', 'table_colname' => 'id', 'assertion' => 'uint')
184 ),
185 );
186 $opspec_list['parentmap-edit-add'] = array
187 (
188 'table' => 'ObjectParentCompat',
189 'action' => 'INSERT',
190 'arglist' => array
191 (
192 array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
193 array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
194 ),
195 );
196 $opspec_list['parentmap-edit-del'] = array
197 (
198 'table' => 'ObjectParentCompat',
199 'action' => 'DELETE',
200 'arglist' => array
201 (
202 array ('url_argname' => 'parent_objtype_id', 'assertion' => 'uint'),
203 array ('url_argname' => 'child_objtype_id', 'assertion' => 'uint'),
204 ),
205 );
206 $opspec_list['portmap-edit-add'] = array
207 (
208 'table' => 'PortCompat',
209 'action' => 'INSERT',
210 'arglist' => array
211 (
212 array ('url_argname' => 'type1', 'assertion' => 'uint'),
213 array ('url_argname' => 'type2', 'assertion' => 'uint'),
214 ),
215 );
216 $opspec_list['portmap-edit-del'] = array
217 (
218 'table' => 'PortCompat',
219 'action' => 'DELETE',
220 'arglist' => array
221 (
222 array ('url_argname' => 'type1', 'assertion' => 'uint'),
223 array ('url_argname' => 'type2', 'assertion' => 'uint'),
224 ),
225 );
226 $opspec_list['portifcompat-edit-del'] = array
227 (
228 'table' => 'PortInterfaceCompat',
229 'action' => 'DELETE',
230 'arglist' => array
231 (
232 array ('url_argname' => 'iif_id', 'assertion' => 'uint'),
233 array ('url_argname' => 'oif_id', 'assertion' => 'uint'),
234 ),
235 );
236 $opspec_list['attrs-editmap-del'] = array
237 (
238 'table' => 'AttributeMap',
239 'action' => 'DELETE',
240 'arglist' => array
241 (
242 array ('url_argname' => 'attr_id', 'assertion' => 'uint'),
243 array ('url_argname' => 'objtype_id', 'assertion' => 'uint'),
244 ),
245 );
246 $opspec_list['attrs-editattrs-add'] = array
247 (
248 'table' => 'Attribute',
249 'action' => 'INSERT',
250 'arglist' => array
251 (
252 array ('url_argname' => 'attr_type', 'table_colname' => 'type', 'assertion' => 'enum/attr_type'),
253 array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
254 ),
255 );
256 $opspec_list['attrs-editattrs-del'] = array
257 (
258 'table' => 'Attribute',
259 'action' => 'DELETE',
260 'arglist' => array
261 (
262 array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
263 ),
264 );
265 $opspec_list['attrs-editattrs-upd'] = array
266 (
267 'table' => 'Attribute',
268 'action' => 'UPDATE',
269 'set_arglist' => array
270 (
271 array ('url_argname' => 'attr_name', 'table_colname' => 'name', 'assertion' => 'string'),
272 ),
273 'where_arglist' => array
274 (
275 array ('url_argname' => 'attr_id', 'table_colname' => 'id', 'assertion' => 'uint'),
276 ),
277 );
278 $opspec_list['dict-chapters-add'] = array
279 (
280 'table' => 'Chapter',
281 'action' => 'INSERT',
282 'arglist' => array
283 (
284 array ('url_argname' => 'chapter_name', 'table_colname' => 'name', 'assertion' => 'string')
285 ),
286 );
287 $opspec_list['chapter-edit-add'] = array
288 (
289 'table' => 'Dictionary',
290 'action' => 'INSERT',
291 'arglist' => array
292 (
293 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
294 array ('url_argname' => 'dict_value', 'assertion' => 'string'),
295 ),
296 );
297 $opspec_list['chapter-edit-del'] = array
298 (
299 'table' => 'Dictionary',
300 'action' => 'DELETE',
301 'arglist' => array
302 (
303 // Technically dict_key is enough to delete, but including chapter_id into
304 // WHERE clause makes sure, that the action actually happends for the same
305 // chapter, which authorization was granted for.
306 array ('url_argname' => 'chapter_no', 'table_colname' => 'chapter_id', 'assertion' => 'uint'),
307 array ('url_argname' => 'dict_key', 'assertion' => 'uint'),
308 ),
309 );
310 $opspec_list['tagtree-edit-createTag'] = array
311 (
312 'table' => 'TagTree',
313 'action' => 'INSERT',
314 'arglist' => array
315 (
316 array ('url_argname' => 'tag_name', 'table_colname' => 'tag', 'assertion' => 'tag'),
317 array ('url_argname' => 'parent_id', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
318 ),
319 );
320 $opspec_list['tagtree-edit-destroyTag'] = array
321 (
322 'table' => 'TagTree',
323 'action' => 'DELETE',
324 'arglist' => array
325 (
326 array ('url_argname' => 'tag_id', 'table_colname' => 'id', 'assertion' => 'uint'),
327 ),
328 );
329 $opspec_list['tagtree-edit-updateTag'] = array
330 (
331 'table' => 'TagTree',
332 'action' => 'UPDATE',
333 'set_arglist' => array
334 (
335 array ('url_argname' => 'tag_name', 'table_colname' => 'tag', 'assertion' => 'tag'),
336 array ('url_argname' => 'parent_id', 'assertion' => 'uint0', 'if_empty' => 'NULL'),
337 ),
338 'where_arglist' => array
339 (
340 array ('url_argname' => 'tag_id', 'table_colname' => 'id', 'assertion' => 'uint'),
341 ),
342 );
343 $opspec_list['8021q-vstlist-upd'] = array
344 (
345 'table' => 'VLANSwitchTemplate',
346 'action' => 'UPDATE',
347 'set_arglist' => array
348 (
349 array ('url_argname' => 'vst_descr', 'table_colname' => 'description', 'assertion' => 'string'),
350 ),
351 'where_arglist' => array
352 (
353 array ('url_argname' => 'vst_id', 'table_colname' => 'id', 'assertion' => 'uint'),
354 ),
355 );
356 $opspec_list['8021q-vdlist-upd'] = array
357 (
358 'table' => 'VLANDomain',
359 'action' => 'UPDATE',
360 'set_arglist' => array
361 (
362 array ('url_argname' => 'vdom_descr', 'table_colname' => 'description', 'assertion' => 'string'),
363 ),
364 'where_arglist' => array
365 (
366 array ('url_argname' => 'vdom_id', 'table_colname' => 'id', 'assertion' => 'uint'),
367 ),
368 );
369 $opspec_list['vlandomain-vlanlist-add'] = array
370 (
371 'table' => 'VLANDescription',
372 'action' => 'INSERT',
373 'arglist' => array
374 (
375 array ('url_argname' => 'vdom_id', 'table_colname' => 'domain_id', 'assertion' => 'uint'),
376 array ('url_argname' => 'vlan_id', 'assertion' => 'uint'),
377 array ('url_argname' => 'vlan_type', 'assertion' => 'enum/vlan_type'),
378 array ('url_argname' => 'vlan_descr', 'assertion' => 'string0', 'if_empty' => 'NULL'),
379 ),
380 );
381
382 // This function is DEPRECATED. Show messages through showError and showSuccess,
383 // you dont need to return anything from an ophandler to redirect user back to the page containing submit form
384 function buildWideRedirectURL ($log = NULL, $nextpage = NULL, $nexttab = NULL, $moreArgs = array())
385 {
386 global $page, $pageno, $tabno;
387 if ($nextpage === NULL)
388 $nextpage = $pageno;
389 if ($nexttab === NULL)
390 $nexttab = $tabno;
391 $url = "index.php?page=${nextpage}&tab=${nexttab}";
392 if (isset ($page[$nextpage]['bypass']))
393 $url .= '&' . $page[$nextpage]['bypass'] . '=' . $_REQUEST[$page[$nextpage]['bypass']];
394
395 if (count ($moreArgs) > 0)
396 foreach ($moreArgs as $arg => $value)
397 if (gettype ($value) != 'array')
398 $url .= '&' . urlencode ($arg) . '=' . urlencode ($value);
399 else
400 foreach ($value as $v)
401 $url .= '&' . urlencode ($arg . '[]') . '=' . urlencode ($v);
402
403 if (! empty ($log))
404 {
405 if (empty ($_SESSION['log']))
406 $_SESSION['log'] = $log;
407 elseif ($_SESSION['log']['v'] == $log['v'])
408 $_SESSION['log'] = array_merge_recursive($log, $_SESSION['log']);
409 elseif ($log['v'] == 1 and $_SESSION['log']['v'] == 2)
410 foreach ($log['m'] as $msg)
411 setMessage ($msg['code'], $msg['message'], FALSE);
412 elseif ($log['v'] == 2 and $_SESSION['log']['v'] == 1)
413 {
414 foreach ($_SESSION['log'] as $msg)
415 {
416 if (! is_array ($msg))
417 continue;
418 $new_v2_item = array('c' => '', 'a' => array());
419 switch ($msg['code'])
420 {
421 case 'error':
422 $new_v2_item['c'] = 100;
423 break;
424 case 'success':
425 $new_v2_item['c'] = 0;
426 break;
427 case 'warning':
428 $new_v2_item['c'] = 200;
429 break;
430 default:
431 $new_v2_item['c'] = 300;
432 }
433 $new_v2_item['a'][] = $msg['message'];
434 $log['m'][] = $new_v2_item;
435 }
436 $_SESSION['log'] = $log; // substitute v1 log structure with merged v2
437 }
438 }
439 return $url;
440 }
441
442 // This function is DEPRECATED. Show messages through showError and showSuccess,
443 // you dont need to return anything from an ophandler to redirect user back to the page containing submit form
444 function buildRedirectURL ($callfunc, $status, $log_args = array(), $nextpage = NULL, $nexttab = NULL, $url_args = array())
445 {
446 global $pageno, $tabno, $msgcode;
447 if ($nextpage === NULL)
448 $nextpage = $pageno;
449 if ($nexttab === NULL)
450 $nexttab = $tabno;
451 return buildWideRedirectURL (oneLiner ($msgcode[$callfunc][$status], $log_args), $nextpage, $nexttab, $url_args);
452 }
453
454 $msgcode['addPortForwarding']['OK'] = 48;
455 $msgcode['addPortForwarding']['ERR'] = 100;
456 function addPortForwarding ()
457 {
458 assertUIntArg ('object_id');
459 assertIPv4Arg ('localip');
460 assertIPv4Arg ('remoteip');
461 assertUIntArg ('localport');
462 assertStringArg ('proto');
463 assertStringArg ('description', TRUE);
464 $remoteport = isset ($_REQUEST['remoteport']) ? $_REQUEST['remoteport'] : '';
465 if (!strlen ($remoteport))
466 $remoteport = $_REQUEST['localport'];
467
468 $error = newPortForwarding
469 (
470 $_REQUEST['object_id'],
471 $_REQUEST['localip'],
472 $_REQUEST['localport'],
473 $_REQUEST['remoteip'],
474 $remoteport,
475 $_REQUEST['proto'],
476 $_REQUEST['description']
477 );
478
479 if ($error == '')
480 return buildRedirectURL (__FUNCTION__, 'OK');
481 else
482 return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
483 }
484
485 $msgcode['delPortForwarding']['OK'] = 49;
486 $msgcode['delPortForwarding']['ERR'] = 111;
487 function delPortForwarding ()
488 {
489 assertUIntArg ('object_id');
490 assertIPv4Arg ('localip');
491 assertIPv4Arg ('remoteip');
492 assertUIntArg ('localport');
493 assertUIntArg ('remoteport');
494 assertStringArg ('proto');
495
496 $result = deletePortForwarding
497 (
498 $_REQUEST['object_id'],
499 $_REQUEST['localip'],
500 $_REQUEST['localport'],
501 $_REQUEST['remoteip'],
502 $_REQUEST['remoteport'],
503 $_REQUEST['proto']
504 );
505 buildRedirectURL (__FUNCTION__, $result !== FALSE ? 'OK' : 'ERR');
506 }
507
508 $msgcode['updPortForwarding']['OK'] = 51;
509 $msgcode['updPortForwarding']['ERR'] = 109;
510 function updPortForwarding ()
511 {
512 assertUIntArg ('object_id');
513 assertIPv4Arg ('localip');
514 assertIPv4Arg ('remoteip');
515 assertUIntArg ('localport');
516 assertUIntArg ('remoteport');
517 assertStringArg ('proto');
518 assertStringArg ('description');
519
520 $result = updatePortForwarding
521 (
522 $_REQUEST['object_id'],
523 $_REQUEST['localip'],
524 $_REQUEST['localport'],
525 $_REQUEST['remoteip'],
526 $_REQUEST['remoteport'],
527 $_REQUEST['proto'],
528 $_REQUEST['description']
529 );
530 buildRedirectURL (__FUNCTION__, $result !== FALSE ? 'OK' : 'ERR');
531 }
532
533 $msgcode['addPortForObject']['OK'] = 48;
534 function addPortForObject ()
535 {
536 assertStringArg ('port_name', TRUE);
537 genericAssertion ('port_l2address', 'l2address0');
538 genericAssertion ('port_name', 'string');
539 commitAddPort
540 (
541 $_REQUEST['object_id'],
542 trim ($_REQUEST['port_name']),
543 $_REQUEST['port_type_id'],
544 trim ($_REQUEST['port_label']),
545 trim ($_REQUEST['port_l2address'])
546 );
547 return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['port_name']));
548 }
549
550 $msgcode['editPortForObject']['OK'] = 6;
551 function editPortForObject ()
552 {
553 global $sic;
554 assertUIntArg ('port_id');
555 assertUIntArg ('port_type_id');
556 assertStringArg ('reservation_comment', TRUE);
557 genericAssertion ('l2address', 'l2address0');
558 genericAssertion ('name', 'string');
559 commitUpdatePort ($sic['object_id'], $sic['port_id'], $sic['name'], $sic['port_type_id'], $sic['label'], $sic['l2address'], $sic['reservation_comment']);
560 return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['name']));
561 }
562
563 $msgcode['linkPortForObject']['OK'] = 8;
564 $msgcode['linkPortForObject']['ERR'] = 100;
565 function linkPortForObject ()
566 {
567 assertUIntArg ('port_id');
568 assertUIntArg ('remote_port_id');
569 assertStringArg ('cable', TRUE);
570
571 // FIXME: ensure, that at least one of these ports belongs to the current object
572 $error = linkPorts ($_REQUEST['port_id'], $_REQUEST['remote_port_id'], $_REQUEST['cable']);
573 if ($error != '')
574 return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
575 global $sic;
576 $local_port_info = getPortInfo ($sic['port_id']);
577 $remote_port_info = getPortInfo ($sic['remote_port_id']);
578 $remote_object = spotEntity ('object', $remote_port_info['object_id']);
579 return buildRedirectURL
580 (
581 __FUNCTION__,
582 'OK',
583 array
584 (
585 $local_port_info['name'],
586 $remote_port_info['name'],
587 $remote_object['dname'],
588 )
589 );
590 }
591
592 $msgcode['addMultiPorts']['OK'] = 10;
593 $msgcode['addMultiPorts']['ERR'] = 123;
594 function addMultiPorts ()
595 {
596 assertStringArg ('format');
597 assertStringArg ('input');
598 assertStringArg ('port_type');
599 $format = $_REQUEST['format'];
600 $port_type = $_REQUEST['port_type'];
601 $object_id = $_REQUEST['object_id'];
602 // Input lines are escaped, so we have to explode and to chop by 2-char
603 // \n and \r respectively.
604 $lines1 = explode ("\n", $_REQUEST['input']);
605 foreach ($lines1 as $line)
606 {
607 $parts = explode ('\r', $line);
608 reset ($parts);
609 if (!strlen ($parts[0]))
610 continue;
611 else
612 $lines2[] = rtrim ($parts[0]);
613 }
614 $ports = array();
615 foreach ($lines2 as $line)
616 {
617 switch ($format)
618 {
619 case 'fisxii':
620 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', $line));
621 list ($slot, $port) = explode ('/', $words[0]);
622 $ports[] = array
623 (
624 'name' => "e ${slot}/${port}",
625 'l2address' => $words[8],
626 'label' => "slot ${slot} port ${port}"
627 );
628 break;
629 case 'c3600asy':
630 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', trim (substr ($line, 3))));
631 /*
632 How Async Lines are Numbered in Cisco 3600 Series Routers
633 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00801ca70b.shtml
634
635 Understanding 16- and 32-Port Async Network Modules
636 http://www.cisco.com/en/US/products/hw/routers/ps274/products_tech_note09186a00800a93f0.shtml
637 */
638 $async = $words[0];
639 $slot = floor (($async - 1) / 32);
640 $octalgroup = floor (($async - 1 - $slot * 32) / 8);
641 $cable = $async - $slot * 32 - $octalgroup * 8;
642 $og_label[0] = 'async 0-7';
643 $og_label[1] = 'async 8-15';
644 $og_label[2] = 'async 16-23';
645 $og_label[3] = 'async 24-31';
646 $ports[] = array
647 (
648 'name' => "async ${async}",
649 'l2address' => '',
650 'label' => "slot ${slot} " . $og_label[$octalgroup] . " cable ${cable}"
651 );
652 break;
653 case 'fiwg':
654 $words = explode (' ', preg_replace ('/[[:space:]]+/', ' ', $line));
655 $ifnumber = $words[0] * 1;
656 $ports[] = array
657 (
658 'name' => "e ${ifnumber}",
659 'l2address' => "${words[8]}",
660 'label' => "${ifnumber}"
661 );
662 break;
663 case 'ssv1':
664 $words = explode (' ', $line);
665 if (!strlen ($words[0]) or !strlen ($words[1]))
666 continue;
667 $ports[] = array
668 (
669 'name' => $words[0],
670 'l2address' => $words[1],
671 'label' => ''
672 );
673 break;
674 default:
675 return buildRedirectURL (__FUNCTION__, 'ERR');
676 break;
677 }
678 }
679 // Create ports, if they don't exist.
680 $added_count = $updated_count = $error_count = 0;
681 foreach ($ports as $port)
682 {
683 $port_ids = getPortIDs ($object_id, $port['name']);
684 if (!count ($port_ids))
685 {
686 commitAddPort ($object_id, $port['name'], $port_type, $port['label'], $port['l2address']);
687 $added_count++;
688 }
689 elseif (count ($port_ids) == 1) // update only single-socket ports
690 {
691 commitUpdatePort ($object_id, $port_ids[0], $port['name'], $port_type, $port['label'], $port['l2address']);
692 $updated_count++;
693 }
694 }
695 return buildRedirectURL (__FUNCTION__, 'OK', array ($added_count, $updated_count, $error_count));
696 }
697
698 $msgcode['addBulkPorts']['OK'] = 82;
699 function addBulkPorts ()
700 {
701 assertStringArg ('port_type_id');
702 assertStringArg ('port_name');
703 assertStringArg ('port_label', TRUE);
704 assertUIntArg ('port_numbering_start', TRUE);
705 assertUIntArg ('port_numbering_count');
706
707 $object_id = $_REQUEST['object_id'];
708 $port_name = $_REQUEST['port_name'];
709 $port_type_id = $_REQUEST['port_type_id'];
710 $port_label = $_REQUEST['port_label'];
711 $port_numbering_start = $_REQUEST['port_numbering_start'];
712 $port_numbering_count = $_REQUEST['port_numbering_count'];
713
714 $added_count = $error_count = 0;
715 if(strrpos($port_name, "%u") === false )
716 $port_name .= '%u';
717 for ($i=0,$c=$port_numbering_start; $i<$port_numbering_count; $i++,$c++)
718 {
719 commitAddPort ($object_id, @sprintf($port_name,$c), $port_type_id, @sprintf($port_label,$c), '');
720 $added_count++;
721 }
722 return buildRedirectURL (__FUNCTION__, 'OK', array ($added_count, $error_count));
723 }
724
725 $msgcode['updIPv4Allocation']['OK'] = 51;
726 $msgcode['updIPv4Allocation']['ERR'] = 109;
727 function updIPv4Allocation ()
728 {
729 assertIPv4Arg ('ip');
730 assertUIntArg ('object_id');
731 assertStringArg ('bond_name', TRUE);
732 genericAssertion ('bond_type', 'enum/inet4alloc');
733
734 $result = updateBond ($_REQUEST['ip'], $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
735 return buildRedirectURL (__FUNCTION__, $result === FALSE ? 'ERR' : 'OK');
736 }
737
738 $msgcode['updIPv6Allocation']['OK'] = 51;
739 $msgcode['updIv6PAllocation']['ERR'] = 109;
740 function updIPv6Allocation ()
741 {
742 $ipv6 = assertIPv6Arg ('ip');
743 assertUIntArg ('object_id');
744 assertStringArg ('bond_name', TRUE);
745 genericAssertion ('bond_type', 'enum/inet6alloc');
746
747 $result = updateIPv6Bond ($ipv6, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']);
748 return buildRedirectURL (__FUNCTION__, $result === FALSE ? 'ERR' : 'OK');
749 }
750
751 $msgcode['delIPv4Allocation']['OK'] = 49;
752 $msgcode['delIPv4Allocation']['ERR'] = 111;
753 function delIPv4Allocation ()
754 {
755 assertIPv4Arg ('ip');
756 assertUIntArg ('object_id');
757
758 $result = unbindIpFromObject ($_REQUEST['ip'], $_REQUEST['object_id']);
759 return buildRedirectURL (__FUNCTION__, $result === FALSE ? 'ERR' : 'OK');
760 }
761
762 $msgcode['delIPv6Allocation']['OK'] = 49;
763 $msgcode['delIPv6Allocation']['ERR'] = 111;
764 function delIPv6Allocation ()
765 {
766 assertUIntArg ('object_id');
767 $ipv6 = assertIPv6Arg ('ip');
768 $result = unbindIPv6FromObject ($ipv6, $_REQUEST['object_id']);
769 return buildRedirectURL (__FUNCTION__, $result === FALSE ? 'ERR' : 'OK');
770 }
771
772 $msgcode['addIPv4Allocation']['OK'] = 48;
773 $msgcode['addIPv4Allocation']['ERR1'] = 170;
774 $msgcode['addIPv4Allocation']['ERR2'] = 100;
775 function addIPv4Allocation ()
776 {
777 assertIPv4Arg ('ip');
778 assertUIntArg ('object_id');
779 assertStringArg ('bond_name', TRUE);
780 genericAssertion ('bond_type', 'enum/inet4alloc');
781
782 // Strip masklen.
783 $ip = preg_replace ('@/[[:digit:]]+$@', '', $_REQUEST['ip']);
784 if (getConfigVar ('IPV4_JAYWALK') != 'yes' and NULL === getIPv4AddressNetworkId ($ip))
785 return buildRedirectURL (__FUNCTION__, 'ERR1', array ($ip));
786
787 if (FALSE === bindIpToObject ($ip, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']))
788 return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
789 $address = getIPv4Address ($ip);
790 if ($address['reserved'] == 'yes' or strlen ($address['name']))
791 {
792 $release = getConfigVar ('IPV4_AUTO_RELEASE');
793 if ($release >= 1)
794 $address['reserved'] = 'no';
795 if ($release >= 2)
796 $address['name'] = '';
797 updateAddress ($ip, $address['name'], $address['reserved']);
798 }
799 return buildRedirectURL (__FUNCTION__, 'OK');
800 }
801
802 $msgcode['addIPv6Allocation']['OK'] = 48;
803 $msgcode['addIPv6Allocation']['ERR1'] = 170;
804 $msgcode['addIPv6Allocation']['ERR2'] = 100;
805 function addIPv6Allocation ()
806 {
807 assertUIntArg ('object_id');
808 assertStringArg ('bond_name', TRUE);
809 genericAssertion ('bond_type', 'enum/inet6alloc');
810
811 // Strip masklen.
812 $ipv6 = new IPv6Address;
813 if (! $ipv6->parse (preg_replace ('@/\d+$@', '', $_REQUEST['ip'])))
814 throw new InvalidRequestArgException('ip', $_REQUEST['ip'], 'parameter is not a valid ipv6 address');
815
816 if (getConfigVar ('IPV4_JAYWALK') != 'yes' and NULL === getIPv6AddressNetworkId ($ipv6))
817 return buildRedirectURL (__FUNCTION__, 'ERR1', array ($ip));
818
819 if (FALSE === bindIPv6ToObject ($ipv6, $_REQUEST['object_id'], $_REQUEST['bond_name'], $_REQUEST['bond_type']))
820 return buildRedirectURL (__FUNCTION__, 'ERR2', array ($error));
821 $address = getIPv6Address ($ipv6);
822 if ($address['reserved'] == 'yes' or strlen ($address['name']))
823 {
824 $release = getConfigVar ('IPV4_AUTO_RELEASE');
825 if ($release >= 1)
826 $address['reserved'] = 'no';
827 if ($release >= 2)
828 $address['name'] = '';
829 updateAddress ($ipv6, $address['name'], $address['reserved']);
830 }
831 return buildRedirectURL (__FUNCTION__, 'OK');
832 }
833
834 $msgcode['addIPv4Prefix']['OK'] = 48;
835 function addIPv4Prefix ()
836 {
837 assertStringArg ('range');
838 assertStringArg ('name', TRUE);
839
840 $is_bcast = isset ($_REQUEST['is_bcast']) ? $_REQUEST['is_bcast'] : 'off';
841 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
842 global $sic;
843 createIPv4Prefix ($_REQUEST['range'], $sic['name'], $is_bcast == 'on', $taglist);
844 return buildRedirectURL (__FUNCTION__, 'OK');
845 }
846
847 $msgcode['addIPv6Prefix']['OK'] = 48;
848 function addIPv6Prefix ()
849 {
850 assertStringArg ('range');
851 assertStringArg ('name', TRUE);
852
853 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
854 global $sic;
855 createIPv6Prefix ($_REQUEST['range'], $sic['name'], $taglist);
856 return buildRedirectURL (__FUNCTION__, 'OK');
857 }
858
859 $msgcode['delIPv4Prefix']['OK'] = 49;
860 function delIPv4Prefix ()
861 {
862 assertUIntArg ('id');
863 destroyIPv4Prefix ($_REQUEST['id']);
864 return buildRedirectURL (__FUNCTION__, 'OK');
865 }
866
867 $msgcode['delIPv6Prefix']['OK'] = 49;
868 function delIPv6Prefix ()
869 {
870 assertUIntArg ('id');
871 destroyIPv6Prefix ($_REQUEST['id']);
872 return buildRedirectURL (__FUNCTION__, 'OK');
873 }
874
875 $msgcode['editAddress']['OK'] = 51;
876 $msgcode['editAddress']['ERR'] = 100;
877 function editAddress ()
878 {
879 assertStringArg ('name', TRUE);
880
881 if (isset ($_REQUEST['reserved']))
882 $reserved = $_REQUEST['reserved'];
883 else
884 $reserved = 'off';
885 $error = updateAddress ($_REQUEST['ip'], $_REQUEST['name'], $reserved == 'on' ? 'yes' : 'no');
886 if ($error != '')
887 return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
888 else
889 return buildRedirectURL (__FUNCTION__, 'OK');
890 }
891
892 $msgcode['editv6Address']['OK'] = 51;
893 $msgcode['editv6Address']['ERR'] = 100;
894 function editv6Address ()
895 {
896 $ipv6 = assertIPArg ('ip');
897 assertStringArg ('name', TRUE);
898
899 if (isset ($_REQUEST['reserved']))
900 $reserved = $_REQUEST['reserved'];
901 else
902 $reserved = 'off';
903 $error = updateAddress ($ipv6, $_REQUEST['name'], $reserved == 'on' ? 'yes' : 'no');
904 if ($error != '')
905 return buildRedirectURL (__FUNCTION__, 'ERR', array ($error));
906 else
907 return buildRedirectURL (__FUNCTION__, 'OK');
908 }
909
910 $msgcode['createUser']['OK'] = 5;
911 $msgcode['createUser']['ERR'] = 102;
912 function createUser ()
913 {
914 assertStringArg ('username');
915 assertStringArg ('realname', TRUE);
916 assertStringArg ('password');
917 $username = $_REQUEST['username'];
918 $password = sha1 ($_REQUEST['password']);
919 $result = commitCreateUserAccount ($username, $_REQUEST['realname'], $password);
920 if ($result != TRUE)
921 return buildRedirectURL (__FUNCTION__, 'ERR', array ($username));
922 if (isset ($_REQUEST['taglist']))
923 produceTagsForLastRecord ('user', $_REQUEST['taglist']);
924 return buildRedirectURL (__FUNCTION__, 'OK', array ($username));
925 }
926
927 $msgcode['updateUser']['OK'] = 6;
928 $msgcode['updateUser']['ERR2'] = 104;
929 function updateUser ()
930 {
931 assertStringArg ('username');
932 assertStringArg ('realname', TRUE);
933 assertStringArg ('password');
934 $username = $_REQUEST['username'];
935 $new_password = $_REQUEST['password'];
936 $userinfo = spotEntity ('user', $_REQUEST['user_id']);
937 // Update user password only if provided password is not the same as current password hash.
938 if ($new_password != $userinfo['user_password_hash'])
939 $new_password = sha1 ($new_password);
940 $result = commitUpdateUserAccount ($_REQUEST['user_id'], $username, $_REQUEST['realname'], $new_password);
941 if ($result !== FALSE)
942 return buildRedirectURL (__FUNCTION__, 'OK', array ($username));
943 else
944 return buildRedirectURL (__FUNCTION__, 'ERR2', array ($username));
945 }
946
947 $msgcode['updateDictionary']['OK'] = 51;
948 function updateDictionary ()
949 {
950 assertUIntArg ('dict_key');
951 assertStringArg ('dict_value');
952 // this request must be built with chapter_no
953 usePreparedUpdateBlade
954 (
955 'Dictionary',
956 array ('dict_value' => $sic['dict_value']),
957 array
958 (
959 'chapter_id' => $sic['chapter_no'],
960 'dict_key' => $sic['dict_key'],
961 )
962 );
963 return buildRedirectURL (__FUNCTION__, 'OK');
964 }
965
966 $msgcode['updateChapter']['OK'] = 51;
967 function updateChapter ()
968 {
969 assertUIntArg ('chapter_no');
970 assertStringArg ('chapter_name');
971 usePreparedUpdateBlade
972 (
973 'Chapter',
974 array
975 (
976 'name' => $chapter_name,
977 ),
978 array
979 (
980 'id' => $chapter_no,
981 'sticky' => 'no', // note this constant, it protects system chapters
982 )
983 );
984 return buildRedirectURL (__FUNCTION__, 'OK');
985 }
986
987 $msgcode['delChapter']['OK'] = 49;
988 $msgcode['delChapter']['ERR'] = 111;
989 function delChapter ()
990 {
991 assertUIntArg ('chapter_no');
992 if (commitDeleteChapter ($_REQUEST['chapter_no']))
993 return buildRedirectURL (__FUNCTION__, 'OK');
994 else
995 return buildRedirectURL (__FUNCTION__, 'ERR');
996 }
997
998 $msgcode['supplementAttrMap']['OK'] = 48;
999 $msgcode['supplementAttrMap']['ERR1'] = 154;
1000 $msgcode['supplementAttrMap']['ERR2'] = 110;
1001 function supplementAttrMap ()
1002 {
1003 assertUIntArg ('attr_id');
1004 assertUIntArg ('objtype_id');
1005 $attrMap = getAttrMap();
1006 if ($attrMap[$_REQUEST['attr_id']]['type'] != 'dict')
1007 $chapter_id = NULL;
1008 else
1009 {
1010 try
1011 {
1012 assertUIntArg ('chapter_no');
1013 }
1014 catch (InvalidRequestArgException $e)
1015 {
1016 return buildRedirectURL (__FUNCTION__, 'ERR1', array ('chapter not selected'));
1017 }
1018 $chapter_id = $_REQUEST['chapter_no'];
1019 }
1020 if (commitSupplementAttrMap ($_REQUEST['attr_id'], $_REQUEST['objtype_id'], $chapter_id) !== FALSE)
1021 return buildRedirectURL (__FUNCTION__, 'OK');
1022 else
1023 return buildRedirectURL (__FUNCTION__, 'ERR2');
1024 }
1025
1026 $msgcode['clearSticker']['OK'] = 49;
1027 $msgcode['clearSticker']['ERR'] = 120;
1028 function clearSticker ()
1029 {
1030 assertUIntArg ('attr_id');
1031 if (commitResetAttrValue ($_REQUEST['object_id'], $_REQUEST['attr_id']) !== FALSE)
1032 return buildRedirectURL (__FUNCTION__, 'OK');
1033 else
1034 return buildRedirectURL (__FUNCTION__, 'ERR');
1035 }
1036
1037 $msgcode['updateObjectAllocation']['OK'] = 63;
1038 function updateObjectAllocation ()
1039 {
1040 global $remote_username, $sic;
1041 if (!isset ($_REQUEST['got_atoms']))
1042 {
1043 unset($_GET['page']);
1044 unset($_GET['tab']);
1045 unset($_GET['op']);
1046 unset($_POST['page']);
1047 unset($_POST['tab']);
1048 unset($_POST['op']);
1049 return buildWideRedirectURL (array(), NULL, NULL, array_merge ($_GET, $_POST));
1050 }
1051 $object_id = $_REQUEST['object_id'];
1052 $workingRacksData = array();
1053 foreach ($_REQUEST['rackmulti'] as $cand_id)
1054 {
1055 if (!isset ($workingRacksData[$cand_id]))
1056 {
1057 $rackData = spotEntity ('rack', $cand_id);
1058 amplifyCell ($rackData);
1059 $workingRacksData[$cand_id] = $rackData;
1060 }
1061 }
1062
1063 foreach ($workingRacksData as &$rd)
1064 applyObjectMountMask ($rd, $object_id);
1065
1066 $oldMolecule = getMoleculeForObject ($object_id);
1067 $changecnt = 0;
1068 $log = array();
1069 foreach ($workingRacksData as $rack_id => $rackData)
1070 {
1071 $logrecord = processGridForm ($rackData, 'F', 'T', $object_id);
1072 $log[] = $logrecord;
1073 if ($logrecord['code'] == 300)
1074 continue;
1075 $changecnt++;
1076 // Reload our working copy after form processing.
1077 $rackData = spotEntity ('rack', $cand_id);
1078 amplifyCell ($rackData);
1079 applyObjectMountMask ($rackData, $object_id);
1080 $workingRacksData[$rack_id] = $rackData;
1081 }
1082 if (!$changecnt)
1083 return buildRedirectURL (__FUNCTION__, 'OK', $changecnt);
1084 // Log a record.
1085 $newMolecule = getMoleculeForObject ($object_id);
1086 usePreparedInsertBlade
1087 (
1088 'MountOperation',
1089 array
1090 (
1091 'object_id' => $object_id,
1092 'old_molecule_id' => count ($oldMolecule) ? createMolecule ($oldMolecule) : NULL,
1093 'new_molecule_id' => count ($newMolecule) ? createMolecule ($newMolecule) : NULL,
1094 'user_name' => $remote_username,
1095 'comment' => empty ($sic['comment']) ? NULL : $sic['comment'],
1096 )
1097 );
1098 $log[] = array ('code' => 200, 'message' => 'history logged');
1099 return buildWideRedirectURL ($log);
1100 }
1101
1102 $msgcode['updateObject']['OK'] = 51;
1103 $msgcode['updateObject']['ERR'] = 109;
1104 function updateObject ()
1105 {
1106 assertUIntArg ('num_attrs', TRUE);
1107 assertStringArg ('object_name', TRUE);
1108 assertStringArg ('object_label', TRUE);
1109 assertStringArg ('object_barcode', TRUE);
1110 assertStringArg ('object_asset_no', TRUE);
1111 if (isset ($_REQUEST['object_has_problems']) and $_REQUEST['object_has_problems'] == 'on')
1112 $has_problems = 'yes';
1113 else
1114 $has_problems = 'no';
1115
1116 if (commitUpdateObject (
1117 $_REQUEST['object_id'],
1118 $_REQUEST['object_name'],
1119 $_REQUEST['object_label'],
1120 $_REQUEST['object_barcode'],
1121 $has_problems,
1122 $_REQUEST['object_asset_no'],
1123 $_REQUEST['object_comment']
1124 ) !== TRUE)
1125 return buildRedirectURL (__FUNCTION__, 'ERR');
1126
1127 // Update optional attributes
1128 $oldvalues = getAttrValues ($_REQUEST['object_id']);
1129 $result = array();
1130 $num_attrs = isset ($_REQUEST['num_attrs']) ? $_REQUEST['num_attrs'] : 0;
1131 for ($i = 0; $i < $num_attrs; $i++)
1132 {
1133 assertUIntArg ("${i}_attr_id");
1134 $attr_id = $_REQUEST["${i}_attr_id"];
1135
1136 // Field is empty, delete attribute and move on. OR if the field type is a dictionary and it is the --NOT SET-- value of 0
1137 if (!strlen ($_REQUEST["${i}_value"]) || ($oldvalues[$attr_id]['type']=='dict' && $_REQUEST["${i}_value"] == 0))
1138 {
1139 commitResetAttrValue ($_REQUEST['object_id'], $attr_id);
1140 continue;
1141 }
1142
1143 // The value could be uint/float, but we don't know ATM. Let SQL
1144 // server check this and complain.
1145 assertStringArg ("${i}_value");
1146 $value = $_REQUEST["${i}_value"];
1147 switch ($oldvalues[$attr_id]['type'])
1148 {
1149 case 'uint':
1150 case 'float':
1151 case 'string':
1152 $oldvalue = $oldvalues[$attr_id]['value'];
1153 break;
1154 case 'dict':
1155 $oldvalue = $oldvalues[$attr_id]['key'];
1156 break;
1157 default:
1158 }
1159 if ($value === $oldvalue) // ('' == 0), but ('' !== 0)
1160 continue;
1161
1162 // Note if the queries succeed or not, it determines which page they see.
1163 $result[] = commitUpdateAttrValue ($_REQUEST['object_id'], $attr_id, $value);
1164 }
1165 if (in_array (FALSE, $result))
1166 return buildRedirectURL (__FUNCTION__, 'ERR');
1167
1168 // Invalidate thumb cache of all racks objects could occupy.
1169 foreach (getResidentRacksData ($_REQUEST['object_id'], FALSE) as $rack_id)
1170 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1171
1172 return buildRedirectURL (__FUNCTION__, 'OK');
1173 }
1174
1175 function addMultipleObjects()
1176 {
1177 $log = emptyLog();
1178 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1179 $max = getConfigVar ('MASSCOUNT');
1180 for ($i = 0; $i < $max; $i++)
1181 {
1182 if (!isset ($_REQUEST["${i}_object_type_id"]))
1183 {
1184 $log = mergeLogs ($log, oneLiner (184, array ($i + 1)));
1185 break;
1186 }
1187
1188 // set to empty values for virtual objects
1189 if (isset ($_REQUEST['virtual_objects']))
1190 {
1191 $_REQUEST["${i}_object_label"] = '';
1192 $_REQUEST["${i}_object_barcode"] = '';
1193 $_REQUEST["${i}_object_asset_no"] = '';
1194 }
1195
1196 assertUIntArg ("${i}_object_type_id", TRUE);
1197 assertStringArg ("${i}_object_name", TRUE);
1198 assertStringArg ("${i}_object_label", TRUE);
1199 assertStringArg ("${i}_object_asset_no", TRUE);
1200 assertStringArg ("${i}_object_barcode", TRUE);
1201 $name = $_REQUEST["${i}_object_name"];
1202
1203 // It's better to skip silently, than to print a notice.
1204 if ($_REQUEST["${i}_object_type_id"] == 0)
1205 continue;
1206 if (($object_id = commitAddObject
1207 (
1208 $name,
1209 $_REQUEST["${i}_object_label"],
1210 $_REQUEST["${i}_object_barcode"],
1211 $_REQUEST["${i}_object_type_id"],
1212 $_REQUEST["${i}_object_asset_no"],
1213 $taglist
1214 )) !== FALSE){
1215 $info = spotEntity ('object', $object_id);
1216 // FIXME: employ amplifyCell() instead of calling loader functions directly
1217 amplifyCell ($info);
1218 $log = mergeLogs ($log, oneLiner (5, array ('<a href="' . makeHref (array ('page' => 'object', 'tab' => 'default', 'object_id' => $object_id)) . '">' . $info['dname'] . '</a>')));
1219 }else{
1220 $log = mergeLogs ($log, oneLiner (147, array ($name)));
1221 }
1222 }
1223 return buildWideRedirectURL ($log);
1224 }
1225
1226 function addLotOfObjects()
1227 {
1228 $log = emptyLog();
1229 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1230 assertUIntArg ('global_type_id', TRUE);
1231 assertStringArg ('namelist', TRUE);
1232 $global_type_id = $_REQUEST['global_type_id'];
1233 if ($global_type_id == 0 or !strlen ($_REQUEST['namelist']))
1234 $log = mergeLogs ($log, oneLiner (186));
1235 else
1236 {
1237 // The name extractor below was stolen from ophandlers.php:addMultiPorts()
1238 $names1 = explode ("\n", $_REQUEST['namelist']);
1239 $names2 = array();
1240 foreach ($names1 as $line)
1241 {
1242 $parts = explode ('\r', $line);
1243 reset ($parts);
1244 if (!strlen ($parts[0]))
1245 continue;
1246 else
1247 $names2[] = rtrim ($parts[0]);
1248 }
1249 foreach ($names2 as $name)
1250 if (($object_id = commitAddObject ($name, '', '', $global_type_id, '', $taglist)) !== FALSE)
1251 {
1252 $info = spotEntity ('object', $object_id);
1253 amplifyCell ($info);
1254 $log = mergeLogs ($log, oneLiner (5, array ('<a href="' . makeHref (array ('page' => 'object', 'tab' => 'default', 'object_id' => $object_id)) . '">' . $info['dname'] . '</a>')));
1255 }
1256 else
1257 $log = mergeLogs ($log, oneLiner (147, array ($name)));
1258 }
1259 return buildWideRedirectURL ($log);
1260 }
1261
1262 $msgcode['deleteObject']['OK'] = 6;
1263 function deleteObject ()
1264 {
1265 assertUIntArg ('object_id');
1266 $oinfo = spotEntity ('object', $_REQUEST['object_id']);
1267
1268 $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
1269 commitDeleteObject ($_REQUEST['object_id']);
1270 foreach ($racklist as $rack_id)
1271 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1272 return buildRedirectURL (__FUNCTION__, 'OK', array ($oinfo['dname']));
1273 }
1274
1275 $msgcode['resetObject']['OK'] = 57;
1276 function resetObject ()
1277 {
1278 $oinfo = spotEntity ('object', $_REQUEST['object_id']);
1279
1280 $racklist = getResidentRacksData ($_REQUEST['object_id'], FALSE);
1281 commitResetObject ($_REQUEST['object_id']);
1282 foreach ($racklist as $rack_id)
1283 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $rack_id));
1284 return buildRedirectURL (__FUNCTION__, 'OK');
1285 }
1286
1287 $msgcode['useupPort']['OK'] = 49;
1288 function useupPort ()
1289 {
1290 global $sic;
1291 assertUIntArg ('port_id');
1292 usePreparedUpdateBlade
1293 (
1294 'Port',
1295 array
1296 (
1297 'reservation_comment' => NULL,
1298 ),
1299 array
1300 (
1301 'object_id' => $sic['object_id'],
1302 'id' => $sic['port_id'],
1303 )
1304 );
1305 return buildRedirectURL (__FUNCTION__, 'OK');
1306 }
1307
1308 $msgcode['updateUI']['OK'] = 51;
1309 function updateUI ()
1310 {
1311 assertUIntArg ('num_vars');
1312
1313 for ($i = 0; $i < $_REQUEST['num_vars']; $i++)
1314 {
1315 assertStringArg ("${i}_varname");
1316 assertStringArg ("${i}_varvalue", TRUE);
1317 $varname = $_REQUEST["${i}_varname"];
1318 $varvalue = $_REQUEST["${i}_varvalue"];
1319
1320 // If form value = value in DB, don't bother updating DB
1321 if (!isConfigVarChanged($varname, $varvalue))
1322 continue;
1323 // any exceptions will be handled by process.php
1324 setConfigVar ($varname, $varvalue, TRUE);
1325 }
1326 return buildRedirectURL (__FUNCTION__, 'OK');
1327 }
1328
1329 $msgcode['saveMyPreferences']['OK'] = 51;
1330 function saveMyPreferences ()
1331 {
1332 assertUIntArg ('num_vars');
1333
1334 for ($i = 0; $i < $_REQUEST['num_vars']; $i++)
1335 {
1336 assertStringArg ("${i}_varname");
1337 assertStringArg ("${i}_varvalue", TRUE);
1338 $varname = $_REQUEST["${i}_varname"];
1339 $varvalue = $_REQUEST["${i}_varvalue"];
1340
1341 // If form value = value in DB, don't bother updating DB
1342 if (!isConfigVarChanged($varname, $varvalue))
1343 continue;
1344 setUserConfigVar ($varname, $varvalue);
1345 }
1346 return buildRedirectURL (__FUNCTION__, 'OK');
1347 }
1348
1349 $msgcode['resetMyPreference']['OK'] = 51;
1350 function resetMyPreference ()
1351 {
1352 assertStringArg ("varname");
1353 resetUserConfigVar ($_REQUEST["varname"]);
1354 return buildRedirectURL (__FUNCTION__, 'OK');
1355 }
1356
1357 $msgcode['resetUIConfig']['OK'] = 57;
1358 function resetUIConfig()
1359 {
1360 setConfigVar ('MASSCOUNT','8');
1361 setConfigVar ('MAXSELSIZE','30');
1362 setConfigVar ('ROW_SCALE','2');
1363 setConfigVar ('PORTS_PER_ROW','12');
1364 setConfigVar ('IPV4_ADDRS_PER_PAGE','256');
1365 setConfigVar ('DEFAULT_RACK_HEIGHT','42');
1366 setConfigVar ('DEFAULT_SLB_VS_PORT','');
1367 setConfigVar ('DEFAULT_SLB_RS_PORT','');
1368 setConfigVar ('DETECT_URLS','no');
1369 setConfigVar ('RACK_PRESELECT_THRESHOLD','1');
1370 setConfigVar ('DEFAULT_IPV4_RS_INSERVICE','no');
1371 setConfigVar ('AUTOPORTS_CONFIG','4 = 1*33*kvm + 2*24*eth%u;15 = 1*446*kvm');
1372 setConfigVar ('SHOW_EXPLICIT_TAGS','yes');
1373 setConfigVar ('SHOW_IMPLICIT_TAGS','yes');
1374 setConfigVar ('SHOW_AUTOMATIC_TAGS','no');
1375 setConfigVar ('DEFAULT_OBJECT_TYPE','4');
1376 setConfigVar ('IPV4_AUTO_RELEASE','1');
1377 setConfigVar ('SHOW_LAST_TAB', 'no');
1378 setConfigVar ('EXT_IPV4_VIEW', 'yes');
1379 setConfigVar ('TREE_THRESHOLD', '25');
1380 setConfigVar ('IPV4_JAYWALK', 'no');
1381 setConfigVar ('ADDNEW_AT_TOP', 'yes');
1382 setConfigVar ('IPV4_TREE_SHOW_USAGE', 'yes');
1383 setConfigVar ('PREVIEW_TEXT_MAXCHARS', '10240');
1384 setConfigVar ('PREVIEW_TEXT_ROWS', '25');
1385 setConfigVar ('PREVIEW_TEXT_COLS', '80');
1386 setConfigVar ('PREVIEW_IMAGE_MAXPXS', '320');
1387 setConfigVar ('VENDOR_SIEVE', '');
1388 setConfigVar ('IPV4LB_LISTSRC', '{$typeid_4}');
1389 setConfigVar ('IPV4OBJ_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_12} or {$typeid_445} or {$typeid_447} or {$typeid_798} or {$typeid_1504}');
1390 setConfigVar ('IPV4NAT_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8} or {$typeid_798}');
1391 setConfigVar ('ASSETWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
1392 setConfigVar ('NAMEWARN_LISTSRC','{$typeid_4} or {$typeid_7} or {$typeid_8}');
1393 setConfigVar ('RACKS_PER_ROW','12');
1394 setConfigVar ('FILTER_PREDICATE_SIEVE','');
1395 setConfigVar ('FILTER_DEFAULT_ANDOR','or');
1396 setConfigVar ('FILTER_SUGGEST_ANDOR','yes');
1397 setConfigVar ('FILTER_SUGGEST_TAGS','yes');
1398 setConfigVar ('FILTER_SUGGEST_PREDICATES','yes');
1399 setConfigVar ('FILTER_SUGGEST_EXTRA','no');
1400 setConfigVar ('DEFAULT_SNMP_COMMUNITY','public');
1401 setConfigVar ('IPV4_ENABLE_KNIGHT','yes');
1402 setConfigVar ('TAGS_TOPLIST_SIZE','50');
1403 setConfigVar ('TAGS_QUICKLIST_SIZE','20');
1404 setConfigVar ('TAGS_QUICKLIST_THRESHOLD','50');
1405 setConfigVar ('ENABLE_MULTIPORT_FORM', 'no');
1406 setConfigVar ('DEFAULT_PORT_IIF_ID', '1');
1407 setConfigVar ('DEFAULT_PORT_OIF_IDS', '1=24; 3=1078; 4=1077; 5=1079; 6=1080; 8=1082; 9=1084');
1408 setConfigVar ('IPV4_TREE_RTR_AS_CELL', 'yes');
1409 setConfigVar ('PROXIMITY_RANGE', 0);
1410 setConfigVar ('IPV4_TREE_SHOW_VLAN', 'yes');
1411 setConfigVar ('VLANSWITCH_LISTSRC', '');
1412 setConfigVar ('VLANIPV4NET_LISTSRC', '');
1413 setConfigVar ('DEFAULT_VDOM_ID', '');
1414 setConfigVar ('DEFAULT_VST_ID', '');
1415 setConfigVar ('STATIC_FILTER', 'yes');
1416 setConfigVar ('8021Q_DEPLOY_MINAGE', '300');
1417 setConfigVar ('8021Q_DEPLOY_MAXAGE', '3600');
1418 setConfigVar ('8021Q_DEPLOY_RETRY', '10800');
1419 setConfigVar ('8021Q_WRI_AFTER_CONFT_LISTSRC', 'false');
1420 setConfigVar ('8021Q_INSTANT_DEPLOY', 'no');
1421 setConfigVar ('CDP_RUNNERS_LISTSRC', '');
1422 setConfigVar ('LLDP_RUNNERS_LISTSRC', '');
1423 setConfigVar ('HNDP_RUNNERS_LISTSRC', '');
1424 setConfigVar ('SHRINK_TAG_TREE_ON_CLICK', 'yes');
1425 setConfigVar ('MAX_UNFILTERED_ENTITIES', '0');
1426 setConfigVar ('SYNCDOMAIN_MAX_PROCESSES', '0');
1427 setConfigVar ('VIRTUAL_OBJ_LISTSRC', '{$typeid_1504} or {$typeid_1505} or {$typeid_1506} or {$typeid_1507}');
1428 setConfigVar ('PORT_EXCLUSION_LISTSRC', '{$typeid_3} or {$typeid_10} or {$typeid_11} or {$typeid_1505} or {$typeid_1506}');
1429 return buildRedirectURL (__FUNCTION__, 'OK');
1430 }
1431
1432 $msgcode['addRealServer']['OK'] = 48;
1433 $msgcode['addRealServer']['ERR'] = 110;
1434 // Add single record.
1435 function addRealServer ()
1436 {
1437 assertUIntArg ('pool_id');
1438 assertIPv4Arg ('remoteip');
1439 assertStringArg ('rsport', TRUE);
1440 assertStringArg ('rsconfig', TRUE);
1441 if (!addRStoRSPool (
1442 $_REQUEST['pool_id'],
1443 $_REQUEST['remoteip'],
1444 $_REQUEST['rsport'],
1445 getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'),
1446 $_REQUEST['rsconfig']
1447 ))
1448 return buildRedirectURL (__FUNCTION__, 'ERR');
1449 else
1450 return buildRedirectURL (__FUNCTION__, 'OK');
1451 }
1452
1453 $msgcode['addRealServers']['OK'] = 37;
1454 $msgcode['addRealServers']['ERR1'] = 131;
1455 $msgcode['addRealServers']['ERR2'] = 127;
1456 // Parse textarea submitted and try adding a real server for each line.
1457 function addRealServers ()
1458 {
1459 assertStringArg ('format');
1460 assertStringArg ('rawtext');
1461 $ngood = $nbad = 0;
1462 $rsconfig = '';
1463 // Keep in mind, that the text will have HTML entities (namely '>') escaped.
1464 foreach (explode ("\n", dos2unix ($_REQUEST['rawtext'])) as $line)
1465 {
1466 if (!strlen ($line))
1467 continue;
1468 $match = array ();
1469 switch ($_REQUEST['format'])
1470 {
1471 case 'ipvs_2': // address and port only
1472 if (!preg_match ('/^ -&gt; ([0-9\.]+):([0-9]+) /', $line, $match))
1473 continue;
1474 if (addRStoRSPool ($_REQUEST['pool_id'], $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), ''))
1475 $ngood++;
1476 else
1477 $nbad++;
1478 break;
1479 case 'ipvs_3': // address, port and weight
1480 if (!preg_match ('/^ -&gt; ([0-9\.]+):([0-9]+) +[a-zA-Z]+ +([0-9]+) /', $line, $match))
1481 continue;
1482 if (addRStoRSPool ($_REQUEST['pool_id'], $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), 'weight ' . $match[3]))
1483 $ngood++;
1484 else
1485 $nbad++;
1486 break;
1487 case 'ssv_2': // IP address and port
1488 if (!preg_match ('/^([0-9\.]+) ([0-9]+)$/', $line, $match))
1489 continue;
1490 if (addRStoRSPool ($_REQUEST['pool_id'], $match[1], $match[2], getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), ''))
1491 $ngood++;
1492 else
1493 $nbad++;
1494 break;
1495 case 'ssv_1': // IP address
1496 if (!preg_match ('/^([0-9\.]+)$/', $line, $match))
1497 continue;
1498 if (addRStoRSPool ($_REQUEST['pool_id'], $match[1], 0, getConfigVar ('DEFAULT_IPV4_RS_INSERVICE'), ''))
1499 $ngood++;
1500 else
1501 $nbad++;
1502 break;
1503 default:
1504 return buildRedirectURL (__FUNCTION__, 'ERR1');
1505 break;
1506 }
1507 }
1508 if ($nbad == 0 and $ngood > 0)
1509 return buildRedirectURL (__FUNCTION__, 'OK', array ($ngood));
1510 else
1511 return buildRedirectURL (__FUNCTION__, 'ERR2', array ($ngood, $nbad));
1512 }
1513
1514 $msgcode['addVService']['OK'] = 48;
1515 function addVService ()
1516 {
1517 assertIPv4Arg ('vip');
1518 assertUIntArg ('vport');
1519 genericAssertion ('proto', 'enum/ipproto');
1520 assertStringArg ('name', TRUE);
1521 assertStringArg ('vsconfig', TRUE);
1522 assertStringArg ('rsconfig', TRUE);
1523 usePreparedExecuteBlade
1524 (
1525 'INSERT INTO IPv4VS (vip, vport, proto, name, vsconfig, rsconfig) VALUES (INET_ATON(?), ?, ?, ?, ?, ?)',
1526 array
1527 (
1528 $_REQUEST['vip'],
1529 $_REQUEST['vport'],
1530 $_REQUEST['proto'],
1531 !mb_strlen ($_REQUEST['name']) ? NULL : $_REQUEST['name'],
1532 !strlen ($_REQUEST['vsconfig']) ? NULL : $_REQUEST['vsconfig'],
1533 !strlen ($_REQUEST['rsconfig']) ? NULL : $_REQUEST['rsconfig'],
1534 )
1535 );
1536 produceTagsForLastRecord ('ipv4vs', isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array());
1537 return buildRedirectURL (__FUNCTION__, 'OK');
1538 }
1539
1540 $msgcode['deleteVService']['OK'] = 49;
1541 $msgcode['deleteVService']['ERR'] = 111;
1542 function deleteVService ()
1543 {
1544 assertUIntArg ('vs_id');
1545 if (!commitDeleteVS ($_REQUEST['vs_id']))
1546 return buildRedirectURL (__FUNCTION__, 'ERR');
1547 else
1548 return buildRedirectURL (__FUNCTION__, 'OK');
1549 }
1550
1551 $msgcode['updateSLBDefConfig']['OK'] = 43;
1552 $msgcode['updateSLBDefConfig']['ERR'] = 109;
1553 function updateSLBDefConfig ()
1554 {
1555 $data = array(
1556 'vs' => $_REQUEST['vsconfig'],
1557 'rs' => $_REQUEST['rsconfig']
1558 );
1559 if (!commitUpdateSLBDefConf ($data))
1560 return buildRedirectURL (__FUNCTION__, 'ERR');
1561 else
1562 return buildRedirectURL (__FUNCTION__, 'OK');
1563 }
1564
1565 $msgcode['updateRealServer']['OK'] = 51;
1566 $msgcode['updateRealServer']['ERR'] = 109;
1567 function updateRealServer ()
1568 {
1569 assertUIntArg ('rs_id');
1570 assertIPv4Arg ('rsip');
1571 assertStringArg ('rsport', TRUE);
1572 assertStringArg ('rsconfig', TRUE);
1573 if (FALSE === commitUpdateRS (
1574 $_REQUEST['rs_id'],
1575 $_REQUEST['rsip'],
1576 $_REQUEST['rsport'],
1577 $_REQUEST['rsconfig']
1578 ))
1579 return buildRedirectURL (__FUNCTION__, 'ERR');
1580 else
1581 return buildRedirectURL (__FUNCTION__, 'OK');
1582 }
1583
1584 $msgcode['updateVService']['OK'] = 51;
1585 $msgcode['updateVService']['ERR'] = 109;
1586 function updateVService ()
1587 {
1588 assertUIntArg ('vs_id');
1589 assertIPv4Arg ('vip');
1590 assertUIntArg ('vport');
1591 genericAssertion ('proto', 'enum/ipproto');
1592 assertStringArg ('name', TRUE);
1593 assertStringArg ('vsconfig', TRUE);
1594 assertStringArg ('rsconfig', TRUE);
1595 if (FALSE === commitUpdateVS (
1596 $_REQUEST['vs_id'],
1597 $_REQUEST['vip'],
1598 $_REQUEST['vport'],
1599 $_REQUEST['proto'],
1600 $_REQUEST['name'],
1601 $_REQUEST['vsconfig'],
1602 $_REQUEST['rsconfig']
1603 ))
1604 return buildRedirectURL (__FUNCTION__, 'ERR');
1605 else
1606 return buildRedirectURL (__FUNCTION__, 'OK');
1607 }
1608
1609 $msgcode['addLoadBalancer']['OK'] = 48;
1610 $msgcode['addLoadBalancer']['ERR'] = 110;
1611 function addLoadBalancer ()
1612 {
1613 assertUIntArg ('pool_id');
1614 assertUIntArg ('object_id');
1615 assertUIntArg ('vs_id');
1616 assertStringArg ('vsconfig', TRUE);
1617 assertStringArg ('rsconfig', TRUE);
1618 if (! empty($_REQUEST['prio']))
1619 assertUIntArg('prio', TRUE);
1620
1621 if (!addLBtoRSPool (
1622 $_REQUEST['pool_id'],
1623 $_REQUEST['object_id'],
1624 $_REQUEST['vs_id'],
1625 $_REQUEST['vsconfig'],
1626 $_REQUEST['rsconfig'],
1627 $_REQUEST['prio']
1628 ))
1629 return buildRedirectURL (__FUNCTION__, 'ERR');
1630 else
1631 return buildRedirectURL (__FUNCTION__, 'OK');
1632 }
1633
1634 $msgcode['addRSPool']['OK'] = 48;
1635 function addRSPool ()
1636 {
1637 assertStringArg ('name');
1638 assertStringArg ('vsconfig', TRUE);
1639 assertStringArg ('rsconfig', TRUE);
1640 commitCreateRSPool
1641 (
1642 $_REQUEST['name'],
1643 $_REQUEST['vsconfig'],
1644 $_REQUEST['rsconfig'],
1645 isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array()
1646 );
1647 return buildRedirectURL (__FUNCTION__, 'OK');
1648 }
1649
1650 $msgcode['deleteRSPool']['OK'] = 49;
1651 $msgcode['deleteRSPool']['ERR'] = 111;
1652 function deleteRSPool ()
1653 {
1654 assertUIntArg ('pool_id');
1655 if (commitDeleteRSPool ($_REQUEST['pool_id']) === FALSE)
1656 return buildRedirectURL (__FUNCTION__, 'ERR');
1657 else
1658 return buildRedirectURL (__FUNCTION__, 'OK');
1659 }
1660
1661 $msgcode['updateRSInService']['OK'] = 26;
1662 $msgcode['updateRSInService']['ERR'] = 141;
1663 function updateRSInService ()
1664 {
1665 assertUIntArg ('rscount');
1666 $pool_id = $_REQUEST['pool_id'];
1667 $orig = spotEntity ('ipv4rspool', $pool_id);
1668 amplifyCell ($orig);
1669 $nbad = $ngood = 0;
1670 for ($i = 1; $i <= $_REQUEST['rscount']; $i++)
1671 {
1672 $rs_id = $_REQUEST["rsid_${i}"];
1673 if (isset ($_REQUEST["inservice_${i}"]) and $_REQUEST["inservice_${i}"] == 'on')
1674 $newval = 'yes';
1675 else
1676 $newval = 'no';
1677 if ($newval != $orig['rslist'][$rs_id]['inservice'])
1678 {
1679 if (FALSE !== commitSetInService ($rs_id, $newval))
1680 $ngood++;
1681 else
1682 $nbad++;
1683 }
1684 }
1685 if (!$nbad)
1686 return buildRedirectURL (__FUNCTION__, 'OK', array ($ngood));
1687 else
1688 return buildRedirectURL (__FUNCTION__, 'ERR', array ($nbad, $ngood));
1689 }
1690
1691 $msgcode['importPTRData']['OK'] = 26;
1692 $msgcode['importPTRData']['ERR'] = 141;
1693 // FIXME: check, that each submitted address belongs to the prefix we
1694 // are operating on.
1695 function importPTRData ()
1696 {
1697 assertUIntArg ('addrcount');
1698 $nbad = $ngood = 0;
1699 for ($i = 0; $i < $_REQUEST['addrcount']; $i++)
1700 {
1701 $inputname = "import_${i}";
1702 if (!isset ($_REQUEST[$inputname]) or $_REQUEST[$inputname] != 'on')
1703 continue;
1704 assertIPv4Arg ("addr_${i}");
1705 assertStringArg ("descr_${i}", TRUE);
1706 assertStringArg ("rsvd_${i}");
1707 // Non-existent addresses will not have this argument set in request.
1708 $rsvd = 'no';
1709 if ($_REQUEST["rsvd_${i}"] == 'yes')
1710 $rsvd = 'yes';
1711 if (updateAddress ($_REQUEST["addr_${i}"], $_REQUEST["descr_${i}"], $rsvd) == '')
1712 $ngood++;
1713 else
1714 $nbad++;
1715 }
1716 if (!$nbad)
1717 return buildRedirectURL (__FUNCTION__, 'OK', array ($ngood));
1718 else
1719 return buildRedirectURL (__FUNCTION__, 'ERR', array ($nbad, $ngood));
1720 }
1721
1722 $msgcode['generateAutoPorts']['OK'] = 21;
1723 $msgcode['generateAutoPorts']['ERR'] = 142;
1724 function generateAutoPorts ()
1725 {
1726 global $pageno;
1727 $info = spotEntity ('object', $_REQUEST['object_id']);
1728 // Navigate away in case of success, stay at the place otherwise.
1729 if (executeAutoPorts ($_REQUEST['object_id'], $info['objtype_id']))
1730 return buildRedirectURL (__FUNCTION__, 'OK', array(), $pageno, 'ports');
1731 else
1732 return buildRedirectURL (__FUNCTION__, 'ERR');
1733 }
1734
1735 $msgcode['saveEntityTags']['OK'] = 26;
1736 $msgcode['saveEntityTags']['ERR1'] = 143;
1737 // Filter out implicit tags before storing the new tag set.
1738 function saveEntityTags ()
1739 {
1740 global $pageno, $etype_by_pageno;
1741 if (!isset ($etype_by_pageno[$pageno]))
1742 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
1743 $realm = $etype_by_pageno[$pageno];
1744 $entity_id = getBypassValue();
1745 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1746 // Build a chain from the submitted data, minimize it,
1747 // then wipe existing records and store the new set instead.
1748 destroyTagsForEntity ($realm, $entity_id);
1749 // TODO: these actions are very close to what rebuildTagChainForEntity() does,
1750 // so why not use it?
1751 $newchain = getExplicitTagsOnly (buildTagChainFromIds ($taglist));
1752 $n_succeeds = $n_errors = 0;
1753 foreach ($newchain as $taginfo)
1754 if (addTagForEntity ($realm, $entity_id, $taginfo['id']))
1755 $n_succeeds++;
1756 else
1757 $n_errors++;
1758 if ($n_errors)
1759 return buildRedirectURL (__FUNCTION__, 'ERR1', array ($n_succeeds, $n_errors));
1760 else
1761 return buildRedirectURL (__FUNCTION__, 'OK', array ($n_succeeds));
1762 }
1763
1764 $msgcode['rollTags']['OK'] = 67;
1765 $msgcode['rollTags']['ERR'] = 149;
1766 function rollTags ()
1767 {
1768 assertStringArg ('sum', TRUE);
1769 assertUIntArg ('realsum');
1770 if ($_REQUEST['sum'] != $_REQUEST['realsum'])
1771 return buildRedirectURL (__FUNCTION__, 'ERR');
1772 // Even if the user requested an empty tag list, don't bail out, but process existing
1773 // tag chains with "zero" extra. This will make sure, that the stuff processed will
1774 // have its chains refined to "normal" form.
1775 $extratags = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1776 $n_ok = 0;
1777 // Minimizing the extra chain early, so that tag rebuilder doesn't have to
1778 // filter out the same tag again and again. It will have own noise to cancel.
1779 $extrachain = getExplicitTagsOnly (buildTagChainFromIds ($extratags));
1780 foreach (listCells ('rack', $_REQUEST['row_id']) as $rack)
1781 {
1782 if (rebuildTagChainForEntity ('rack', $rack['id'], $extrachain))
1783 $n_ok++;
1784 amplifyCell ($rack);
1785 foreach ($rack['mountedObjects'] as $object_id)
1786 if (rebuildTagChainForEntity ('object', $object_id, $extrachain))
1787 $n_ok++;
1788 }
1789 return buildRedirectURL (__FUNCTION__, 'OK', array ($n_ok));
1790 }
1791
1792 $msgcode['changeMyPassword']['OK'] = 51;
1793 $msgcode['changeMyPassword']['ERR1'] = 150;
1794 $msgcode['changeMyPassword']['ERR2'] = 151;
1795 $msgcode['changeMyPassword']['ERR3'] = 152;
1796 $msgcode['changeMyPassword']['ERR4'] = 153;
1797 function changeMyPassword ()
1798 {
1799 global $remote_username, $user_auth_src;
1800 if ($user_auth_src != 'database')
1801 return buildRedirectURL (__FUNCTION__, 'ERR1');
1802 assertStringArg ('oldpassword');
1803 assertStringArg ('newpassword1');
1804 assertStringArg ('newpassword2');
1805 $remote_userid = getUserIDByUsername ($remote_username);
1806 $userinfo = spotEntity ('user', $remote_userid);
1807 if ($userinfo['user_password_hash'] != sha1 ($_REQUEST['oldpassword']))
1808 return buildRedirectURL (__FUNCTION__, 'ERR2');
1809 if ($_REQUEST['newpassword1'] != $_REQUEST['newpassword2'])
1810 return buildRedirectURL (__FUNCTION__, 'ERR3');
1811 if (FALSE !== commitUpdateUserAccount ($remote_userid, $userinfo['user_name'], $userinfo['user_realname'], sha1 ($_REQUEST['newpassword1'])))
1812 return buildRedirectURL (__FUNCTION__, 'OK');
1813 else
1814 return buildRedirectURL (__FUNCTION__, 'ERR4');
1815 }
1816
1817 $msgcode['saveRackCode']['OK'] = 43;
1818 $msgcode['saveRackCode']['ERR1'] = 154;
1819 $msgcode['saveRackCode']['ERR2'] = 155;
1820 function saveRackCode ()
1821 {
1822 assertStringArg ('rackcode');
1823 // For the test to succeed, unescape LFs, strip CRs.
1824 $newcode = dos2unix ($_REQUEST['rackcode']);
1825 $parseTree = getRackCode ($newcode);
1826 if ($parseTree['result'] != 'ACK')
1827 return buildRedirectURL (__FUNCTION__, 'ERR1', array ($parseTree['load']));
1828 if (FALSE !== saveScript ('RackCode', $newcode))
1829 {
1830 saveScript ('RackCodeCache', base64_encode (serialize ($parseTree)));
1831 return buildRedirectURL (__FUNCTION__, 'OK');
1832 }
1833 return buildRedirectURL (__FUNCTION__, 'ERR2');
1834 }
1835
1836 $msgcode['setPortVLAN']['ERR'] = 164;
1837 // This handler's context is pre-built, but not authorized. It is assumed, that the
1838 // handler will take existing context and before each commit check authorization
1839 // on the base chain plus necessary context added.
1840 function setPortVLAN ()
1841 {
1842 assertUIntArg ('portcount');
1843 try
1844 {
1845 $data = getSwitchVLANs ($_REQUEST['object_id']);
1846 }
1847 catch (RTGatewayError $re)
1848 {
1849 return buildRedirectURL (__FUNCTION__, 'ERR', array ($re->getMessage()));
1850 }
1851 list ($vlanlist, $portlist) = $data;
1852 // Here we just build up 1 set command for the gateway with all of the ports
1853 // included. The gateway is expected to filter unnecessary changes silently
1854 // and to provide a list of responses with either error or success message
1855 // for each of the rest.
1856 $nports = $_REQUEST['portcount'];
1857 $prefix = 'set ';
1858 $log = emptyLog();
1859 $setcmd = '';
1860 for ($i = 0; $i < $nports; $i++)
1861 {
1862 genericAssertion ('portname_' . $i, 'string');
1863 genericAssertion ('vlanid_' . $i, 'string');
1864 if ($_REQUEST['portname_' . $i] != $portlist[$i]['portname'])
1865 throw new InvalidRequestArgException ('portname_' . $i, $_REQUEST['portname_' . $i], 'expected to be ' . $portlist[$i]['portname']);
1866 if
1867 (
1868 $_REQUEST['vlanid_' . $i] == $portlist[$i]['vlanid'] ||
1869 $portlist[$i]['vlaind'] == 'TRUNK'
1870 )
1871 continue;
1872 $portname = $_REQUEST['portname_' . $i];
1873 $oldvlanid = $portlist[$i]['vlanid'];
1874 $newvlanid = $_REQUEST['vlanid_' . $i];
1875 if
1876 (
1877 !permitted (NULL, NULL, NULL, array (array ('tag' => '$fromvlan_' . $oldvlanid))) or
1878 !permitted (NULL, NULL, NULL, array (array ('tag' => '$tovlan_' . $newvlanid)))
1879 )
1880 {
1881 $log = mergeLogs ($log, oneLiner (159, array ($portname, $oldvlanid, $newvlanid)));
1882 continue;
1883 }
1884 $setcmd .= $prefix . $portname . '=' . $newvlanid;
1885 $prefix = ';';
1886 }
1887 // Feed the gateway and interpret its (non)response.
1888 if ($setcmd == '')
1889 $log = mergeLogs ($log, oneLiner (201));
1890 else
1891 {
1892 try
1893 {
1894 $log = mergeLogs ($log, setSwitchVLANs ($_REQUEST['object_id'], $setcmd));
1895 }
1896 catch (RTGatewayError $e)
1897 {
1898 $log = mergeLogs ($log, oneLiner (164, $e->getMessage()));
1899 }
1900 }
1901 return buildWideRedirectURL ($log);
1902 }
1903
1904 $msgcode['submitSLBConfig']['OK'] = 66;
1905 $msgcode['submitSLBConfig']['ERR'] = 164;
1906 function submitSLBConfig ()
1907 {
1908 $newconfig = buildLVSConfig ($_REQUEST['object_id']);
1909 try
1910 {
1911 gwSendFileToObject ($_REQUEST['object_id'], 'slbconfig', html_entity_decode ($newconfig, ENT_QUOTES, 'UTF-8'));
1912 }
1913 catch (RTGatewayError $e)
1914 {
1915 return buildRedirectURL (__FUNCTION__, 'ERR', array ($e->getMessage()));
1916 }
1917 return buildRedirectURL (__FUNCTION__, 'OK', array ('slbconfig'));
1918 }
1919
1920 $msgcode['addRack']['OK'] = 51;
1921 $msgcode['addRack']['ERR2'] = 172;
1922 function addRack ()
1923 {
1924 $taglist = isset ($_REQUEST['taglist']) ? $_REQUEST['taglist'] : array();
1925 if (isset ($_REQUEST['got_data']))
1926 {
1927 assertStringArg ('rack_name');
1928 assertUIntArg ('rack_height1');
1929 assertStringArg ('rack_comment', TRUE);
1930 commitAddRack ($_REQUEST['rack_name'], $_REQUEST['rack_height1'], $_REQUEST['row_id'], $_REQUEST['rack_comment'], $taglist);
1931 return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
1932 }
1933 elseif (isset ($_REQUEST['got_mdata']))
1934 {
1935 assertUIntArg ('rack_height2');
1936 assertStringArg ('rack_names', TRUE);
1937 $log = emptyLog();
1938 // copy-and-paste from renderAddMultipleObjectsForm()
1939 $names1 = explode ("\n", $_REQUEST['rack_names']);
1940 $names2 = array();
1941 foreach ($names1 as $line)
1942 {
1943 $parts = explode ('\r', $line);
1944 reset ($parts);
1945 if (!strlen ($parts[0]))
1946 continue;
1947 else
1948 $names2[] = rtrim ($parts[0]);
1949 }
1950 global $msgcode;
1951 foreach ($names2 as $cname)
1952 {
1953 commitAddRack ($cname, $_REQUEST['rack_height2'], $_REQUEST['row_id'], '', $taglist);
1954 $log['m'][] = array ('c' => $msgcode[__FUNCTION__]['OK'], 'a' => array ($cname));
1955 }
1956 return buildWideRedirectURL ($log);
1957 }
1958 else
1959 return buildRedirectURL (__FUNCTION__, 'ERR2');
1960 }
1961
1962 $msgcode['deleteRack']['OK'] = 6;
1963 $msgcode['deleteRack']['ERR'] = 100;
1964 $msgcode['deleteRack']['ERR1'] = 206;
1965 function deleteRack ()
1966 {
1967 assertUIntArg ('rack_id');
1968 $rackData = spotEntity ('rack', $_REQUEST['rack_id']);
1969 amplifyCell ($rackData);
1970 if (count ($rackData['mountedObjects']))
1971 return buildRedirectURL (__FUNCTION__, 'ERR1');
1972 if (TRUE !== commitDeleteRack ($_REQUEST['rack_id']))
1973 return buildRedirectURL (__FUNCTION__, 'ERR', array(), 'rackspace', 'default');
1974 return buildRedirectURL (__FUNCTION__, 'OK', array ($rackData['name']), 'rackspace', 'default');
1975 }
1976
1977 $msgcode['updateRack']['OK'] = 7;
1978 $msgcode['updateRack']['ERR'] = 109;
1979 function updateRack ()
1980 {
1981 assertUIntArg ('rack_row_id');
1982 assertUIntArg ('rack_height');
1983 assertStringArg ('rack_name');
1984 assertStringArg ('rack_comment', TRUE);
1985
1986 global $sic;
1987 usePreparedUpdateBlade ('Rack', array ('thumb_data' => NULL), array ('id' => $sic['rack_id']));
1988 if (TRUE === commitUpdateRack ($_REQUEST['rack_id'], $_REQUEST['rack_name'], $_REQUEST['rack_height'], $_REQUEST['rack_row_id'], $_REQUEST['rack_comment']))
1989 return buildRedirectURL (__FUNCTION__, 'OK', array ($_REQUEST['rack_name']));
1990 else
1991 return buildRedirectURL (__FUNCTION__, 'ERR');
1992 }
1993
1994 function updateRackDesign ()
1995 {
1996 $rackData = spotEntity ('rack', $_REQUEST['rack_id']);
1997 amplifyCell ($rackData);
1998 applyRackDesignMask($rackData);
1999 markupObjectProblems ($rackData);
2000 $response = processGridForm ($rackData, 'A', 'F');
2001 return buildWideRedirectURL (array($response));
2002 }
2003
2004 function updateRackProblems ()
2005 {
2006 $rackData = spotEntity ('rack', $_REQUEST['rack_id']);
2007 amplifyCell ($rackData);
2008 applyRackProblemMask($rackData);
2009 markupObjectProblems ($rackData);
2010 $response = processGridForm ($rackData, 'F', 'U');
2011 return buildWideRedirectURL (array($response));
2012 }
2013
2014 function querySNMPData ()
2015 {
2016 assertStringArg ('community', TRUE);
2017
2018 $snmpsetup = array ();
2019 if ($_REQUEST['community'] != '')
2020 $snmpsetup['community'] = $_REQUEST['community'];
2021 else
2022 {
2023 assertStringArg ('sec_name');
2024 assertStringArg ('sec_level');
2025 assertStringArg ('auth_protocol');
2026 assertStringArg ('auth_passphrase', TRUE);
2027 assertStringArg ('priv_protocol');
2028 assertStringArg ('priv_passphrase', TRUE);
2029
2030 $snmpsetup['sec_name'] = $_REQUEST['sec_name'];
2031 $snmpsetup['sec_level'] = $_REQUEST['sec_level'];
2032 $snmpsetup['auth_protocol'] = $_REQUEST['auth_protocol'];
2033 $snmpsetup['auth_passphrase'] = $_REQUEST['auth_passphrase'];
2034 $snmpsetup['priv_protocol'] = $_REQUEST['priv_protocol'];
2035 $snmpsetup['priv_passphrase'] = $_REQUEST['priv_passphrase'];
2036 }
2037 return doSNMPmining ($_REQUEST['object_id'], $snmpsetup);
2038 }
2039
2040 $msgcode['linkEntities']['OK'] = 51;
2041 $msgcode['linkEntities']['ERR2'] = 109;
2042 function linkEntities ()
2043 {
2044 assertStringArg ('parent_entity_type');
2045 assertUIntArg ('parent_entity_id');
2046 assertStringArg ('child_entity_type');
2047 assertUIntArg ('child_entity_id');
2048 $result = usePreparedInsertBlade
2049 (
2050 'EntityLink',
2051 array
2052 (
2053 'parent_entity_type' => $_REQUEST['parent_entity_type'],
2054 'parent_entity_id' => $_REQUEST['parent_entity_id'],
2055 'child_entity_type' => $_REQUEST['child_entity_type'],
2056 'child_entity_id' => $_REQUEST['child_entity_id'],
2057 )
2058 );
2059 if ($result === FALSE)
2060 return buildRedirectURL (__FUNCTION__, 'ERR2');
2061 return buildRedirectURL (__FUNCTION__, 'OK');
2062 }
2063
2064 $msgcode['unlinkEntities']['OK'] = 49;
2065 $msgcode['unlinkEntities']['ERR'] = 111;
2066 function unlinkEntities ()
2067 {
2068 assertUIntArg ('link_id');
2069 return buildRedirectURL (__FUNCTION__, commitUnlinkEntities ($_REQUEST['link_id']) === FALSE ? 'ERR' : 'OK');
2070 }
2071
2072 $msgcode['addFileWithoutLink']['OK'] = 5;
2073 // File-related functions
2074 function addFileWithoutLink ()
2075 {
2076 assertStringArg ('comment', TRUE);
2077
2078 // Make sure the file can be uploaded
2079 if (get_cfg_var('file_uploads') != 1)
2080 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
2081
2082 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
2083 global $sic;
2084 commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
2085 if (isset ($_REQUEST['taglist']))
2086 produceTagsForLastRecord ('file', $_REQUEST['taglist']);
2087 return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
2088 }
2089
2090 $msgcode['addFileToEntity']['OK'] = 5;
2091 function addFileToEntity ()
2092 {
2093 global $pageno, $etype_by_pageno;
2094 if (!isset ($etype_by_pageno[$pageno]))
2095 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
2096 $realm = $etype_by_pageno[$pageno];
2097 assertStringArg ('comment', TRUE);
2098
2099 // Make sure the file can be uploaded
2100 if (get_cfg_var('file_uploads') != 1)
2101 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
2102
2103 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
2104 global $sic;
2105 commitAddFile ($_FILES['file']['name'], $_FILES['file']['type'], $fp, $sic['comment']);
2106 usePreparedInsertBlade
2107 (
2108 'FileLink',
2109 array
2110 (
2111 'file_id' => lastInsertID(),
2112 'entity_type' => $realm,
2113 'entity_id' => getBypassValue(),
2114 )
2115 );
2116 return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($_FILES['file']['name'])));
2117 }
2118
2119 $msgcode['linkFileToEntity']['OK'] = 71;
2120 function linkFileToEntity ()
2121 {
2122 assertUIntArg ('file_id');
2123 global $pageno, $etype_by_pageno, $sic;
2124 if (!isset ($etype_by_pageno[$pageno]))
2125 throw new RackTablesError ('key not found in etype_by_pageno', RackTablesError::INTERNAL);
2126
2127 $fi = spotEntity ('file', $sic['file_id']);
2128 usePreparedInsertBlade
2129 (
2130 'FileLink',
2131 array
2132 (
2133 'file_id' => $sic['file_id'],
2134 'entity_type' => $etype_by_pageno[$pageno],
2135 'entity_id' => getBypassValue(),
2136 )
2137 );
2138 return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($fi['name'])));
2139 }
2140
2141 $msgcode['replaceFile']['OK'] = 7;
2142 $msgcode['replaceFile']['ERR2'] = 207;
2143 $msgcode['replaceFile']['ERR3'] = 109;
2144 function replaceFile ()
2145 {
2146 global $sic;
2147
2148 // Make sure the file can be uploaded
2149 if (get_cfg_var('file_uploads') != 1)
2150 throw new RackTablesError ('file uploads not allowed, change "file_uploads" parameter in php.ini', RackTablesError::MISCONFIGURED);
2151 $shortInfo = spotEntity ('file', $sic['file_id']);
2152
2153 $fp = fopen($_FILES['file']['tmp_name'], 'rb');
2154 if ($fp === FALSE)
2155 return buildRedirectURL (__FUNCTION__, 'ERR2');
2156 if (FALSE === commitReplaceFile ($sic['file_id'], $fp))
2157 return buildRedirectURL (__FUNCTION__, 'ERR3');
2158
2159 usePreparedExecuteBlade
2160 (
2161 'UPDATE File SET thumbnail = NULL WHERE id = ?',
2162 $sic['file_id']
2163 );
2164
2165 return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2166 }
2167
2168 $msgcode['unlinkFile']['OK'] = 72;
2169 $msgcode['unlinkFile']['ERR'] = 111;
2170 function unlinkFile ()
2171 {
2172 assertUIntArg ('link_id');
2173 return buildRedirectURL (__FUNCTION__, commitUnlinkFile ($_REQUEST['link_id']) === FALSE ? 'ERR' : 'OK');
2174 }
2175
2176 $msgcode['deleteFile']['OK'] = 6;
2177 function deleteFile ()
2178 {
2179 assertUIntArg ('file_id');
2180 $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
2181 commitDeleteFile ($_REQUEST['file_id']);
2182 return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2183 }
2184
2185 $msgcode['updateFileText']['OK'] = 7;
2186 $msgcode['updateFileText']['ERR1'] = 179;
2187 $msgcode['updateFileText']['ERR2'] = 155;
2188 function updateFileText ()
2189 {
2190 assertStringArg ('mtime_copy');
2191 assertStringArg ('file_text', TRUE); // it's Ok to save empty
2192 $shortInfo = spotEntity ('file', $_REQUEST['file_id']);
2193 if ($shortInfo['mtime'] != $_REQUEST['mtime_copy'])
2194 return buildRedirectURL (__FUNCTION__, 'ERR1');
2195 global $sic;
2196 if (FALSE === commitReplaceFile ($sic['file_id'], $sic['file_text']))
2197 return buildRedirectURL (__FUNCTION__, 'ERR2');
2198 return buildRedirectURL (__FUNCTION__, 'OK', array (htmlspecialchars ($shortInfo['name'])));
2199 }
2200
2201 $msgcode['addPortInterfaceCompat']['OK'] = 48;
2202 $msgcode['addPortInterfaceCompat']['ERR'] = 110;
2203 function addPortInterfaceCompat ()
2204 {
2205 assertUIntArg ('iif_id');
2206 assertUIntArg ('oif_id');
2207 if (commitSupplementPIC ($_REQUEST['iif_id'], $_REQUEST['oif_id']))
2208 return buildRedirectURL (__FUNCTION__, 'OK');
2209 return buildRedirectURL (__FUNCTION__, 'ERR');
2210 }
2211
2212 $ifcompatpack = array
2213 (
2214 '1000cwdm80' => array (1209, 1210, 1211, 1212, 1213, 1214, 1215, 1216),
2215 '1000dwdm80' => array // ITU channels 20~61
2216 (
2217 1217, 1218, 1219, 1220, 1221, 1222, 1223, 1224, 1225, 1226,
2218 1227, 1228, 1229, 1230, 1231, 1232, 1233, 1234, 1235, 1236,
2219 1237, 1238, 1239, 1240, 1241, 1242, 1243, 1244, 1245, 1246,
2220 1247, 1248, 1249, 1250, 1251, 1252, 1253, 1254, 1255, 1256,
2221 1257, 1258
2222 ),
2223 '10000dwdm80' => array // same channels for 10GE
2224 (
2225 1259, 1260, 1261, 1262, 1263, 1264, 1265, 1266, 1267, 1268,
2226 1269, 1270, 1271, 1272, 1273, 1274, 1275, 1276, 1277, 1278,
2227 1279, 1280, 1281, 1282, 1283, 1284, 1285, 1286, 1287, 1288,
2228 1289, 1290, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298,
2229 1299, 1300
2230 ),
2231 );
2232
2233 $msgcode['addPortInterfaceCompatPack']['OK'] = 44;
2234 function addPortInterfaceCompatPack ()
2235 {
2236 genericAssertion ('standard', 'enum/wdmstd');
2237 genericAssertion ('iif_id', 'iif');
2238 global $ifcompatpack;
2239 $ngood = $nbad = 0;
2240 foreach ($ifcompatpack[$_REQUEST['standard']] as $oif_id)
2241 if (commitSupplementPIC ($_REQUEST['iif_id'], $oif_id))
2242 $ngood++;
2243 else
2244 $nbad++;
2245 return buildRedirectURL (__FUNCTION__, 'OK', array ($nbad, $ngood));
2246 }
2247
2248 $msgcode['delPortInterfaceCompatPack']['OK'] = 44;
2249 $msgcode['delPortInterfaceCompatPack']['ERR'] = 123;
2250 function delPortInterfaceCompatPack ()
2251 {
2252 assertStringArg ('standard');
2253 assertUIntArg ('iif_id');
2254 global $ifcompatpack, $sic;
2255 if (!array_key_exists ($sic['standard'], $ifcompatpack) or !array_key_exists ($sic['iif_id'], getPortIIFOptions()))
2256 return buildRedirectURL (__FUNCTION__, 'ERR');
2257 $ngood = $nbad = 0;
2258 foreach ($ifcompatpack[$sic['standard']] as $oif_id)
2259 if (usePreparedDeleteBlade ('PortInterfaceCompat', array ('iif_id' => $sic['iif_id'], 'oif_id' => $oif_id)))
2260 $ngood++;
2261 else
2262 $nbad++;
2263 return buildRedirectURL (__FUNCTION__, 'OK', array ($nbad, $ngood));
2264 }
2265
2266 $msgcode['add8021QOrder']['OK'] = 48;
2267 $msgcode['add8021QOrder']['ERR'] = 110;
2268 function add8021QOrder ()
2269 {
2270 assertUIntArg ('vdom_id');
2271 assertUIntArg ('object_id');
2272 assertUIntArg ('vst_id');
2273 global $sic;
2274 $result = usePreparedExecuteBlade
2275 (
2276 'INSERT INTO VLANSwitch (domain_id, object_id, template_id, last_change, out_of_sync) ' .
2277 'VALUES (?, ?, ?, NOW(), "yes")',
2278 array ($sic['vdom_id'], $sic['object_id'], $sic['vst_id'])
2279 );
2280 return buildRedirectURL (__FUNCTION__, $result !== FALSE ? 'OK' : 'ERR');
2281 }
2282
2283 $msgcode['del8021QOrder']['OK'] = 49;
2284 $msgcode['del8021QOrder']['ERR'] = 111;
2285 function del8021QOrder ()
2286 {
2287 assertUIntArg ('object_id');
2288 assertUIntArg ('vdom_id');
2289 assertUIntArg ('vst_id');
2290 global $sic;
2291 $result = usePreparedDeleteBlade ('VLANSwitch', array ('object_id' => $sic['object_id']));
2292 $focus_hints = array
2293 (
2294 'prev_objid' => $_REQUEST['object_id'],
2295 'prev_vstid' => $_REQUEST['vst_id'],
2296 'prev_vdid' => $_REQUEST['vdom_id'],
2297 );
2298 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR', array(), NULL, NULL, $focus_hints);
2299 }
2300
2301 $msgcode['delVLANDescription']['OK'] = 49;
2302 $msgcode['delVLANDescription']['ERR1'] = 105;
2303 $msgcode['delVLANDescription']['ERR2'] = 111;
2304 function delVLANDescription ()
2305 {
2306 assertUIntArg ('vlan_id');
2307 global $sic;
2308 if ($sic['vlan_id'] == VLAN_DFL_ID)
2309 return buildRedirectURL (__FUNCTION__, 'ERR1');
2310 $result = commitReduceVLANDescription ($sic['vdom_id'], $sic['vlan_id']);
2311 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR2');
2312 }
2313
2314 $msgcode['updVLANDescription']['OK'] = 51;
2315 $msgcode['updVLANDescription']['ERR1'] = 105;
2316 function updVLANDescription ()
2317 {
2318 assertUIntArg ('vlan_id');
2319 assertStringArg ('vlan_type');
2320 assertStringArg ('vlan_descr', TRUE);
2321 global $sic;
2322 if ($sic['vlan_id'] == VLAN_DFL_ID)
2323 return buildRedirectURL (__FUNCTION__, 'ERR1');
2324 usePreparedUpdateBlade
2325 (
2326 'VLANDescription',
2327 array
2328 (
2329 'vlan_descr' => !mb_strlen ($sic['vlan_descr']) ? NULL : $sic['vlan_descr'],
2330 'vlan_type' => $sic['vlan_type'],
2331 ),
2332 array
2333 (
2334 'domain_id' => $sic['vdom_id'],
2335 'vlan_id' => $sic['vlan_id'],
2336 )
2337 );
2338 return buildRedirectURL (__FUNCTION__, 'OK');
2339 }
2340
2341 $msgcode['createVLANDomain']['OK'] = 48;
2342 $msgcode['createVLANDomain']['ERR'] = 110;
2343 function createVLANDomain ()
2344 {
2345 assertStringArg ('vdom_descr');
2346 global $sic;
2347 $result = usePreparedInsertBlade
2348 (
2349 'VLANDomain',
2350 array
2351 (
2352 'description' => $sic['vdom_descr'],
2353 )
2354 );
2355 $result = $result and usePreparedInsertBlade
2356 (
2357 'VLANDescription',
2358 array
2359 (
2360 'domain_id' => lastInsertID(),
2361 'vlan_id' => VLAN_DFL_ID,
2362 'vlan_type' => 'compulsory',
2363 'vlan_descr' => 'default',
2364 )
2365 );
2366 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2367 }
2368
2369 $msgcode['destroyVLANDomain']['OK'] = 49;
2370 $msgcode['destroyVLANDomain']['ERR'] = 111;
2371 function destroyVLANDomain ()
2372 {
2373 assertUIntArg ('vdom_id');
2374 global $sic;
2375 $result = FALSE !== usePreparedDeleteBlade ('VLANDomain', array ('id' => $sic['vdom_id']));
2376 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2377 }
2378
2379 $msgcode['save8021QPorts']['OK1'] = 63;
2380 $msgcode['save8021QPorts']['OK2'] = 41;
2381 $msgcode['save8021QPorts']['ERR2'] = 109;
2382 function save8021QPorts ()
2383 {
2384 global $sic, $dbxlink;
2385 assertUIntArg ('mutex_rev', TRUE); // counts from 0
2386 assertStringArg ('form_mode');
2387 if ($sic['form_mode'] != 'save' and $sic['form_mode'] != 'duplicate')
2388 throw new InvalidRequestArgException ('form_mode', $sic['form_mode']);
2389 $extra = array();
2390 $dbxlink->beginTransaction();
2391 try
2392 {
2393 if (NULL === $vswitch = getVLANSwitchInfo ($sic['object_id'], 'FOR UPDATE'))
2394 throw new InvalidArgException ('object_id', $object_id, 'VLAN domain is not set for this object');
2395 if ($vswitch['mutex_rev'] != $sic['mutex_rev'])
2396 throw new InvalidRequestArgException ('mutex_rev', $sic['mutex_rev'], 'expired form data');
2397 $after = $before = apply8021QOrder ($vswitch['template_id'], getStored8021QConfig ($sic['object_id'], 'desired'));
2398 $changes = array();
2399 switch ($sic['form_mode'])
2400 {
2401 case 'save':
2402 assertUIntArg ('nports');
2403 if ($sic['nports'] == 1)
2404 {
2405 assertStringArg ('pn_0');
2406 $extra = array ('port_name' => $sic['pn_0']);
2407 }
2408 for ($i = 0; $i < $sic['nports']; $i++)
2409 {
2410 assertStringArg ('pn_' . $i);
2411 assertStringArg ('pm_' . $i);
2412 // An access port only generates form input for its native VLAN,
2413 // which we derive allowed VLAN list from.
2414 $native = isset ($sic['pnv_' . $i]) ? $sic['pnv_' . $i] : 0;
2415 switch ($sic["pm_${i}"])
2416 {
2417 case 'trunk':
2418 # assertArrayArg ('pav_' . $i);
2419 $allowed = isset ($sic['pav_' . $i]) ? $sic['pav_' . $i] : array();
2420 break;
2421 case 'access':
2422 if ($native == 'same')
2423 continue 2;
2424 assertUIntArg ('pnv_' . $i);
2425 $allowed = array ($native);
2426 break;
2427 default:
2428 throw new InvalidRequestArgException ("pm_${i}", $_REQUEST["pm_${i}"], 'unknown port mode');
2429 }
2430 $changes[$sic['pn_' . $i]] = array
2431 (
2432 'mode' => $sic['pm_' . $i],
2433 'allowed' => $allowed,
2434 'native' => $native,
2435 );
2436 }
2437 break;
2438 case 'duplicate':
2439 assertStringArg ('from_port');
2440 # assertArrayArg ('to_ports');
2441 if (!array_key_exists ($sic['from_port'], $before))
2442 throw new InvalidArgException ('from_port', $sic['from_port'], 'this port does not exist');
2443 foreach ($sic['to_ports'] as $tpn)
2444 if (!array_key_exists ($tpn, $before))
2445 throw new InvalidArgException ('to_ports[]', $tpn, 'this port does not exist');
2446 elseif ($tpn != $sic['from_port'])
2447 $changes[$tpn] = $before[$sic['from_port']];
2448 break;
2449 }
2450 $domain_vlanlist = getDomainVLANs ($vswitch['domain_id']);
2451 $changes = filter8021QChangeRequests
2452 (
2453 $domain_vlanlist,
2454 $before,
2455 apply8021QOrder ($vswitch['template_id'], $changes)
2456 );
2457 $changes = authorize8021QChangeRequests ($before, $changes);
2458 foreach ($changes as $port_name => $port)
2459 $after[$port_name] = $port;
2460 $new_uplinks = filter8021QChangeRequests ($domain_vlanlist, $after, produceUplinkPorts ($domain_vlanlist, $after));
2461 $npulled = replace8021QPorts ('desired', $vswitch['object_id'], $before, $changes);
2462 $nsaved_uplinks = replace8021QPorts ('desired', $vswitch['object_id'], $before, $new_uplinks);
2463 }
2464 catch (Exception $e)
2465 {
2466 $dbxlink->rollBack();
2467 return buildRedirectURL (__FUNCTION__, 'ERR2', array(), NULL, NULL, $extra);
2468 }
2469 if ($npulled + $nsaved_uplinks)
2470 $result = usePreparedExecuteBlade
2471 (
2472 'UPDATE VLANSwitch SET mutex_rev=mutex_rev+1, last_change=NOW(), out_of_sync="yes" WHERE object_id=?',
2473 array ($sic['object_id'])
2474 );
2475 $dbxlink->commit();
2476 $log = oneLiner (63, array ($npulled + $nsaved_uplinks));
2477 if ($nsaved_uplinks)
2478 {
2479 initiateUplinksReverb ($vswitch['object_id'], $new_uplinks);
2480 $log = mergeLogs ($log, oneLiner (41));
2481 }
2482 if ($npulled + $nsaved_uplinks > 0 and getConfigVar ('8021Q_INSTANT_DEPLOY') == 'yes')
2483 {
2484 try
2485 {
2486 if (FALSE === $done = exec8021QDeploy ($sic['object_id'], TRUE))
2487 $log = mergeLogs ($log, oneLiner (191));
2488 else
2489 $log = mergeLogs ($log, oneLiner (63, array ($done)));
2490 }
2491 catch (Exception $e)
2492 {
2493 $log = mergeLogs ($log, oneLiner (109));
2494 }
2495 }
2496 return buildWideRedirectURL ($log, NULL, NULL, $extra);
2497 }
2498
2499 $msgcode['bindVLANtoIPv4']['OK'] = 48;
2500 $msgcode['bindVLANtoIPv4']['ERR'] = 110;
2501 function bindVLANtoIPv4 ()
2502 {
2503 assertUIntArg ('id'); // network id
2504 global $sic;
2505 $result = commitSupplementVLANIPv4 ($sic['vlan_ck'], $sic['id']);
2506 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2507 }
2508
2509 $msgcode['bindVLANtoIPv6']['OK'] = 48;
2510 $msgcode['bindVLANtoIPv6']['ERR'] = 110;
2511 function bindVLANtoIPv6 ()
2512 {
2513 assertUIntArg ('id'); // network id
2514 global $sic;
2515 $result = commitSupplementVLANIPv6 ($sic['vlan_ck'], $_REQUEST['id']);
2516 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2517 }
2518
2519 $msgcode['unbindVLANfromIPv4']['OK'] = 49;
2520 $msgcode['unbindVLANfromIPv4']['ERR'] = 111;
2521 function unbindVLANfromIPv4 ()
2522 {
2523 assertUIntArg ('id'); // network id
2524 global $sic;
2525 $result = commitReduceVLANIPv4 ($sic['vlan_ck'], $sic['id']);
2526 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2527 }
2528
2529 $msgcode['unbindVLANfromIPv6']['OK'] = 49;
2530 $msgcode['unbindVLANfromIPv6']['ERR'] = 111;
2531 function unbindVLANfromIPv6 ()
2532 {
2533 assertUIntArg ('id'); // network id
2534 global $sic;
2535 $result = commitReduceVLANIPv6 ($sic['vlan_ck'], $sic['id']);
2536 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2537 }
2538
2539 $msgcode['process8021QSyncRequest']['OK'] = 63;
2540 $msgcode['process8021QSyncRequest']['ERR'] = 191;
2541 function process8021QSyncRequest ()
2542 {
2543 // behave depending on current operation: exec8021QPull or exec8021QPush
2544 global $sic, $op;
2545 if (FALSE === $done = exec8021QDeploy ($sic['object_id'], $op == 'exec8021QPush'))
2546 return buildRedirectURL (__FUNCTION__, 'ERR');
2547 return buildRedirectURL (__FUNCTION__, 'OK', array ($done));
2548 }
2549
2550 $msgcode['process8021QRecalcRequest']['CHANGED'] = 87;
2551 $msgcode['process8021QRecalcRequest']['NO_CHANGES'] = 300;
2552 $msgcode['process8021QRecalcRequest']['ERR'] = 157;
2553 function process8021QRecalcRequest ()
2554 {
2555 global $sic;
2556 if (! permitted (NULL, NULL, NULL, array (array ('tag' => '$op_recalc8021Q'))))
2557 return buildRedirectURL (__FUNCTION__, 'ERR');
2558 $counters = recalc8021QPorts ($sic['object_id']);
2559 if ($counters['ports'])
2560 return buildRedirectURL (__FUNCTION__, 'CHANGED', array ($counters['ports'], $counters['switches']));
2561 else
2562 return buildRedirectURL (__FUNCTION__, 'NO_CHANGES', array ('No changes were made'));
2563 }
2564
2565 $msgcode['resolve8021QConflicts']['OK'] = 63;
2566 $msgcode['resolve8021QConflicts']['ERR1'] = 179;
2567 $msgcode['resolve8021QConflicts']['ERR2'] = 109;
2568 function resolve8021QConflicts ()
2569 {
2570 global $sic, $dbxlink;
2571 assertUIntArg ('mutex_rev', TRUE); // counts from 0
2572 assertUIntArg ('nrows');
2573 // Divide submitted radio buttons into 3 groups:
2574 // left (saved version wins)
2575 // asis (ignore)
2576 // right (running version wins)
2577 $F = array();
2578 for ($i = 0; $i < $sic['nrows']; $i++)
2579 {
2580 if (!array_key_exists ("i_${i}", $sic))
2581 continue;
2582 // let's hope other inputs are in place
2583 switch ($sic["i_${i}"])
2584 {
2585 case 'left':
2586 case 'right':
2587 $F[$sic["pn_${i}"]] = array
2588 (
2589 'mode' => $sic["rm_${i}"],
2590 'allowed' => $sic["ra_${i}"],
2591 'native' => $sic["rn_${i}"],
2592 'decision' => $sic["i_${i}"],
2593 );
2594 break;
2595 default:
2596 // don't care
2597 }
2598 }
2599 $dbxlink->beginTransaction();
2600 try
2601 {
2602 if (NULL === $vswitch = getVLANSwitchInfo ($sic['object_id'], 'FOR UPDATE'))
2603 throw new InvalidArgException ('object_id', $sic['object_id'], 'VLAN domain is not set for this object');
2604 if ($vswitch['mutex_rev'] != $sic['mutex_rev'])
2605 throw new InvalidRequestArgException ('mutex_rev', $sic['mutex_rev'], 'expired form (table data has changed)');
2606 $D = getStored8021QConfig ($vswitch['object_id'], 'desired');
2607 $C = getStored8021QConfig ($vswitch['object_id'], 'cached');
2608 $R = getRunning8021QConfig ($vswitch['object_id']);
2609 $plan = get8021QSyncOptions ($vswitch, $D, $C, $R['portdata']);
2610 $ndone = 0;
2611 foreach ($F as $port_name => $port)
2612 {
2613 if (!array_key_exists ($port_name, $plan))
2614 continue;
2615 elseif ($plan[$port_name]['status'] == 'merge_conflict')
2616 {
2617 // for R neither mutex nor revisions can be emulated, but revision change can be
2618 if (!same8021QConfigs ($port, $R['portdata'][$port_name]))
2619 throw new InvalidRequestArgException ("port ${port_name}", '(hidden)', 'expired form (switch data has changed)');
2620 if ($port['decision'] == 'right') // D wins, frame R by writing value of R to C
2621 $ndone += upd8021QPort ('cached', $vswitch['object_id'], $port_name, $port);
2622 elseif ($port['decision'] == 'left') // R wins, cross D up
2623 $ndone += upd8021QPort ('cached', $vswitch['object_id'], $port_name, $D[$port_name]);
2624 // otherwise there was no decision made
2625 }
2626 elseif
2627 (
2628 $plan[$port_name]['status'] == 'delete_conflict' or
2629 $plan[$port_name]['status'] == 'martian_conflict'
2630 )
2631 {
2632 if ($port['decision'] == 'left') // confirm deletion of local copy
2633 $ndone += del8021QPort ($vswitch['object_id'], $port_name);
2634 }
2635 // otherwise ignore a decision, which doesn't address a conflict
2636 }
2637 }
2638 catch (InvalidRequestArgException $e)
2639 {
2640 $dbxlink->rollBack();
2641 return buildRedirectURL (__FUNCTION__, 'ERR1');
2642 }
2643 catch (Exception $e)
2644 {
2645 $dbxlink->rollBack();
2646 return buildRedirectURL (__FUNCTION__, 'ERR2');
2647 }
2648 $dbxlink->commit();
2649 return buildRedirectURL (__FUNCTION__, 'OK', array ($ndone));
2650 }
2651
2652 $msgcode['addVLANSwitchTemplate']['OK'] = 48;
2653 $msgcode['addVLANSwitchTemplate']['ERR'] = 110;
2654 function addVLANSwitchTemplate()
2655 {
2656 assertStringArg ('vst_descr');
2657 global $sic;
2658 $result = usePreparedInsertBlade
2659 (
2660 'VLANSwitchTemplate',
2661 array
2662 (
2663 'description' => $sic['vst_descr'],
2664 )
2665 );
2666 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2667 }
2668
2669 $msgcode['delVLANSwitchTemplate']['OK'] = 49;
2670 $msgcode['delVLANSwitchTemplate']['ERR'] = 111;
2671 function delVLANSwitchTemplate()
2672 {
2673 assertUIntArg ('vst_id');
2674 global $sic;
2675 $result = FALSE !== usePreparedDeleteBlade ('VLANSwitchTemplate', array ('id' => $sic['vst_id']));
2676 return buildRedirectURL (__FUNCTION__, $result ? 'OK' : 'ERR');
2677 }
2678
2679 $msgcode['cloneVST']['OK'] = 48;
2680 $msgcode['cloneVST']['ERR'] = 179;
2681 function cloneVST()
2682 {
2683 assertUIntArg ('mutex_rev', TRUE);
2684 assertUIntArg ('from_id');
2685 $src_vst = getVLANSwitchTemplate ($_REQUEST['from_id']);
2686 commitUpdateVSTRules (getBypassValue(), $_REQUEST['mutex_rev'], $src_vst['rules']);
2687 return buildRedirectURL (__FUNCTION__, 'OK');
2688 }
2689
2690 $msgcode['updVSTRule']['OK'] = 43;
2691 function updVSTRule()
2692 {
2693 // this is used for making throwing an invalid argument exception easier.
2694 function updVSTRule_get_named_param ($name, $haystack, &$last_used_name)
2695 {
2696 $last_used_name = $name;
2697 return isset ($haystack[$name]) ? $haystack[$name] : NULL;
2698 }
2699
2700 global $port_role_options, $sic;
2701 assertUIntArg ('mutex_rev', TRUE);
2702 genericAssertion ('template_json', 'json');
2703 $data = json_decode ($sic['template_json'], TRUE);
2704 $rule_no = 0;
2705 try
2706 {
2707 $last_field = '';
2708 foreach ($data as $rule)
2709 {
2710 $rule_no++;
2711 if
2712 (
2713 ! isInteger (updVSTRule_get_named_param ('rule_no', $rule, $last_field))
2714 or ! isPCRE (updVSTRule_get_named_param ('port_pcre', $rule, $last_field))
2715 or NULL === updVSTRule_get_named_param ('port_role', $rule, $last_field)
2716 or ! array_key_exists (updVSTRule_get_named_param ('port_role', $rule, $last_field), $port_role_options)
2717 or NULL === updVSTRule_get_named_param ('wrt_vlans', $rule, $last_field)
2718 or ! preg_match ('/^[ 0-9\-,]*$/', updVSTRule_get_named_param ('wrt_vlans', $rule, $last_field))
2719 or NULL === updVSTRule_get_named_param ('description', $rule, $last_field)
2720 )
2721 throw new InvalidRequestArgException ($last_field, $rule[$last_field], "rule #$rule_no");
2722 }
2723 commitUpdateVSTRules ($_REQUEST['vst_id'], $_REQUEST['mutex_rev'], $data);
2724 }
2725 catch (Exception $e)
2726 {
2727 // Every case, which is soft-processed in process.php, will have the working copy available for a retry.
2728 if ($e instanceof InvalidRequestArgException or $e instanceof RTDatabaseError)
2729 $_SESSION['vst_edited'] = $data;
2730 throw $e;
2731 }
2732 return buildRedirectURL (__FUNCTION__, 'OK');
2733 }
2734
2735 $msgcode['importDPData']['OK'] = 44;
2736 function importDPData()
2737 {
2738 global $sic;
2739 assertUIntArg ('nports');
2740 $nignored = $ndone = 0;
2741 $POIFC = getPortOIFCompat();
2742 for ($i = 0; $i < $sic['nports']; $i++)
2743 if (array_key_exists ("do_${i}", $sic))
2744 {
2745 assertUIntArg ("pid1_${i}");
2746 assertUIntArg ("pid2_${i}");
2747 $porta = getPortInfo ($_REQUEST["pid1_${i}"]);
2748 $portb = getPortInfo ($_REQUEST["pid2_${i}"]);
2749 if
2750 (
2751 $porta['linked'] or
2752 $portb['linked'] or
2753 ($porta['object_id'] != $sic['object_id'] and $portb['object_id'] != $sic['object_id'])
2754 )
2755 {
2756 $nignored++;
2757 continue;
2758 }
2759 foreach ($POIFC as $item)
2760 if ($item['type1'] == $porta['oif_id'] and $item['type2'] == $portb['oif_id'])
2761 {
2762 linkPorts ($_REQUEST["pid1_${i}"], $_REQUEST["pid2_${i}"]);
2763 $ndone++;
2764 continue 2; // next port
2765 }
2766 $nignored++;
2767 }
2768 return buildRedirectURL (__FUNCTION__, 'OK', array ($nignored, $ndone));
2769 }
2770
2771 $msgcode['addObjectlog']['OK'] = 0;
2772 function addObjectlog ()
2773 {
2774 assertStringArg ('logentry');
2775 global $remote_username, $sic;
2776 $oi = spotEntity ('object', $sic['object_id']);
2777 usePreparedExecuteBlade ('INSERT INTO ObjectLog SET object_id=?, user=?, date=NOW(), content=?', array ($sic['object_id'], $remote_username, $sic['logentry']));
2778 return buildRedirectURL (__FUNCTION__, 'OK', array ('Log entry for ' . mkA ($oi['dname'], 'object', $sic['object_id'], 'log') . " added by ${remote_username}"));
2779 }
2780
2781 function getOpspec()
2782 {
2783 global $pageno, $tabno, $op, $opspec_list;
2784 if (!array_key_exists ($pageno . '-' . $tabno . '-' . $op, $opspec_list))
2785 throw new RackTablesError ('key not found in opspec_list', RackTablesError::INTERNAL);
2786 $ret = $opspec_list[$pageno . '-' . $tabno . '-' . $op];
2787 if
2788 (
2789 !array_key_exists ('table', $ret)
2790 or !array_key_exists ('action', $ret)
2791 // add further checks here
2792 )
2793 throw new RackTablesError ('malformed array structure in opspec_list', RackTablesError::INTERNAL);
2794 return $ret;
2795 }
2796
2797 function tableHandler()
2798 {
2799 $opspec = getOpspec();
2800 global $sic;
2801 $columns = array();
2802 foreach (array ('arglist', 'set_arglist', 'where_arglist') as $listname)
2803 foreach ($opspec[$listname] as $argspec)
2804 {
2805 genericAssertion ($argspec['url_argname'], $argspec['assertion']);
2806 // "table_colname" is normally used for an override, if it is not
2807 // set, use the URL argument name
2808 $table_colname = array_key_exists ('table_colname', $argspec) ?
2809 $argspec['table_colname'] :
2810 $argspec['url_argname'];
2811 $arg_value = $sic[$argspec['url_argname']];
2812 if
2813 (
2814 ($argspec['assertion'] == 'uint0' and $arg_value == 0)
2815 or ($argspec['assertion'] == 'string0' and $arg_value == '')
2816 )
2817 switch (TRUE)
2818 {
2819 case !array_key_exists ('if_empty', $argspec): // no action requested
2820 break;
2821 case $argspec['if_empty'] == 'NULL':
2822 $arg_value = NULL;
2823 break;
2824 default:
2825 throw new InvalidArgException ('opspec', '(malformed array structure)', '"if_empty" not recognized');
2826 }
2827 $columns[$listname][$table_colname] = $arg_value;
2828 }
2829 switch ($opspec['action'])
2830 {
2831 case 'INSERT':
2832 $retcode = TRUE === usePreparedInsertBlade ($opspec['table'], $columns['arglist']) ? 48 : 110;
2833 break;
2834 case 'DELETE':
2835 $conjunction = array_key_exists ('conjunction', $opspec) ? $opspec['conjunction'] : 'AND';
2836 $retcode = FALSE !== usePreparedDeleteBlade ($opspec['table'], $columns['arglist'], $conjunction) ? 49 : 111;
2837 break;
2838 case 'UPDATE':
2839 usePreparedUpdateBlade
2840 (
2841 $opspec['table'],
2842 $columns['set_arglist'],
2843 $columns['where_arglist'],
2844 array_key_exists ('conjunction', $opspec) ? $opspec['conjunction'] : 'AND'
2845 );
2846 $retcode = 51;
2847 break;
2848 default:
2849 throw new InvalidArgException ('opspec/action', $opspec['action']);
2850 }
2851 return buildWideRedirectURL (oneLiner ($retcode));
2852 }
2853
2854 ?>