Code

Added multi deletion for Partition Tables
[gosa.git] / include / class_ldap.inc
1 <?php
2 /*****************************************************************************
3   newldap.inc - version 1.0
4   Copyright (C) 2003 Alejandro Escanero Blanco <alex@ofmin.com>
5   Copyright (C) 2004 Cajus Pollmeier <pollmeier@gonicus.de>
7   Based in code of ldap.inc of
8   Copyright (C) 1998  Eric Kilfoil <eric@ipass.net>
9  *****************************************************************************/
11 define("ALREADY_EXISTING_ENTRY",-10001);
12 define("UNKNOWN_TOKEN_IN_LDIF_FILE",-10002);
13 define("NO_FILE_UPLOADED",10003);
16 define("INSERT_OK",10000);
20 class LDAP{
22   var $hascon   =false;
23   var $hasres   =false;
24   var $reconnect=false;
25   var $tls      = false;
26   var $basedn   ="";
27   var $cid;
28   var $error    = ""; // Any error messages to be returned can be put here
29   var $start    = 0; // 0 if we are fetching the first entry, otherwise 1
30   var $objectClasses = array(); // Information read from slapd.oc.conf
31   var $binddn   = "";
32   var $bindpw   = "";
33   var $hostname = "";
34   var $follow_referral = FALSE;
35   var $referrals= array();
37   function LDAP($binddn,$bindpw, $hostname, $follow_referral= FALSE, $tls= FALSE)
38   {
39     $this->follow_referral= $follow_referral;
40     $this->tls=$tls;
41     $this->binddn=$binddn;
42     $this->bindpw=$bindpw;
43     $this->hostname=$hostname;
44     $this->connect();
45   }
47   function connect()
48   {
49     $this->hascon=false;
50     $this->reconnect=false;
51     if ($this->cid= @ldap_connect($this->hostname)) {
52       @ldap_set_option($this->cid, LDAP_OPT_PROTOCOL_VERSION, 3);
53       if (function_exists("ldap_set_rebind_proc") && $this->follow_referral) {
54         @ldap_set_option($this->cid, LDAP_OPT_REFERRALS, 1);
55         @ldap_set_rebind_proc($this->cid, array(&$this, "rebind"));
56       }
57       if (function_exists("ldap_start_tls") && $this->tls){
58         @ldap_start_tls($this->cid);
59       }
61       $this->error = "No Error";
62       if ($bid = @ldap_bind($this->cid, $this->binddn, $this->bindpw)) {
63         $this->error = "Success";
64         $this->hascon=true;
65       } else {
66         if ($this->reconnect){
67           if ($this->error != "Success"){
68             $this->error = "Could not rebind to " . $this->binddn;
69           }
70         } else {
71           $this->error = "Could not bind to " . $this->binddn;
72         }
73       }
74     } else {
75       $this->error = "Could not connect to LDAP server";
76     }
77   }
79   function rebind($ldap, $referral)
80   {
81     $credentials= $this->get_credentials($referral);
82     if (@ldap_bind($ldap, $credentials['ADMIN'], $credentials['PASSWORD'])) {
83       $this->error = "Success";
84       $this->hascon=true;
85       $this->reconnect= true;
86       return (0);
87     } else {
88       $this->error = "Could not bind to " . $credentials['ADMIN'];
89       return NULL;
90     }
91   }
93   function reconnect()
94   {
95     if ($this->reconnect){
96       @ldap_unbind($this->cid);
97       $this->cid = NULL;
98     }
99   }
101   function unbind()
102   {
103     @ldap_unbind($this->cid);
104     $this->cid = NULL;
105   }
107   function disconnect()
108   {
109     if($this->hascon){
110       @ldap_close($this->cid);
111       $this->hascon=false;
112     }
113   }
115   function cd($dir)
116   {
117     if ($dir == "..")
118       $this->basedn = $this->getParentDir();
119     else
120       $this->basedn = $dir;
121   }
123   function getParentDir($basedn = "")
124   {
125     if ($basedn=="")
126       $basedn = $this->basedn;
127     return(ereg_replace("[^,]*[,]*[ ]*(.*)", "\\1", $basedn));
128   }
130   function search($filter, $attrs= array())
131   {
132     
133     if($this->hascon){
134       if ($this->reconnect) $this->connect();
135       $this->clearResult();
136       $this->sr = @ldap_search($this->cid, $this->basedn, $filter, $attrs);
137       $this->error = @ldap_error($this->cid);
138       $this->resetResult();
139       $this->hasres=true;
140       return($this->sr);
141     }else{
142       $this->error = "Could not connect to LDAP server";
143       return("");
144     }
145   }
147   function ls($filter = "(objectclass=*)", $basedn = "")
148   {
149     if($this->hascon){
150       if ($this->reconnect) $this->connect();
151       $this->clearResult();
152       if ($basedn == "")
153         $basedn = $this->basedn;
154       $this->sr = @ldap_list($this->cid, $basedn, $filter);
155       $this->error = @ldap_error($this->cid);
156       $this->resetResult();
157       $this->hasres=true;
158       return($this->sr);
159     }else{
160       $this->error = "Could not connect to LDAP server";
161       return("");
162     }
163   }
165   function cat($dn)
166   {
167     if($this->hascon){
168       if ($this->reconnect) $this->connect();
169       $this->clearResult();
170       $filter = "(objectclass=*)";
171       $this->sr = @ldap_read($this->cid, $dn, $filter);
172       $this->error = @ldap_error($this->cid);
173       $this->resetResult();
174       $this->hasres=true;
175       return($this->sr);
176     }else{
177       $this->error = "Could not connect to LDAP server";
178       return("");
179     }
180   }
182   function set_size_limit($size)
183   {
184     /* Ignore zero settings */
185     if ($size == 0){
186       @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, 10000000);
187     }
188     if($this->hascon){
189       @ldap_set_option($this->cid, LDAP_OPT_SIZELIMIT, $size);
190     } else {
191       $this->error = "Could not connect to LDAP server";
192     }
193   }
195   function fetch()
196   {
197     if($this->hascon){
198       if($this->hasres){
199         if ($this->start == 0)
200         {
201           $this->start = 1;
202           $this->re= @ldap_first_entry($this->cid, $this->sr);
203         } else {
204           $this->re= @ldap_next_entry($this->cid, $this->re);
205         }
206         if ($this->re)
207         {
208           $att= @ldap_get_attributes($this->cid, $this->re);
209           $att['dn']= @ldap_get_dn($this->cid, $this->re);
210         }
211         $this->error = @ldap_error($this->cid);
212         if (!isset($att)){
213           $att= array();
214         }
215         return($att);
216       }else{
217         $this->error = "Perform a Fetch with no Search";
218         return("");
219       }
220     }else{
221       $this->error = "Could not connect to LDAP server";
222       return("");
223     }
224   }
226   function resetResult()
227   {
228     $this->start = 0;
229   }
231   function clearResult()
232   {
233     if($this->hasres){
234       $this->hasres = false;
235       @ldap_free_result($this->sr);
236     }
237   }
239   function getDN()
240   {
241     if($this->hascon){
242       if($this->hasres){
244         if(!$this->re)
245           {
246           $this->error = "Perform a Fetch with no valid Result";
247           }
248           else
249           {
250           $rv = @ldap_get_dn($this->cid, $this->re);
251         
252           $this->error = @ldap_error($this->cid);
253           $rv= preg_replace("/[ ]*,[ ]*/", ",", $rv);
254           return($rv);
255            }
256       }else{
257         $this->error = "Perform a Fetch with no Search";
258         return("");
259       }
260     }else{
261       $this->error = "Could not connect to LDAP server";
262       return("");
263     }
264   }
266   function count()
267   {
268     if($this->hascon){
269       if($this->hasres){
270         $rv = @ldap_count_entries($this->cid, $this->sr);
271         $this->error = @ldap_error($this->cid);
272         return($rv);
273       }else{
274         $this->error = "Perform a Fetch with no Search";
275         return("");
276       }
277     }else{
278       $this->error = "Could not connect to LDAP server";
279       return("");
280     }
281   }
283   function rm($attrs = "", $dn = "")
284   {
285     if($this->hascon){
286       if ($this->reconnect) $this->connect();
287       if ($dn == "")
288         $dn = $this->basedn;
290       $r = @ldap_mod_del($this->cid, $dn, $attrs);
291       $this->error = @ldap_error($this->cid);
292       return($r);
293     }else{
294       $this->error = "Could not connect to LDAP server";
295       return("");
296     }
297   }
299   function rename($attrs, $dn = "")
300   {
301     if($this->hascon){
302       if ($this->reconnect) $this->connect();
303       if ($dn == "")
304         $dn = $this->basedn;
306       $r = @ldap_mod_replace($this->cid, $dn, $attrs);
307       $this->error = @ldap_error($this->cid);
308       return($r);
309     }else{
310       $this->error = "Could not connect to LDAP server";
311       return("");
312     }
313   }
315   function rmdir($deletedn)
316   {
317     if($this->hascon){
318       if ($this->reconnect) $this->connect();
319       $r = @ldap_delete($this->cid, $deletedn);
320       $this->error = @ldap_error($this->cid);
321       return($r ? $r : 0);
322     }else{
323       $this->error = "Could not connect to LDAP server";
324       return("");
325     }
326   }
328   /**
329   *  Function rmdir_recursive
330   *
331   *  Description: Based in recursive_remove, adding two thing: full subtree remove, and delete own node.
332   *  Parameters:  The dn to delete
333   *  GiveBack:    True on sucessfull , 0 in error, and "" when we don't get a ldap conection
334   *
335   */
337   function rmdir_recursive($deletedn)
338   {
339     if($this->hascon){
340       if ($this->reconnect) $this->connect();
341       $delarray= array();
342         
343       /* Get sorted list of dn's to delete */
344       $this->ls ("(objectClass=*)",$deletedn);
345       while ($this->fetch()){
346         $deldn= $this->getDN();
347         $delarray[$deldn]= strlen($deldn);
348       }
349       arsort ($delarray);
350       reset ($delarray);
352       /* Really Delete ALL dn's in subtree */
353       foreach ($delarray as $key => $value){
354         $this->rmdir_recursive($key);
355       }
356       
357       /* Finally Delete own Node */
358       $r = @ldap_delete($this->cid, $deletedn);
359       $this->error = @ldap_error($this->cid);
360       return($r ? $r : 0);
361     }else{
362       $this->error = "Could not connect to LDAP server";
363       return("");
364     }
365   }
367   /* Copy given attributes and sub-dns with attributes to destination dn 
368       
369   */
370   function copy_FAI_resource_recursive($sourcedn,$destinationdn,$type="branch",$is_first = false)
371   {
372     error_reporting(E_ALL);
373     if($this->hascon){
374       if ($this->reconnect) $this->connect();
376       /* Save base dn */
377       $basedn= $this->basedn;
378       $delarray= array();
379       
380       /* Check if destination entry already exists */
381       if($this->count($this->fetch($this->cat($destinationdn)))){
382         return;
383       }else{
385         /* Get source entrie */
386         $this->cd($basedn);
387         $attr = $this->fetch($this->cat($sourcedn));
389         /* check if this is a department */
390         if(in_array("organizationalUnit",$attr['objectClass'])){
391           $attr['dn'] = $destinationdn;
392           $this->cd($basedn);
393           $this->create_missing_trees($destinationdn);
394           $this->cd($destinationdn);
396           /* If is first entry, append FAIbranch to department entry */
397           if($is_first){
398             $attr= $this->fetch($this->cat($destinationdn));
400             /* Filter unneeded informations */
401             foreach($attr as $key => $value){
402               if(is_numeric($key)) unset($attr[$key]);
403               if(isset($attr[$key]['count'])){
404                 if(($attr[$key]['count']==1)&&($key!="objectClass")){
405                   $attr[$key] = $attr[$key][0];
406                 }
407               }
408               if(isset($attr[$key]['count'])) unset($attr[$key]['count']);
409             }
410             unset($attr['count']);
411             unset($attr['dn']);
413             /* Add marking attribute */
414             $attr['objectClass'][] = "FAIbranch";
415             
416             /* Add this entry */
417             $this->modify($attr);
418             //echo $this->error;
419           }
420           
421         }else{
422         /* If this is no department */
423           foreach($attr as $key => $value){
424             if(is_numeric($key)) unset($attr[$key]);
425             if(isset($attr[$key]['count'])){
426               if(($attr[$key]['count']==1)&&($key!="objectClass")){
427                 $attr[$key] = $attr[$key][0];
428               }
429             }
430             if(isset($attr[$key]['count'])) unset($attr[$key]['count']); 
431           }
432           unset($attr['count']);
433           unset($attr['dn']);
434  
435           if($type=="branch"){
436             $attr['FAIstate'] ="branch";
437           }elseif($type=="freeze"){
438             $attr['FAIstate'] ="freeze";
439           }else{
440             print_red(_("Unknown FAIsate %s"),$type);
441           }
442  
443           /* Add entry */
444           $this->cd($destinationdn);
445           $a = $this->fetch($this->cat($destinationdn));
446           if(!count($a)){
447             $this->add($attr);
448           }
449           //echo $this->error;
451           if($this->error != "Success"){
452             /* Some error occured */
453             print "---------------------------------------------";
454             print $this->get_error()."<br>";
455             print $sourcedn."<br>";
456             print $destinationdn."<br>";
457             print_a( $attr);
458             exit();
459           }          
460         }
461       }
463       $this->ls ("(objectClass=*)",$sourcedn);
464       while ($this->fetch()){
465         $deldn= $this->getDN();
466         $delarray[$deldn]= strlen($deldn);
467       }
468       asort ($delarray);
469       reset ($delarray);
471       foreach($delarray as $dn => $bla){
472         if($dn != $destinationdn){
473           $this->cd($basedn);
474           $item = $this->fetch($this->cat($dn));
475           if(!in_array("FAIbranch",$item['objectClass'])){
476             $this->copy_FAI_resource_recursive($dn,str_replace($sourcedn,$destinationdn,$dn),$type);
477           } 
478         }
479       //  $this->cd($basedn);
480       //  $this->copy_recursive($dn,preg_replace("/".$sourcedn."/i",$destinationdn,$dn),$filter);
481       }
482     }
483   }
485   function modify($attrs)
486   {
487     if($this->hascon){
488       if ($this->reconnect) $this->connect();
489       $r = @ldap_modify($this->cid, $this->basedn, $attrs);
490       $this->error = @ldap_error($this->cid);
491       return($r ? $r : 0);
492     }else{
493       $this->error = "Could not connect to LDAP server";
494       return("");
495     }
496   }
498   function add($attrs)
499   {
500     if($this->hascon){
501       if ($this->reconnect) $this->connect();
502       $r = @ldap_add($this->cid, $this->basedn, $attrs);
503       $this->error = @ldap_error($this->cid);
504       return($r ? $r : 0);
505     }else{
506       $this->error = "Could not connect to LDAP server";
507       return("");
508     }
509   }
511   function create_missing_trees($target)
512   {
513     /* Ignore create_missing trees if the base equals target */
514     if ($target == $this->basedn){
515      return;
516     }
517     $l= array_reverse(explode(",", preg_replace("/,".$this->basedn."/", "", $target)));
518     $cdn= $this->basedn;
519     foreach ($l as $part){
520       $cdn= "$part,$cdn";
522       /* Ignore referrals */
523       $found= false;
524       foreach($this->referrals as $ref){
525         $base= preg_replace('!^[^:]+://[^/]+/([^?]+).*$!', '\\1', $ref['URL']);
526         if ($base == $cdn){
527           $found= true;
528           break;
529         }
530       }
531       if ($found){
532         continue;
533       }
535       $this->cat ($cdn);
536       $attrs= $this->fetch();
538       /* Create missing entry? */
539       if (!count ($attrs)){
540         $type= preg_replace('/^([^=]+)=.*$/', '\\1', $cdn);
541         $param= preg_replace('/^[^=]+=([^,]+),.*$/', '\\1', $cdn);
543         $na= array();
544         switch ($type){
545           case 'ou':
546             $na["objectClass"]= "organizationalUnit";
547             $na["ou"]= $param;
548             break;
549           case 'dc':
550             $na["objectClass"]= array("dcObject", "top", "locality");
551             $na["dc"]= $param;
552             break;
553           default:
554             print_red(sprintf(_("Autocreation of type '%s' is currently not supported. Please report to the GOsa team."), $type));
555             echo $_SESSION['errors'];
556             exit;
557         }
558         $this->cd($cdn);
559         $this->add($na);
560       }
561     }
562   }
564   function recursive_remove()
565   {
566     $delarray= array();
568     /* Get sorted list of dn's to delete */
569     $this->search ("(objectClass=*)");
570     while ($this->fetch()){
571       $deldn= $this->getDN();
572       $delarray[$deldn]= strlen($deldn);
573     }
574     arsort ($delarray);
575     reset ($delarray);
577     /* Delete all dn's in subtree */
578     foreach ($delarray as $key => $value){
579       $this->rmdir($key);
580     }
581   }
583   function get_attribute($dn, $name,$r_array=0)
584   {
585     $data= "";
586     if ($this->reconnect) $this->connect();
587     $sr= @ldap_read($this->cid, $dn, "objectClass=*", array("$name"));
589     /* fill data from LDAP */
590     if ($sr) {
591       $ei= @ldap_first_entry($this->cid, $sr);
592       if ($ei) {
593         if ($info= @ldap_get_values_len($this->cid, $ei, "$name")){
594           $data= $info[0];
595         }
597       }
598     }
599     if($r_array==0)
600     return ($data);
601     else
602     return ($info);
603   
604   
605   }
606  
609   function get_additional_error()
610   {
611     $error= "";
612     @ldap_get_option ($this->cid, LDAP_OPT_ERROR_STRING, $error);
613     return ($error);
614   }
616   function get_error()
617   {
618     if ($this->error == 'Success'){
619       return $this->error;
620     } else {
621       $error= $this->error." (".$this->get_additional_error().")";
622       return $error;
623     }
624   }
626   function get_credentials($url, $referrals= NULL)
627   {
628     $ret= array();
629     $url= preg_replace('!\?\?.*$!', '', $url);
630     $server= preg_replace('!^([^:]+://[^/]+)/.*$!', '\\1', $url);
632     if ($referrals == NULL){
633       $referrals= $this->referrals;
634     }
636     if (isset($referrals[$server])){
637       return ($referrals[$server]);
638     } else {
639       $ret['ADMIN']= $this->binddn;
640       $ret['PASSWORD']= $this->bindpw;
641     }
643     return ($ret);
644   }
647   function gen_ldif ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE)
648   {
649     $display= "";
651     if ($recursive){
652       $this->cd($dn);
653       $this->search("$filter", array('dn'));
654       while ($attrs= $this->fetch()){
655         $display.= $this->gen_one_entry($attrs['dn'], $filter, $attributes);
656         $display.= "\n";
657       }
658     } else {
659       $display.= $this->gen_one_entry($dn);
660     }
662     return ($display);
663   }
665 function gen_xls ($dn, $filter= "(objectClass=*)", $attributes= array('*'), $recursive= TRUE,$r_array=0)
666   {
667     $display= "";
669       $this->cd($dn);
670       $this->search("$filter");
672       $i=0;
673       while ($attrs= $this->fetch()){
674         $j=0;
676         foreach ($attributes as $at){
677           $display[$i][$j]= $this->get_attribute($attrs['dn'], $at,$r_array);
678           $j++;
679         }
681         $i++;
682       }
684     return ($display);
685   }
688   function gen_one_entry($dn, $filter= "(objectClass=*)" , $name= array("*"))
689   {
690     $ret = "";
691     $data = "";
692     if($this->reconnect){
693       $this->connect();
694     }
696     /* Searching Ldap Tree */
697     $sr= @ldap_read($this->cid, $dn, $filter, $name);
699     /* Get the first entry */   
700     $entry= @ldap_first_entry($this->cid, $sr);
702     /* Get all attributes related to that Objekt */
703     $atts = array();
704     
705     /* Assemble dn */
706     $atts[0]['name']  = "dn";
707     $atts[0]['value'] = array('count' => 1, 0 => $dn);
709     /* Reset index */
710     $i = 1 ; 
711   $identifier = array();
712     $attribute= @ldap_first_attribute($this->cid,$entry,$identifier);
713     while ($attribute) {
714       $i++;
715       $atts[$i]['name']  = $attribute;
716       $atts[$i]['value'] = @ldap_get_values_len($this->cid, $entry, "$attribute");
718       /* Next one */
719       $attribute= @ldap_next_attribute($this->cid,$entry,$identifier);
720     }
722     foreach($atts as $at)
723     {
724       for ($i= 0; $i<$at['value']['count']; $i++){
726         /* Check if we must encode the data */
727         if(!preg_match('/^[a-z0-9+@#.=, \/ -]+$/i', $at['value'][$i])) {
728           $ret .= $at['name'].":: ".base64_encode($at['value'][$i])."\n";
729         } else {
730           $ret .= $at['name'].": ".$at['value'][$i]."\n";
731         }
732       }
733     }
735     return($ret);
736   }
739   function dn_exists($dn)
740   {
741     return @ldap_list($this->cid, $dn, "(objectClass=*)", array("objectClass"));
742   }
743   
746   function import_complete_ldif($str_attr,&$error,$overwrite,$cleanup)
747   {
748     if($this->reconnect) $this->connect();
750     /* First we have to splitt the string ito detect empty lines
751        An empty line indicates an new Entry */
752     $entries = split("\n",$str_attr);
754     $data = "";
755     $cnt = 0; 
756     $current_line = 0;
758     /* Every single line ... */
759     foreach($entries as $entry) {
760       $current_line ++;
762       /* Removing Spaces to .. 
763          .. test if a new entry begins */
764       $tmp  = str_replace(" ","",$data );
766       /* .. prevent empty lines in an entry */
767       $tmp2 = str_replace(" ","",$entry);
769       /* If the Block ends (Empty Line) */
770       if((empty($entry))&&(!empty($tmp))) {
771         /* Add collected lines as a complete block */
772         $all[$cnt] = $data;
773         $cnt ++;
774         $data ="";
775       } else {
777         /* Append lines ... */
778         if(!empty($tmp2)) {
779           /* check if we need base64_decode for this line */
780           if(ereg("::",$tmp2))
781           {
782             $encoded = split("::",$entry);
783             $attr  = $encoded[0];
784             $value = base64_decode($encoded[1]);
785             /* Add linenumber */
786             $data .= $current_line."#".$attr.":".$value."\n";
787           }
788           else
789           {
790             /* Add Linenumber */ 
791             $data .= $current_line."#".$entry."\n";
792           }
793         }
794       }
795     }
797     /* The Data we collected is not in the array all[];
798        For example the Data is stored like this..
800        all[0] = "1#dn : .... \n 
801        2#ObjectType: person \n ...."
802        
803        Now we check every insertblock and try to insert */
804     foreach ( $all as $single) {
805       $lineone = split("\n",$single);  
806       $ndn = split("#", $lineone[0]);
807       $line = $ndn[1];
809       $dnn = split (":",$line);
810       $current_line = $ndn[0];
811       $dn    = $dnn[0];
812       $value = $dnn[1];
814       /* Every block must begin with a dn */
815       if($dn != "dn") {
816         $error= sprintf(_("This is not a valid DN: '%s'. A block for import should begin with 'dn: ...' in line %s"), $line, $current_line);
817         return -2;  
818       }
820       /* Should we use Modify instead of Add */
821       $usemodify= false;
823       /* Delete before insert */
824       $usermdir= false;
825     
826       /* The dn address already exists! */
827       if (($this->dn_exists($value))&&((!$overwrite)&&(!$cleanup))) {
829         $error= sprintf(_("The dn: '%s' (from line %s) already exists in the LDAP database."), $line, $current_line);
830         return ALREADY_EXISTING_ENTRY;   
832       } elseif(($this->dn_exists($value))&&($cleanup)){
834         /* Delete first, then add */
835         $usermdir = true;        
837       } elseif(($this->dn_exists($value))&&($overwrite)) {
838         
839         /* Modify instead of Add */
840         $usemodify = true;
841       }
842      
843       /* If we can't Import, return with a file error */
844       if(!$this->import_single_entry($single,$usemodify,$usermdir) ) {
845         $error= sprintf(_("Error while importing dn: '%s', please check your LDIF from line %s on!"), $line,
846                         $current_line);
847         return UNKNOWN_TOKEN_IN_LDIF_FILE;      }
848     }
850     return (INSERT_OK);
851   }
854   /* Imports a single entry */
855   function import_single_entry($str_attr,$modify,$delete)
856   {
857     if($this->reconnect) $this->connect();
859     $ret = false;
860     $rows= split("\n",$str_attr);
861     $data= false;
863     foreach($rows as $row) {
864       
865       /* Check if we use Linenumbers (when import_complete_ldif is called we use
866          Linenumbers) Linenumbers are use like this 123#attribute : value */
867       if(!empty($row)) {
868         if((strpos($row,"#")!=FALSE)&&(strpos($row,"#")<strpos($row,":"))) {
870           /* We are using line numbers 
871              Because there is a # before a : */
872           $tmp1= split("#",$row);
873           $current_line= $tmp1[0];
874           $row= $tmp1[1];
875         }
877         /* Split the line into  attribute  and value */
878         $attr   = split(":", $row);
879         $attr[0]= trim($attr[0]);  /* attribute */
880         $attr[1]= trim($attr[1]);  /* value */
882         /* Check for attributes that are used more than once */
883         if(!isset($data[$attr[0]])) {
884           $data[$attr[0]]=$attr[1];
885         } else {
886           $tmp = $data[$attr[0]];
888           if(!is_array($tmp)) {
889             $new[0]=$tmp;
890             $new[1]=$attr[1];
891             $datas[$attr[0]]['count']=1;             
892             $data[$attr[0]]=$new;
893           } else {
894             $cnt = $datas[$attr[0]]['count'];           
895             $cnt ++;
896             $data[$attr[0]][$cnt]=$attr[1];
897             $datas[$attr[0]]['count'] = $cnt;
898           }
899         }
900       }
901     } 
902     
903     /* If dn is an index of data, we should try to insert the data */
904     if(isset($data['dn'])) {
905       /* Creating Entry */
906       $this->cd($data['dn']);
908       /* Delete existing entry */
909       if($delete){
910         $this->rmdir($data['dn']);
911       }
912       
913       /* Create missing trees */
914       $this->create_missing_trees($data['dn']);
915       unset($data['dn']);
916       
917       /* If entry exists use modify */
918       if(!$modify){
919         $ret = $this->add($data);
920       } else {
921         $ret = $this->modify($data);
922       }
923     }
925     return($ret);
926   }
928   
929   function importcsv($str)
930   {
931     $lines = split("\n",$str);
932     foreach($lines as $line)
933     {
934       /* continue if theres a comment */
935       if(substr(trim($line),0,1)=="#"){
936         continue;
937       }
939       $line= str_replace ("\t\t","\t",$line);
940       $line= str_replace ("\t"  ,"," ,$line);
941       echo $line;
943       $cells = split(",",$line )  ;
944       $linet= str_replace ("\t\t",",",$line);
945       $cells = split("\t",$line);
946       $count = count($cells);  
947     }
949   }
953 // vim:tabstop=2:expandtab:shiftwidth=2:filetype=php:syntax:ruler:
954 ?>