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