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