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