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