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