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