From d50a8c482dbaf98715d65f76faad55207b4169f7 Mon Sep 17 00:00:00 2001 From: pallo Date: Sun, 2 Apr 2000 16:50:40 +0000 Subject: [PATCH] Added address management methods (delete & modify). Better file locking. git-svn-id: https://svn.code.sf.net/p/squirrelmail/code/trunk/squirrelmail@373 7612ce4b-ef26-0410-bec9-ea0150e637f0 --- functions/abook_local_file.php | 127 ++++++++++++++++++++++++++++++++- 1 file changed, 124 insertions(+), 3 deletions(-) diff --git a/functions/abook_local_file.php b/functions/abook_local_file.php index 3ad5dec2..91c3e8df 100644 --- a/functions/abook_local_file.php +++ b/functions/abook_local_file.php @@ -46,6 +46,9 @@ if(isset($param["umask"])) $this->umask = $param["umask"]; + if(!empty($param["name"])) + $this->sname = $param["name"]; + $this->open(true); } else { $this->set_error("Invalid argument to constructor"); @@ -102,6 +105,40 @@ $this->filename = ""; $this->writable = false; } + + // Lock the datafile - try 20 times in 5 seconds + function lock() { + for($i = 0 ; $i < 20 ; $i++) { + if(flock($this->filehandle, 2 + 4)) + return true; + else + usleep(250000); + } + return false; + } + + // Lock the datafile + function unlock() { + return flock($this->filehandle, 3); + } + + // Overwrite the file with data from $rows + // NOTE! Previous locks are broken by this function + function overwrite($rows) { + $newfh = @fopen($this->filename, "w"); + if(!$newfh) + return $this->set_error("$file: "._("Open failed")); + + for($i = 0 ; $i < sizeof($rows) ; $i++) { + if(is_array($rows[$i])) + fwrite($newfh, join("|", $rows[$i])."\n"); + } + + fclose($newfh); + $this->unlock(); + $this->open(true); + return true; + } // ========================== Public ======================== @@ -208,13 +245,97 @@ if(!$this->writeable) return $this->set_error(_("Addressbook is read-only")); + // Lock the file + if(!$this->lock()) + return $this->set_error(_("Could not lock datafile")); + + // Write $r = fwrite($this->filehandle, $data); - if($r > 0) - return true; + // Unlock file + $this->unlock(); + + // Test write result and exit if OK + if($r > 0) return true; + + // Fail $this->set_error(_("Write to addressbook failed")); return false; } - } + // Delete address + function remove($alias) { + if(!$this->writeable) + return $this->set_error(_("Addressbook is read-only")); + + // Lock the file to make sure we're the only process working + // on it. + if(!$this->lock()) + return $this->set_error(_("Could not lock datafile")); + + // Read file into memory, ignoring nicknames to delete + $this->open(); + @rewind($this->filehandle); + $i = 0; + $rows = array(); + while($row = @fgetcsv($this->filehandle, 2048, "|")) { + if(!in_array($row[0], $alias)) + $rows[$i++] = $row; + } + + // Write data back + if(!$this->overwrite(&$rows)) { + $this->unlock(); + return false; + } + + $this->unlock(); + return true; + } + + // Modify address + function modify($alias, $userdata) { + if(!$this->writeable) + return $this->set_error(_("Addressbook is read-only")); + + // See if user exist + $ret = $this->lookup($alias); + if(empty($ret)) + return $this->set_error(sprintf(_("User '%s' does not exist"), + $alias)); + + // Lock the file to make sure we're the only process working + // on it. + if(!$this->lock()) + return $this->set_error(_("Could not lock datafile")); + + // Read file into memory, modifying the data for the + // user identifyed by $alias + $this->open(); + @rewind($this->filehandle); + $i = 0; + $rows = array(); + while($row = @fgetcsv($this->filehandle, 2048, "|")) { + if(strtolower($row[0]) != strtolower($alias)) { + $rows[$i++] = $row; + } else { + $rows[$i++] = array(0 => $userdata["nickname"], + 1 => $userdata["firstname"], + 2 => $userdata["lastname"], + 3 => $userdata["email"], + 4 => $userdata["label"]); + } + } + + // Write data back + if(!$this->overwrite(&$rows)) { + $this->unlock(); + return false; + } + + $this->unlock(); + return true; + } + + } // End of class abook_local_file ?> -- 2.25.1