1 <?php
3 class faiPartitionTable extends plugin
4 {
5 /* attribute list for save action */
6 var $ignore_account = TRUE;
7 var $attributes = array("cn","description");
8 var $objectclasses = array("top","FAIclass","FAIpartitionTable");
10 var $subAttributes = array("cn","description");
11 var $subPartAttributes = array("cn","FAIpartitionNr","FAIpartitionSize","FAImountPoint","FAIfsType","FAIpartitionType","FAImountOptions","FAIfsOptions","FAIpartitionFlags","description");
13 var $sub64coded = array();
14 var $subBinary = array();
16 /* Specific attributes */
17 var $cn = ""; // The class name for this object
18 var $description = ""; // The description for this set of partitions
19 var $disks = array(); // All defined Disks
20 var $is_dialog = false; // specifies which buttons will be shown to save or abort
22 var $FAIstate = "";
23 var $ui;
25 var $view_logged = FALSE;
27 function faiPartitionTable (&$config, $dn= NULL)
28 {
29 /* Load Attributes */
30 plugin::plugin ($config, $dn);
32 /* If "dn==new" we try to create a new entry
33 * Else we must read all objects from ldap which belong to this entry.
34 */
35 $this->ui = get_userinfo();
36 if($dn != "new"){
37 $this->dn =$dn;
39 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
40 */
41 $res = FAI::get_leaf_objects($this->dn, $this->cn, "FAIpartitionDisk", get_ou('faiPartitionRDN'));
42 foreach($res as $obj){
43 $objects = array();
44 $objects['description'] = "";
45 $objects['status'] = "edited";
46 $objects['dn'] = $obj['dn'];
47 $objects = $this->get_object_attributes($objects,$this->subAttributes);
48 $this->disks[$objects['cn']] = $objects;
49 $this->disks[$objects['cn']]['partitions'] = array();
50 }
52 /* read all partitions for each disk
53 */
54 foreach($this->disks as $name => $disk){
56 $res = FAI::get_leaf_objects($disk['dn'], $name, "FAIpartitionEntry", "cn=".$this->cn.",".get_ou('faiPartitionRDN'));
57 foreach($res as $obj){
58 $objects = array();
59 $objects['status'] = "edited";
60 $objects['dn'] = $obj['dn'];
61 $objects = $this->get_object_attributes($objects,$this->subPartAttributes);
62 unset($objects['dn']);;
63 $this->disks[$name]['partitions'][$objects['FAIpartitionNr']] = $objects;
64 }
65 }
66 }
68 $this->is_new = FALSE;
69 if($this->dn == "new"){
70 $this->is_new =TRUE;
71 }
72 ksort($this->disks);
73 }
76 function acl_base_for_current_object($dn)
77 {
78 if($dn == "new" || $dn == ""){
79 if($this->dn == "new"){
80 $dn= $this->parent->parent->acl_base;
81 }else{
82 $dn = $this->dn;
83 }
84 }
85 return($dn);
86 }
89 function execute()
90 {
91 /* Call parent execute */
92 plugin::execute();
94 if($this->is_account && !$this->view_logged){
95 $this->view_logged = TRUE;
96 new log("view","fai/".get_class($this),$this->dn);
97 }
99 /* Fill templating stuff */
100 $smarty= get_smarty();
101 $display= "";
103 /* Add Disk to this Partitionset
104 * This code adds a new HDD to the disks
105 * A new Dialog will be opened
106 */
107 if(isset($_POST['AddDisk']) && !preg_match("/freeze/i",$this->FAIstate)){
108 $usedDiskNames =array();
109 foreach($this->disks as $key=>$disk){
110 $usedDiskNames[]= $key;
111 }
112 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames);
113 $this->dialog->set_acl_base($this->acl_base_for_current_object($this->dn));
114 $this->dialog->set_acl_category("fai");
115 $this->dialog->FAIstate = $this->FAIstate;
116 $this->is_dialog = true;
117 }
119 /* Edit disk.
120 * Open dialog which allows us to edit the selected entry
121 */
123 if($this->dn != "new"){
124 set_object_info($this->dn);
125 }
127 if((isset($_POST['EditDisk']))&&(isset($_POST['disks']))){
128 $usedDiskNames =array();
129 $Udisk = $_POST['disks'][0];
130 if(isset($this->disks[$Udisk])){
132 foreach($this->disks as $key=>$disk){
133 if($key != $Udisk){
134 $usedDiskNames[]= $key;
135 }
136 }
138 /* Set object info string, which will be displayed in plugin info line */
139 if(isset($this->disks[$Udisk]['dn'])){
140 set_object_info($this->disks[$Udisk]['dn']);
141 $dn = $this->disks[$Udisk]['dn'];
142 }else{
143 set_object_info("");
144 $dn = "new";
145 }
147 $this->dialog = new faiPartitionTableEntry($this->config,$this->dn,$usedDiskNames,$this->disks[$Udisk]);
148 $this->dialog->set_acl_base($this->acl_base_for_current_object($dn));
149 $this->dialog->set_acl_category("fai");
150 $this->dialog->FAIstate = $this->FAIstate;
152 $this->is_dialog = true;
153 }
154 }
156 /* Edit aborted, close dialog, without saving anything
157 */
158 if(isset($_POST['CancelDisk'])){
159 unset($this->dialog);
160 $this->dialog = FALSE;
161 $this->is_dialog=false;
162 }
164 /* Dialog saved
165 * Save given data from Dialog, if no error is occurred
166 */
167 if(isset($_POST['SaveDisk'])){
169 if (!preg_match("/freeze/i", $this->FAIstate)){
170 $this->dialog->save_object();
171 if(count($this->dialog->check())){
172 foreach($this->dialog->check() as $msg){
173 msg_dialog::display(_("Error"), $msg, ERROR_DIALOG);
174 }
175 }else{
176 $disk = $this->dialog->save();
177 if(isset($disk['rename'])){
178 if($this->disks[$disk['rename']['from']]['status']=="edited"){
179 $this->disks[$disk['rename']['from']]['status']="delete";
180 }else{
181 unset($this->disks[$disk['rename']['from']]);
182 }
184 foreach($disk['partitions'] as $key => $val){
185 if($disk['partitions'][$key]['status']!="delete"){
186 $disk['partitions'][$key]['status']= "new";
187 }
188 }
190 $disk['status']="new";
191 $disk['cn']= $disk['rename']['to'];
192 }
194 $this->disks[$disk['cn']]=$disk;
195 unset($this->dialog);
196 $this->dialog = FALSE;
197 $this->is_dialog=false;
198 ksort($this->disks);
199 }
200 }else{
201 $this->dialog = FALSE;
202 $this->is_dialog=false;
203 }
204 }
206 /* Delete selected disk drive from list
207 * Assign delete status for all its partitions
208 */
209 if((isset($_POST['DelDisk']))&&(!empty($_POST['disks']))){
210 if (!preg_match("/freeze/i", $this->FAIstate)){
211 foreach($_POST['disks'] as $disk) {
213 if(isset($this->disks[$disk])){
214 if($this->disks[$disk]['status']=="edited"){
215 $this->disks[$disk."-delete"]=$this->disks[$disk];
216 unset($this->disks[$disk]);
217 $disk = $disk."-delete";
218 $this->disks[$disk]['status']="delete";
219 foreach($this->disks[$disk]['partitions'] as $name => $value ){
220 if($value['status']=="edited"){
221 $this->disks[$disk]['partitions'][$name]['status']="delete";
222 }else{
223 unset($this->disks[$disk]['partitions'][$name]);
224 }
225 }
226 }else{
227 unset($this->disks[$disk]);
228 }
229 }
230 }
231 }
232 }
234 /* Display dialog if one is defined
235 */
236 if(is_object($this->dialog)){
237 $this->dialog->save_object();
238 return($this->dialog->execute());
239 }
241 /* Assign all attributes to smarty engine
242 */
243 foreach($this->attributes as $attrs){
244 $smarty->assign($attrs,$this->$attrs);
245 if($this->$attrs){
246 $smarty->assign($attrs."CHK"," ");
247 }else{
248 $smarty->assign($attrs."CHK"," disabled ");
249 }
250 }
252 $dn = $this->acl_base_for_current_object($this->dn);
253 $smarty->assign("sub_object_is_addable",
254 preg_match("/c/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
255 !preg_match("/freeze/",$this->FAIstate));
256 $smarty->assign("sub_object_is_removeable",
257 preg_match("/d/",$this->ui->get_permissions($dn,"fai/faiPartitionTableEntry")) &&
258 !preg_match("/freeze/",$this->FAIstate));
260 $tmp = $this->plInfo();
261 foreach($tmp['plProvidedAcls'] as $name => $translated){
262 $smarty->assign($name."ACL",$this->getacl($name,preg_match("/freeze/i",$this->FAIstate)));
263 }
264 $disks = $this->getDisks();
265 $smarty->assign("disks" ,$disks);
266 $display.= $smarty->fetch(get_template_path('faiPartitionTable.tpl', TRUE));
267 return($display);
268 }
270 function getDisks(){
271 /* Return all available disks for this partition table
272 * Return in listBox friendly array
273 */
274 $a_return = array();
275 foreach($this->disks as $key => $disk){
277 $dn = "new";
278 if(isset($obj['dn'])){
279 $dn = $obj['dn'];
280 }
281 $dn = $this->acl_base_for_current_object($dn);
282 $acl = $this->ui->get_permissions($dn,"fai/faiPartitionTableEntry");
283 if(preg_match("/(r|w)/",$acl)) {
285 if($disk['status'] != "delete"){
286 $cnt=0;
287 foreach($disk['partitions'] as $val){
288 if($val['status']!="delete"){
289 $cnt ++;
290 }
291 }
292 if(!empty($disk['description'])){
293 if($cnt == 1){
294 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition"), $cnt);
295 }else{
296 $a_return[$key]= $disk['cn']." [".$disk['description']."], ".sprintf(_("%s partition(s)"), $cnt);
297 }
298 }else{
299 if($cnt == 1){
300 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition"), $cnt);
301 }else{
302 $a_return[$key]= $disk['cn'].", ".sprintf(_("%s partition(s)"), $cnt);
303 }
304 }
305 }
306 }
307 }
308 return($a_return);
309 }
312 /* Delete me, and all my subtrees
313 */
314 function remove_from_parent()
315 {
316 $ldap = $this->config->get_ldap_link();
317 $ldap->cd ($this->dn);
319 $release = $this->parent->parent->fai_release;
320 $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i", $release, $this->dn);
322 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
323 new log("remove","fai/".get_class($this),$use_dn,$this->attributes);
324 foreach($this->disks as $disk){
325 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
326 $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i",$release, $disk_dn);
327 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
328 foreach($disk['partitions'] as $key => $partition){
329 $partition_dn= "FAIpartitionNr=".$partition['FAIpartitionNr'].",".$disk_dn;
330 $use_dn = preg_replace("/".preg_quote(FAI::get_release_dn($this->dn), '/')."/i", $release, $partition_dn);
331 FAI::prepare_to_save_FAI_object($use_dn,array(),true);
332 }
333 }
334 }
337 /* Save data to object
338 */
339 function save_object()
340 {
341 if (preg_match("/freeze/", $this->FAIstate)) return;
342 plugin::save_object();
343 foreach($this->attributes as $attrs){
344 if(isset($_POST[$attrs])){
345 $this->$attrs = $_POST[$attrs];
346 }
347 }
348 }
351 /* Check supplied data */
352 function check()
353 {
354 /* Call common method to give check the hook */
355 $message= plugin::check();
357 /* Ensure that we do not overwrite an allready existing entry
358 */
359 if($this->is_new){
360 $release = $this->parent->parent->fai_release;
361 $new_dn= 'cn='.$this->cn.",".get_ou('faiPartitionRDN').get_ou('faiBaseRDN').$release;
362 $res = faiManagement::check_class_name("FAIpartitionTable",$this->cn,$new_dn);
363 if(isset($res[$this->cn])){
364 $message[] = msgPool::duplicated(_("Name"));
365 }
366 }
368 if (preg_match("/^-/", $this->cn)) {
369 $message[] = sprintf(_("The specified classname '%s' is invalid. Classnames must not start with a dash."), $this->cn);
370 }
372 if($this->cn != preg_replace("/ /","",trim($this->cn))){
373 $message[] = msgPool::invalid(_("Name"),preg_replace("/ /","_",$this->cn),"/[^_]/");
374 }
376 return ($message);
377 }
380 /* Save to LDAP */
381 function save()
382 {
384 plugin::save();
385 /* Save current settings.
386 * 1 : We must save the partition table, with its description and cn
387 * 2 : Append Disk with cn and description.
388 * 3 : Save partitions for each disk
389 */
391 $ldap = $this->config->get_ldap_link();
393 FAI::prepare_to_save_FAI_object($this->dn,$this->attrs);
395 if($this->initially_was_account){
396 new log("modify","fai/".get_class($this),$this->dn,$this->attributes);
397 }else{
398 new log("create","fai/".get_class($this),$this->dn,$this->attributes);
399 }
401 /* Sort entries, because we must delete entries with status="delete" first */
402 $order = array();
403 foreach($this->disks as $key => $disk){
404 if($disk['status'] == "delete"){
405 $order[$key] = $disk;
406 }
407 }
408 foreach($this->disks as $key => $disk){
409 if($disk['status'] != "delete"){
410 $order[$key] = $disk;
411 }
412 }
414 /* Append all disks to ldap */
415 foreach($order as $cn=>$disk){
416 $disk_dn = "cn=".$disk['cn'].",".$this->dn;
417 $disk_attrs['cn'] = $disk['cn'];
418 $disk_attrs['description'] = $disk['description'];
420 if(empty($disk_attrs['description']) && $disk['status'] == "edited"){
421 $disk_attrs['description'] = array();
422 }
424 $disk_attrs['objectClass'] = array("top","FAIclass","FAIpartitionDisk");
426 if($disk['status']=="new"){
427 $ldap->cat($disk_dn,array("objectClass"));
428 if($ldap->count()){
429 $disk['status']="edited";
430 }
431 }
433 /* Tag object */
434 $ui= get_userinfo();
435 $this->tag_attrs($disk_attrs, $disk_dn, $ui->gosaUnitTag);
437 if($disk['status'] == "delete"){
438 FAI::prepare_to_save_FAI_object($disk_dn,array(),true);
439 $this->handle_post_events("remove");
440 }elseif($disk['status'] == "edited"){
441 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
442 $this->handle_post_events("modify");
443 }elseif($disk['status']=="new"){
444 FAI::prepare_to_save_FAI_object($disk_dn,$disk_attrs);
445 $this->handle_post_events("add");
446 }
448 if($disk['status']!="delete")
449 /* Add all partitions */
450 foreach($disk['partitions'] as $key => $partition){
451 $partition_attrs = array();
453 foreach($partition as $key => $value){
454 if(!empty($value)){
455 $partition_attrs[$key]=$value;
456 }else{
457 unset($partition_attrs[$key]);
458 }
459 }
461 $partition_dn= "FAIpartitionNr=".$partition_attrs['FAIpartitionNr'].",".$disk_dn;
462 $partition_attrs['objectClass']= array("top","FAIclass","FAIpartitionEntry");
463 $partition_attrs['cn']= $partition_attrs['FAIpartitionNr'];
465 unset($partition_attrs['status']);
466 unset($partition_attrs['old_cn']);
468 if($partition['status']=="new"){
469 $ldap->cat($partition_dn,array("objectClass"));
470 if($ldap->count()){
471 $partition['status']="edited";
472 }
473 }
475 if((!isset($partition['FAImountPoint']))||(empty($partition['FAImountPoint']))){
476 $partition_attrs['FAImountPoint']="swap";
477 }
479 /* Tag object */
480 $ui= get_userinfo();
481 $this->tag_attrs($partition_attrs, $partition_dn, $ui->gosaUnitTag);
483 if($partition['status'] == "delete"){
484 FAI::prepare_to_save_FAI_object($partition_dn,array(),true);
485 $this->handle_post_events("remove");
486 }elseif($partition['status'] == "edited"){
487 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
488 $this->handle_post_events("modify");
489 }elseif($partition['status']=="new"){
490 FAI::prepare_to_save_FAI_object($partition_dn,$partition_attrs);
491 $this->handle_post_events("add");
492 }
493 }
494 }
495 $this->handle_post_events("add");
496 }
499 function PrepareForCopyPaste($source)
500 {
501 plugin::PrepareForCopyPaste($source);
503 /* Read all leaf objects of this object (For FAIscript this would be FAIscriptEntry)
504 */
505 $res = FAI::get_leaf_objects($source['dn'], $source['cn'][0], "FAIpartitionDisk", get_ou('faiPartitionRDN'));
506 foreach($res as $obj){
507 $objects = array();
508 $objects['description'] = "";
509 $objects['status'] = "edited";
510 $objects['dn'] = $obj['dn'];
511 $objects = $this->get_object_attributes($objects,$this->subAttributes);
512 $this->disks[$objects['cn']] = $objects;
513 $this->disks[$objects['cn']]['partitions'] = array();
514 }
516 /* read all partitions for each disk
517 */
518 foreach($this->disks as $name => $disk){
519 $res = FAI::get_leaf_objects($disk['dn'], $name, "FAIpartitionEntry", "cn=".$source['cn'][0].",".get_ou('faiPartitionRDN'));
520 foreach($res as $obj){
521 $objects = array();
522 $objects['status'] = "edited";
523 $objects['dn'] = $obj['dn'];
524 $objects = $this->get_object_attributes($objects,$this->subPartAttributes);
525 unset($objects['dn']);;
526 $this->disks[$name]['partitions'][$objects['FAIpartitionNr']] = $objects;
527 }
528 }
529 ksort($this->disks);
530 }
533 /* Return plugin informations for acl handling */
534 static function plInfo()
535 {
536 return (array(
537 "plShortName" => _("Partition table"),
538 "plDescription" => _("FAI partition table"),
539 "plSelfModify" => FALSE,
540 "plDepends" => array(),
541 "plPriority" => 26,
542 "plSection" => array("administration"),
543 "plCategory" => array("fai"),
544 "plProvidedAcls" => array(
545 "cn" => _("Name")." ("._("Read only").")",
546 "description" => _("Description"))
547 ));
548 }
551 /*! \brief Used for copy & paste.
552 Returns a HTML input mask, which allows to change the cn of this entry.
553 @param Array Array containing current status && a HTML template.
554 */
555 function getCopyDialog()
556 {
557 $vars = array("cn");
558 $smarty = get_smarty();
559 $smarty->assign("cn", htmlentities($this->cn));
560 $str = $smarty->fetch(get_template_path("paste_generic.tpl",TRUE));
561 $ret = array();
562 $ret['string'] = $str;
563 $ret['status'] = "";
564 return($ret);
565 }
568 /*! \brief Used for copy & paste.
569 Some entries must be renamed to avaoid duplicate entries.
570 */
571 function saveCopyDialog()
572 {
573 if(isset($_POST['cn'])){
574 $this->cn = get_post('cn');
575 }
576 }
578 /* Reload some attributes */
579 function get_object_attributes($object,$attributes)
580 {
581 $ldap = $this->config->get_ldap_link();
582 $ldap->cd($this->config->current['BASE']);
583 $ldap->cat($object['dn'],$attributes);
584 $tmp = $ldap->fetch();
586 foreach($attributes as $attrs){
587 if(isset($tmp[$attrs][0])){
588 $var = $tmp[$attrs][0];
590 /* Check if we must decode some attributes */
591 if(in_array_ics($attrs,$this->sub64coded)){
592 $var = base64_decode($var);
593 }
595 /* check if this is a binary entry */
596 if(in_array_ics($attrs,$this->subBinary)){
597 $var = $ldap->get_attribute($object['dn'], $attrs,$r_array=0);
598 }
600 /* Fix slashes */
601 $var = addslashes($var);
602 $object[$attrs] = $var;
603 }
604 }
605 return($object);
606 }
608 }
610 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
611 ?>