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