[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 ab
From: |
skwashd |
Subject: |
[Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1 |
Date: |
Thu, 5 May 2005 02:56:00 +0200 |
Update of old/squirrelmail/functions
Added Files:
Branch: MAIN
abook_database.php
abook_ldap_server.php
abook_local_file.php
strings.php
addressbook.php
Log Message:
cvs clean up
====================================================
Index: abook_database.php
<?php {
/**
** abook_database.php
**
** Backend for personal addressbook stored in a database,
** accessed using the DB-casses in PEAR.
**
** IMPORTANT: The PEAR modules must be in the include path
** for this class to work.
**
** An array with the following elements must be passed to
** the class constructor (elements marked ? are optional):
**
** dsn => database DNS (see PEAR for syntax)
** table => table to store addresses in (must exist)
** owner => current user (owner of address data)
** ? writeable => set writeable flag (true/false)
**
** The table used should have the following columns:
** owner, nickname, firstname, lastname, email, label
** The pair (owner,nickname) should be unique (primary key).
**
** NOTE. This class should not be used directly. Use the
** "AddressBook" class instead.
**
** $Id: abook_database.php,v 1.1 2005/05/05 00:56:40 skwashd Exp $
**/
require_once('DB.php');
class abook_database extends addressbook_backend {
var $btype = 'local';
var $bname = 'database';
var $dsn = '';
var $table = '';
var $owner = '';
var $dbh = false;
var $writeable = true;
// ========================== Private =======================
// Constructor
function abook_database($param) {
$this->sname = lang("Personal address book");
if(is_array($param)) {
if(empty($param['dsn']) ||
empty($param['table']) ||
empty($param['owner']))
return $this->set_error('Invalid parameters');
$this->dsn = $param['dsn'];
$this->table = $param['table'];
$this->owner = $param['owner'];
if(!empty($param['name']))
$this->sname = $param['name'];
if(isset($param['writeable']))
$this->writeable = $param['writeable'];
$this->open(true);
} else {
return $this->set_error('Invalid argument to constructor');
}
}
// Open the database. New connection if $new is true
function open($new = false) {
$this->error = '';
// Return true is file is open and $new is unset
if($this->dbh && !$new)
return true;
// Close old file, if any
if($this->dbh) $this->close();
$dbh = DB::connect($this->dsn, true);
if(DB::isError($dbh) || DB::isWarning($dbh))
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($dbh)));
$this->dbh = $dbh;
return true;
}
// Close the file and forget the filehandle
function close() {
$this->dbh->disconnect();
$this->dbh = false;
}
// ========================== Public ========================
// Search the file
function &search($expr) {
$ret = array();
if(!$this->open())
return false;
// To be replaced by advanded search expression parsing
if(is_array($expr)) return;
// Make regexp from glob'ed expression
$expr = ereg_replace('\?', '_', $expr);
$expr = ereg_replace('\*'. '%', $expr);
$expr = $this->dbh->quoteString($expr);
$expr = "%$expr%";
$query = sprintf('SELECT * FROM %s WHERE owner=\'%s\' AND ' .
'(firstname LIKE \'%s\' OR lastname LIKE \'%s\')',
$this->table, $this->owner, $expr, $expr);
$res = $this->dbh->query($query);
if(DB::isError($res))
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($res)));
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
array_push($ret, array('nickname' => $row['nickname'],
'name' => "$row[firstname]
$row[lastname]",
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'email' => $row['email'],
'label' => $row['label'],
'backend' => $this->bnum,
'source' => &$this->sname));
}
return $ret;
}
// Lookup alias
function &lookup($alias) {
if(empty($alias))
return array();
$alias = strtolower($alias);
if(!$this->open())
return false;
$query = sprintf('SELECT * FROM %s WHERE owner=\'%s\' AND
nickname=\'%s\'',
$this->table, $this->owner, $alias);
$res = $this->dbh->query($query);
if(DB::isError($res))
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($res)));
if ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
return array('nickname' => $row['nickname'],
'name' => "$row[firstname] $row[lastname]",
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'email' => $row['email'],
'label' => $row['label'],
'backend' => $this->bnum,
'source' => &$this->sname);
}
return array();
}
// List all addresses
function &list_addr() {
$ret = array();
if(!$this->open())
return false;
$query = sprintf('SELECT * FROM %s WHERE owner=\'%s\'',
$this->table, $this->owner);
$res = $this->dbh->query($query);
if(DB::isError($res))
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($res)));
while ($row = $res->fetchRow(DB_FETCHMODE_ASSOC)) {
array_push($ret, array('nickname' => $row['nickname'],
'name' => "$row[firstname]
$row[lastname]",
'firstname' => $row['firstname'],
'lastname' => $row['lastname'],
'email' => $row['email'],
'label' => $row['label'],
'backend' => $this->bnum,
'source' => &$this->sname));
}
return $ret;
}
// Add address
function add($userdata) {
if(!$this->writeable)
return $this->set_error(lang("Addressbook is read-only"));
if(!$this->open())
return false;
// See if user exist already
$ret = $this->lookup($userdata['nickname']);
if(!empty($ret))
return $this->set_error(sprintf(lang("User '%1' already exist"),
$ret['nickname']));
// Create query
$query = sprintf('INSERT INTO %s (owner, nickname, firstname, ' .
"lastname, email, label) VALUES('%s','%s','%s'," .
"'%s','%s','%s')",
$this->table, $this->owner,
$this->dbh->quoteString($userdata['nickname']),
$this->dbh->quoteString($userdata['firstname']),
$this->dbh->quoteString($userdata['lastname']),
$this->dbh->quoteString($userdata['email']),
$this->dbh->quoteString($userdata['label']) );
// Do the insert
$r = $this->dbh->simpleQuery($query);
if($r == DB_OK) return true;
// Fail
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($r)));
}
// Delete address
function remove($alias) {
if(!$this->writeable)
return $this->set_error(lang("Addressbook is read-only"));
if(!$this->open())
return false;
// Create query
$query = sprintf('DELETE FROM %s WHERE owner=\'%s\' AND (',
$this->table, $this->owner);
$sepstr = '';
while(list($undef, $nickname) = each($alias)) {
$query .= sprintf('%s nickname=\'%s\' ', $sepstr,
$this->dbh->quoteString($nickname));
$sepstr = 'OR';
}
$query .= ')';
// Delete entry
$r = $this->dbh->simpleQuery($query);
if($r == DB_OK) return true;
// Fail
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($r)));
}
// Modify address
function modify($alias, $userdata) {
if(!$this->writeable)
return $this->set_error(lang("Addressbook is read-only"));
if(!$this->open())
return false;
// See if user exist
$ret = $this->lookup($alias);
if(empty($ret))
return $this->set_error(sprintf(lang("User '%1' does not exist"),
$alias));
// Create query
$query = sprintf("UPDATE %s SET nickname='%s', firstname='%s', ".
"lastname='%s', email='%s', label='%s' ".
"WHERE owner='%s' AND nickname='%s'",
$this->table,
$this->dbh->quoteString($userdata['nickname']),
$this->dbh->quoteString($userdata['firstname']),
$this->dbh->quoteString($userdata['lastname']),
$this->dbh->quoteString($userdata['email']),
$this->dbh->quoteString($userdata['label']),
$this->owner,
$this->dbh->quoteString($alias) );
// Do the insert
$r = $this->dbh->simpleQuery($query);
if($r == DB_OK) return true;
// Fail
return $this->set_error(sprintf(lang("Database error: %1"),
DB::errorMessage($r)));
}
} // End of class abook_database
} ?>
====================================================
Index: abook_ldap_server.php
<?php
/**
** abook_ldap_server.php
**
** Address book backend for LDAP server
**
** An array with the following elements must be passed to
** the class constructor (elements marked ? are optional):
**
** host => LDAP server hostname/IP-address
** base => LDAP server root (base dn). Empty string allowed.
** ? port => LDAP server TCP port number (default: 389)
** ? charset => LDAP server charset (default: utf-8)
** ? name => Name for LDAP server (default "LDAP: hostname")
** Used to tag the result data
** ? maxrows => Maximum # of rows in search result
** ? timeout => Timeout for LDAP operations (in seconds, default: 30)
** Might not work for all LDAP libraries or servers.
**
** NOTE. This class should not be used directly. Use the
** "AddressBook" class instead.
**
** $Id: abook_ldap_server.php,v 1.1 2005/05/05 00:56:40 skwashd Exp $
**/
class abook_ldap_server extends addressbook_backend {
var $btype = 'remote';
var $bname = 'ldap_server';
// Parameters changed by class
var $sname = 'LDAP'; // Service name
var $server = ''; // LDAP server name
var $port = 389; // LDAP server port
var $basedn = ''; // LDAP base DN
var $charset = 'utf-8'; // LDAP server charset
var $linkid = false; // PHP LDAP link ID
var $bound = false; // True if LDAP server is bound
var $maxrows = 250; // Max rows in result
var $timeout = 30; // Timeout for LDAP operations (in seconds)
// Constructor. Connects to database
function abook_ldap_server($param) {
if(!function_exists('ldap_connect')) {
$this->set_error('LDAP support missing from PHP');
return;
}
if(is_array($param)) {
$this->server = $param['host'];
$this->basedn = $param['base'];
if(!empty($param['port']))
$this->port = $param['port'];
if(!empty($param['charset']))
$this->charset = strtolower($param['charset']);
if(isset($param['maxrows']))
$this->maxrows = $param['maxrows'];
if(isset($param['timeout']))
$this->timeout = $param['timeout'];
if(empty($param['name']))
$this->sname = 'LDAP: ' . $param['host'];
else
$this->sname = $param['name'];
$this->open(true);
} else {
$this->set_error('Invalid argument to constructor');
}
}
// Open the LDAP server. New connection if $new is true
function open($new = false) {
$this->error = '';
// Connection is already open
if($this->linkid != false && !$new)
return true;
$this->linkid = @ldap_connect($this->server, $this->port);
if(!$this->linkid)
if(function_exists('ldap_error'))
return $this->set_error(ldap_error($this->linkid));
else
return $this->set_error('ldap_connect failed');
if(address@hidden($this->linkid))
if(function_exists('ldap_error'))
return $this->set_error(ldap_error($this->linkid));
else
return $this->set_error('ldap_bind failed');
$this->bound = true;
return true;
}
// Encode iso8859-1 string to the charset used by this LDAP server
function charset_encode($str) {
if($this->charset == 'utf-8') {
if(function_exists('utf8_encode'))
return utf8_encode($str);
else
return $str;
} else {
return $str;
}
}
// Decode from charset used by this LDAP server to iso8859-1
function charset_decode($str) {
if($this->charset == 'utf-8') {
if(function_exists('utf8_decode'))
return utf8_decode($str);
else
return $str;
} else {
return $str;
}
}
// ========================== Public ========================
// Search the LDAP server
function search($expr) {
// To be replaced by advanded search expression parsing
if(is_array($expr)) return false;
// Encode the expression
$expr = $this->charset_encode($expr);
if(!ereg('\\*', $expr))
$expr = "*$expr*";
$expression = "cn=$expr";
// Make sure connection is there
if(!$this->open())
return false;
// Do the search. Use improved ldap_search() if PHP version is
// 4.0.2 or newer.
if(sqCheckPHPVersion(4, 0, 2)) {
$sret = @ldap_search($this->linkid, $this->basedn, $expression,
array('dn', 'o', 'ou', 'sn', 'givenname',
'cn', 'mail', 'telephonenumber'),
0, $this->maxrows, $this->timeout);
} else {
$sret = @ldap_search($this->linkid, $this->basedn, $expression,
array('dn', 'o', 'ou', 'sn', 'givenname',
'cn', 'mail', 'telephonenumber'));
}
// Should get error from server using the ldap_error() function,
// but it only exist in the PHP LDAP documentation.
if(!$sret)
if(function_exists('ldap_error'))
return $this->set_error(ldap_error($this->linkid));
else
return $this->set_error('ldap_search failed');
if(@ldap_count_entries($this->linkid, $sret) <= 0)
return array();
// Get results
$ret = array();
$returned_rows = 0;
$res = @ldap_get_entries($this->linkid, $sret);
for($i = 0 ; $i < $res['count'] ; $i++) {
$row = $res[$i];
// Extract data common for all e-mail addresses
// of an object. Use only the first name
$nickname = $this->charset_decode($row['dn']);
$fullname = $this->charset_decode($row['cn'][0]);
if(empty($row['telephonenumber'][0])) $phone = '';
else $phone = $this->charset_decode($row['telephonenumber'][0]);
if(!empty($row['ou'][0]))
$label = $this->charset_decode($row['ou'][0]);
else if(!empty($row['o'][0]))
$label = $this->charset_decode($row['o'][0]);
else
$label = '';
if(empty($row['givenname'][0])) $firstname = '';
else $firstname = $this->charset_decode($row['givenname'][0]);
if(empty($row['sn'][0])) $surname = '';
else $surname = $this->charset_decode($row['sn'][0]);
// Add one row to result for each e-mail address
for($j = 0 ; $j < $row['mail']['count'] ; $j++) {
array_push($ret, array('nickname' => $nickname,
'name' => $fullname,
'firstname' => $firstname,
'lastname' => $surname,
'email' => $row['mail'][$j],
'label' => $label,
'phone' => $phone,
'backend' => $this->bnum,
'source' => &$this->sname));
// Limit number of hits
$returned_rows++;
if(($returned_rows >= $this->maxrows) &&
($this->maxrows > 0) ) {
ldap_free_result($sret);
return $ret;
}
}
}
ldap_free_result($sret);
return $ret;
} // end search()
}
?>
====================================================
Index: abook_local_file.php
<?php
/**
** abook_local_file.php
**
** Backend for addressbook as a pipe separated file
**
** An array with the following elements must be passed to
** the class constructor (elements marked ? are optional):
**
** filename => path to addressbook file
** ? create => if true: file is created if it does not exist.
** ? umask => umask set before opening file.
**
** NOTE. This class should not be used directly. Use the
** "AddressBook" class instead.
**
** $Id: abook_local_file.php,v 1.1 2005/05/05 00:56:40 skwashd Exp $
**/
class abook_local_file extends addressbook_backend {
var $btype = 'local';
var $bname = 'local_file';
var $filename = '';
var $filehandle = 0;
var $create = false;
var $umask;
// ========================== Private =======================
// Constructor
function abook_local_file($param) {
$this->sname = lang("Personal address book");
$this->umask = Umask();
if(is_array($param)) {
if(empty($param['filename']))
return $this->set_error('Invalid parameters');
if(!is_string($param['filename']))
return $this->set_error($param['filename'] . ': '.
lang("Not a file name"));
$this->filename = $param['filename'];
if($param['create'])
$this->create = true;
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');
}
}
// Open the addressbook file and store the file pointer.
// Use $file as the file to open, or the class' own
// filename property. If $param is empty and file is
// open, do nothing.
function open($new = false) {
$this->error = '';
$file = $this->filename;
$create = $this->create;
// Return true is file is open and $new is unset
if($this->filehandle && !$new)
return true;
// Check that new file exitsts
if((!(file_exists($file) && is_readable($file))) && !$create)
return $this->set_error("$file: " . lang("No such file or directory"));
// Close old file, if any
if($this->filehandle) $this->close();
// Open file. First try to open for reading and writing,
// but fall back to read only.
umask($this->umask);
$fh = @fopen($file, 'a+');
if($fh) {
$this->filehandle = &$fh;
$this->filename = $file;
$this->writeable = true;
} else {
$fh = @fopen($file, 'r');
if($fh) {
$this->filehandle = &$fh;
$this->filename = $file;
$this->writeable = false;
} else {
return $this->set_error("$file: " . lang("Open failed"));
}
}
return true;
}
// Close the file and forget the filehandle
function close() {
@fclose($this->filehandle);
$this->filehandle = 0;
$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: " . lang("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 ========================
// Search the file
function search($expr) {
// To be replaced by advanded search expression parsing
if(is_array($expr)) return;
// Make regexp from glob'ed expression
$expr = ereg_replace('\?', '.', $expr);
$expr = ereg_replace('\*', '.*', $expr);
$res = array();
if(!$this->open())
return false;
@rewind($this->filehandle);
while ($row = @fgetcsv($this->filehandle, 2048, '|')) {
$line = join(' ', $row);
if(eregi($expr, $line)) {
array_push($res, array('nickname' => $row[0],
'name' => $row[1] . ' ' . $row[2],
'firstname' => $row[1],
'lastname' => $row[2],
'email' => $row[3],
'label' => $row[4],
'backend' => $this->bnum,
'source' => &$this->sname));
}
}
return $res;
}
// Lookup alias
function lookup($alias) {
if(empty($alias))
return array();
$alias = strtolower($alias);
$this->open();
@rewind($this->filehandle);
while ($row = @fgetcsv($this->filehandle, 2048, '|')) {
if(strtolower($row[0]) == $alias) {
return array('nickname' => $row[0],
'name' => $row[1] . ' ' . $row[2],
'firstname' => $row[1],
'lastname' => $row[2],
'email' => $row[3],
'label' => $row[4],
'backend' => $this->bnum,
'source' => &$this->sname);
}
}
return array();
}
// List all addresses
function list_addr() {
$res = array();
$this->open();
@rewind($this->filehandle);
while ($row = @fgetcsv($this->filehandle, 2048, '|')) {
array_push($res, array('nickname' => $row[0],
'name' => $row[1] . ' ' . $row[2],
'firstname' => $row[1],
'lastname' => $row[2],
'email' => $row[3],
'label' => $row[4],
'backend' => $this->bnum,
'source' => &$this->sname));
}
return $res;
}
// Add address
function add($userdata) {
if(!$this->writeable)
return $this->set_error(lang("Addressbook is read-only"));
// See if user exist already
$ret = $this->lookup($userdata['nickname']);
if(!empty($ret))
return $this->set_error(sprintf(lang("User '%1' already exist"),
$ret['nickname']));
// Here is the data to write
$data = $userdata['nickname'] . '|' . $userdata['firstname'] . '|' .
$userdata['lastname'] . '|' . $userdata['email'] . '|' .
$userdata['label'];
// Strip linefeeds
$data = ereg_replace("[\r\n]", ' ', $data);
// Add linefeed at end
$data = $data . "\n";
// Reopen file, just to be sure
$this->open(true);
if(!$this->writeable)
return $this->set_error(lang("Addressbook is read-only"));
// Lock the file
if(!$this->lock())
return $this->set_error(lang("Could not lock datafile"));
// Write
$r = fwrite($this->filehandle, $data);
// Unlock file
$this->unlock();
// Test write result and exit if OK
if($r > 0) return true;
// Fail
$this->set_error(lang("Write to addressbook failed"));
return false;
}
// Delete address
function remove($alias) {
if(!$this->writeable)
return $this->set_error(lang("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(lang("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(lang("Addressbook is read-only"));
// See if user exist
$ret = $this->lookup($alias);
if(empty($ret))
return $this->set_error(sprintf(lang("User '%1' 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(lang("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
?>
====================================================
Index: strings.php
<?php
/* $Id: strings.php,v 1.1 2005/05/05 00:56:40 skwashd Exp $ */
$strings_php = true;
//*************************************************************************
// Count the number of occurances of $needle are in $haystack.
// $needle can be a character or string, and need not occur in $haystack
//*************************************************************************
function countCharInString($haystack, $needle) {
if ($needle == '') return 0;
return count(explode($needle, $haystack));
}
//*************************************************************************
// Read from the back of $haystack until $needle is found, or the begining
// of the $haystack is reached. $needle is a single character
//*************************************************************************
function readShortMailboxName($haystack, $needle) {
if ($needle == '') return $haystack;
$parts = explode($needle, $haystack);
$elem = array_pop($parts);
while ($elem == '' && count($parts))
{
$elem = array_pop($parts);
}
return $elem;
}
//*************************************************************************
// Read from the back of $haystack until $needle is found, or the begining
// of the $haystack is reached. $needle is a single character
//*************************************************************************
function readMailboxParent($haystack, $needle) {
if ($needle == '') return '';
$parts = explode($needle, $haystack);
$elem = array_pop($parts);
while ($elem == '' && count($parts))
{
$elem = array_pop($parts);
}
return join($needle, $parts);
}
// Searches for the next position in a string minus white space
function next_pos_minus_white ($haystack, $pos) {
while (substr($haystack, $pos, 1) == ' ' ||
substr($haystack, $pos, 1) == "\t" ||
substr($haystack, $pos, 1) == "\n" ||
substr($haystack, $pos, 1) == "\r") {
if ($pos >= strlen($haystack))
return -1;
$pos++;
}
return $pos;
}
// Wraps text at $wrap characters
// Has a problem with special HTML characters, so call this before
// you do character translation.
// Specifically, ' comes up as 5 characters instead of 1.
// This should not add newlines to the end of lines.
function sqWordWrap(&$line, $wrap) {
preg_match('/^([\\s>]*)([^\\s>].*)?$/', $line, $regs);
$beginning_spaces = $regs[1];
if (isset($regs[2])) {
$words = explode(' ', $regs[2]);
} else {
$words = "";
}
$i = 0;
$line = $beginning_spaces;
while ($i < count($words)) {
// Force one word to be on a line (minimum)
$line .= $words[$i];
$line_len = strlen($beginning_spaces) + strlen($words[$i]) + 2;
if (isset($words[$i + 1]))
$line_len += strlen($words[$i + 1]);
$i ++;
// Add more words (as long as they fit)
while ($line_len < $wrap && $i < count($words)) {
$line .= ' ' . $words[$i];
$i++;
if (isset($words[$i]))
$line_len += strlen($words[$i]) + 1;
else
$line_len += 1;
}
// Skip spaces if they are the first thing on a continued line
while (!isset($words[$i]) && $i < count($words)) {
$i ++;
}
// Go to the next line if we have more to process
if ($i < count($words)) {
$line .= "\n" . $beginning_spaces;
}
}
}
// Does the opposite of sqWordWrap()
function sqUnWordWrap(&$body)
{
$lines = explode("\n", $body);
$body = "";
$PreviousSpaces = "";
for ($i = 0; $i < count($lines); $i ++)
{
preg_match('/^([\\s>]*)([^\\s>].*)?$/', $lines[$i], $regs);
$CurrentSpaces = $regs[1];
if (isset($regs[2]))
$CurrentRest = $regs[2];
if ($i == 0)
{
$PreviousSpaces = $CurrentSpaces;
$body = $lines[$i];
}
else if ($PreviousSpaces == $CurrentSpaces && // Do the beginnings
match
strlen($lines[$i - 1]) > 65 && // Over 65 characters
long
strlen($CurrentRest)) // and there's a line
to continue with
{
$body .= ' ' . $CurrentRest;
}
else
{
$body .= "\n" . $lines[$i];
$PreviousSpaces = $CurrentSpaces;
}
}
$body .= "\n";
}
/** Returns an array of email addresses **/
/* Be cautious of "address@hidden" */
function parseAddrs($text) {
if (trim($text) == "")
return array();
$text = str_replace(' ', '', $text);
$text = ereg_replace('"[^"]*"', '', $text);
$text = ereg_replace('\\([^\\)]*\\)', '', $text);
$text = str_replace(',', ';', $text);
$array = explode(';', $text);
for ($i = 0; $i < count ($array); $i++) {
$array[$i] = eregi_replace ("^.*[<]", '',
$array[$i]);
$array[$i] = eregi_replace ("[>].*$", '',
$array[$i]);
}
return $array;
}
/** Returns a line of comma separated email addresses from an array **/
function getLineOfAddrs($array) {
if (is_array($array)) {
$to_line = implode(', ', $array);
$to_line = trim(ereg_replace(',,+', ',', $to_line));
} else {
$to_line = '';
}
return $to_line;
}
function translateText(&$body, $wrap_at, $charset) {
global $where, $what; // from searching
global $url_parser_php;
if (!isset($url_parser_php)) {
include '../functions/url_parser.php';
}
$body_ary = explode("\n", $body);
$PriorQuotes = 0;
for ($i=0; $i < count($body_ary); $i++) {
$line = $body_ary[$i];
if (strlen($line) - 2 >= $wrap_at) {
sqWordWrap($line, $wrap_at);
}
$line = charset_decode($charset, $line);
$line = str_replace("\t", ' ', $line);
parseUrl ($line);
$Quotes = 0;
$pos = 0;
while (1)
{
if ($line[$pos] == ' ')
{
$pos ++;
}
else if (strpos($line, '>', $pos) === $pos)
{
$pos += 4;
$Quotes ++;
}
else
{
break;
}
}
if ($Quotes > 1)
$line = '<FONT COLOR="FF0000">'.$line.'</FONT>';
elseif ($Quotes)
$line = '<FONT COLOR="800000">'.$line.'</FONT>';
$body_ary[$i] = $line;
}
$body = '<pre>' . implode("\n", $body_ary) . '</pre>';
}
/* SquirrelMail version number -- DO NOT CHANGE */
$version = '1.0.3';
function find_mailbox_name ($mailbox) {
if (ereg(" *\"([^\r\n\"]*)\"[ \r\n]*$", $mailbox, $regs))
return $regs[1];
ereg(" *([^ \r\n\"]*)[ \r\n]*$",$mailbox,$regs);
return $regs[1];
}
function replace_spaces ($string) {
return str_replace(' ', ' ', $string);
}
function replace_escaped_spaces ($string) {
return str_replace(' ', ' ', $string);
}
function get_location () {
# This determines the location to forward to relative
# to your server. If this doesnt work correctly for
# you (although it should), you can remove all this
# code except the last two lines, and change the header()
# function to look something like this, customized to
# the location of SquirrelMail on your server:
#
# http://www.myhost.com/squirrelmail/src/login.php
global $PHP_SELF, $SERVER_NAME, $HTTPS, $HTTP_HOST, $SERVER_PORT;
// Get the path
$path = substr($PHP_SELF, 0, strrpos($PHP_SELF, '/'));
// Check if this is a HTTPS or regular HTTP request
$proto = 'http://';
if(isset($HTTPS) && !strcasecmp($HTTPS, 'on') ) {
$proto = 'https://';
}
// Get the hostname from the Host header or server config.
$host = '';
if (isset($HTTP_HOST) && !empty($HTTP_HOST))
{
$host = $HTTP_HOST;
}
else if (isset($SERVER_NAME) && !empty($SERVER_NAME))
{
$host = $SERVER_NAME;
}
$port = '';
if (! strstr($host, ':'))
{
if (isset($SERVER_PORT)) {
if (($SERVER_PORT != 80 && $proto == 'http://')
|| ($SERVER_PORT != 443 && $proto == 'https://')) {
$port = sprintf(':%d', $SERVER_PORT);
}
}
}
if ($host)
return $proto . $host . $port . $path;
// Fallback is to omit the server name and use a relative URI,
// although this is not RFC 2616 compliant.
return $path;
}
function sqStripSlashes($string) {
if (get_magic_quotes_gpc()) {
$string = stripslashes($string);
}
return $string;
}
// These functions are used to encrypt the passowrd before it is
// stored in a cookie.
function OneTimePadEncrypt ($string, $epad) {
$pad = base64_decode($epad);
$encrypted = '';
for ($i = 0; $i < strlen ($string); $i++) {
$encrypted .= chr (ord($string[$i]) ^ ord($pad[$i]));
}
return base64_encode($encrypted);
}
function OneTimePadDecrypt ($string, $epad) {
$pad = base64_decode($epad);
$encrypted = base64_decode ($string);
$decrypted = '';
for ($i = 0; $i < strlen ($encrypted); $i++) {
$decrypted .= chr (ord($encrypted[$i]) ^ ord($pad[$i]));
}
return $decrypted;
}
// Randomize the mt_rand() function. Toss this in strings or
// integers and it will seed the generator appropriately.
// With strings, it is better to get them long. Use md5() to
// lengthen smaller strings.
function sq_mt_seed($Val)
{
// if mt_getrandmax() does not return a 2^n - 1 number,
// this might not work well. This uses $Max as a bitmask.
$Max = mt_getrandmax();
if (! is_int($Val))
{
if (function_exists('crc32'))
{
$Val = crc32($Val);
}
else
{
$Str = $Val;
$Pos = 0;
$Val = 0;
$Mask = $Max / 2;
$HighBit = $Max ^ $Mask;
while ($Pos < strlen($Str))
{
if ($Val & $HighBit)
{
$Val = (($Val & $Mask) << 1) + 1;
}
else
{
$Val = ($Val & $Mask) << 1;
}
$Val ^= $Str[$Pos];
$Pos ++;
}
}
}
if ($Val < 0)
$Val *= -1;
if ($Val = 0)
return;
mt_srand(($Val ^ mt_rand(0, $Max)) & $Max);
}
// This function initializes the random number generator fairly well.
// It also only initializes it once, so you don't accidentally get
// the same 'random' numbers twice in one session.
function sq_mt_randomize()
{
global $REMOTE_PORT, $REMOTE_ADDR, $UNIQUE_ID;
static $randomized;
if ($randomized)
return;
// Global
sq_mt_seed((int)((double) microtime() * 1000000));
sq_mt_seed(md5($REMOTE_PORT . $REMOTE_ADDR . getmypid()));
// getrusage
if (function_exists('getrusage')) {
$dat = getrusage();
$Str = '';
foreach ($dat as $k => $v)
{
$Str .= $k . $v;
}
sq_mt_seed(md5($Str));
}
// Apache-specific
sq_mt_seed(md5($UNIQUE_ID));
$randomized = 1;
}
function OneTimePadCreate ($length=100) {
sq_mt_randomize();
$pad = '';
for ($i = 0; $i < $length; $i++) {
$pad .= chr(mt_rand(0,255));
}
return base64_encode($pad);
}
// Check if we have a required PHP-version. Return TRUE if we do,
// or FALSE if we don't.
// To check for 4.0.1, use sqCheckPHPVersion(4,0,1)
// To check for 4.0b3, use sqCheckPHPVersion(4,0,-3)
// Does not handle betas like 4.0.1b1 or development versions
function sqCheckPHPVersion($major, $minor, $release) {
$ver = phpversion();
eregi('^([0-9]+)\\.([0-9]+)(.*)', $ver, $regs);
// Parse the version string
$vmajor = strval($regs[1]);
$vminor = strval($regs[2]);
$vrel = $regs[3];
if($vrel[0] == ".")
$vrel = strval(substr($vrel, 1));
if($vrel[0] == 'b' || $vrel[0] == 'B')
$vrel = - strval(substr($vrel, 1));
if($vrel[0] == 'r' || $vrel[0] == 'R')
$vrel = - strval(substr($vrel, 2))/10;
// Compare major version
if($vmajor < $major) return false;
if($vmajor > $major) return true;
// Major is the same. Compare minor
if($vminor < $minor) return false;
if($vminor > $minor) return true;
// Major and minor is the same as the required one.
// Compare release
if($vrel >= 0 && $release >= 0) { // Neither are beta
if($vrel < $release) return false;
} else if($vrel >= 0 && $release < 0){ // This is not beta, required is
beta
return true;
} else if($vrel < 0 && $release >= 0){ // This is beta, require not beta
return false;
} else { // Both are beta
if($vrel > $release) return false;
}
return true;
}
/* Returns a string showing the size of the message/attachment */
function show_readable_size($bytes)
{
$bytes /= 1024;
$type = 'k';
if ($bytes / 1024 > 1)
{
$bytes /= 1024;
$type = 'm';
}
if ($bytes < 10)
{
$bytes *= 10;
settype($bytes, 'integer');
$bytes /= 10;
}
else
settype($bytes, 'integer');
return $bytes . '<small> ' . $type . '</small>';
}
/* Generates a random string from the caracter set you pass in
*
* Flags:
* 1 = add lowercase a-z to $chars
* 2 = add uppercase A-Z to $chars
* 4 = add numbers 0-9 to $chars
*/
function GenerateRandomString($size, $chars, $flags = 0)
{
if ($flags & 0x1)
$chars .= 'abcdefghijklmnopqrstuvwxyz';
if ($flags & 0x2)
$chars .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
if ($flags & 0x4)
$chars .= '0123456789';
if ($size < 1 || strlen($chars) < 1)
return '';
sq_mt_randomize(); // Initialize the random number generator
$String = "";
while (strlen($String) < $size) {
$String .= $chars[mt_rand(0, strlen($chars))];
}
return $String;
}
?>
====================================================
Index: addressbook.php
<?php
/**
** addressbook.php
**
** Functions and classes for the addressbook system.
**
** $Id: addressbook.php,v 1.1 2005/05/05 00:56:40 skwashd Exp $
**/
$addressbook_php = true;
// Include backends here.
include('../functions/abook_local_file.php');
include('../functions/abook_ldap_server.php');
// Create and initialize an addressbook object.
// Returns the created object
function addressbook_init($showerr = true, $onlylocal = false) {
global $data_dir, $username, $ldap_server;
// Create a new addressbook object
$abook = new AddressBook;
// Always add a local backend
$filename = sprintf('%s%s.abook', $data_dir, $username);
$r = $abook->add_backend('local_file', Array('filename' => $filename,
'create' => true));
if(!$r && $showerr) {
printf(lang("Error opening file %1"), $filename);
exit;
}
if($onlylocal)
return $abook;
// Load configured LDAP servers (if PHP has LDAP support)
if(is_array($ldap_server) && function_exists('ldap_connect')) {
reset($ldap_server);
while(list($undef,$param) = each($ldap_server)) {
if(is_array($param)) {
$r = $abook->add_backend('ldap_server', $param);
if(!$r && $showerr) {
printf(' ' . lang("Error initializing LDAP server %1:") .
"<BR>\n", $param['host']);
print(' ' . $abook->error);
exit;
}
}
}
}
// Return the initialized object
return $abook;
}
// Had to move this function outside of the Addressbook Class
// PHP 4.0.4 Seemed to be having problems with inline functions.
function addressbook_cmp($a,$b) {
if($a['backend'] > $b['backend'])
return 1;
else if($a['backend'] < $b['backend'])
return -1;
return (strtolower($a['name']) > strtolower($b['name'])) ? 1 : -1;
}
/**
** This is the main address book class that connect all the
** backends and provide services to the functions above.
**
**/
class AddressBook {
var $backends = array();
var $numbackends = 0;
var $error = '';
var $localbackend = 0;
var $localbackendname = '';
// Constructor function.
function AddressBook() {
$localbackendname = lang("Personal address book");
}
// Return an array of backends of a given type,
// or all backends if no type is specified.
function get_backend_list($type = '') {
$ret = array();
for($i = 1 ; $i <= $this->numbackends ; $i++) {
if(empty($type) || $type == $this->backends[$i]->btype) {
array_push($ret, $this->backends[$i]);
}
}
return $ret;
}
// ========================== Public ========================
// Add a new backend. $backend is the name of a backend
// (without the abook_ prefix), and $param is an optional
// mixed variable that is passed to the backend constructor.
// See each of the backend classes for valid parameters.
function add_backend($backend, $param = '') {
$backend_name = 'abook_' . $backend;
eval('$newback = new ' . $backend_name . '($param);');
if(!empty($newback->error)) {
$this->error = $newback->error;
return false;
}
$this->numbackends++;
$newback->bnum = $this->numbackends;
$this->backends[$this->numbackends] = $newback;
// Store ID of first local backend added
if($this->localbackend == 0 && $newback->btype == 'local') {
$this->localbackend = $this->numbackends;
$this->localbackendname = $newback->sname;
}
return $this->numbackends;
}
// Return a list of addresses matching expression in
// all backends of a given type.
function search($expression, $bnum = -1) {
$ret = array();
$this->error = '';
// Search all backends
if($bnum == -1) {
$sel = $this->get_backend_list('');
$failed = 0;
for($i = 0 ; $i < sizeof($sel) ; $i++) {
$backend = &$sel[$i];
$backend->error = '';
$res = $backend->search($expression);
if(is_array($res)) {
$ret = array_merge($ret, $res);
} else {
$this->error .= "<br>\n" . $backend->error;
$failed++;
}
}
// Only fail if all backends failed
if($failed >= sizeof($sel))
return false;
}
// Search only one backend
else {
$ret = $this->backends[$bnum]->search($expression);
if(!is_array($ret)) {
$this->error .= "<br>\n" . $this->backends[$bnum]->error;
return false;
}
}
return $ret;
}
// Return a sorted search
function s_search($expression, $bnum = -1) {
$ret = $this->search($expression, $bnum);
if(!is_array($ret))
return $ret;
usort($ret, 'addressbook_cmp');
return $ret;
}
// Lookup an address by alias. Only possible in
// local backends.
function lookup($alias, $bnum = -1) {
$ret = array();
if($bnum > -1) {
$res = $this->backends[$bnum]->lookup($alias);
if(is_array($res)) {
return $res;
} else {
$this->error = $backend->error;
return false;
}
}
$sel = $this->get_backend_list('local');
for($i = 0 ; $i < sizeof($sel) ; $i++) {
$backend = &$sel[$i];
$backend->error = '';
$res = $backend->lookup($alias);
if(is_array($res)) {
if(!empty($res))
return $res;
} else {
$this->error = $backend->error;
return false;
}
}
return $ret;
}
// Return all addresses
function list_addr($bnum = -1) {
$ret = array();
if($bnum == -1)
$sel = $this->get_backend_list('local');
else
$sel = array(0 => &$this->backends[$bnum]);
for($i = 0 ; $i < sizeof($sel) ; $i++) {
$backend = &$sel[$i];
$backend->error = '';
$res = $backend->list_addr();
if(is_array($res)) {
$ret = array_merge($ret, $res);
} else {
$this->error = $backend->error;
return false;
}
}
return $ret;
}
// Create a new address from $userdata, in backend $bnum.
// Return the backend number that the/ address was added
// to, or false if it failed.
function add($userdata, $bnum) {
// Validate data
if(!is_array($userdata)) {
$this->error = lang("Invalid input data");
return false;
}
if(empty($userdata['firstname']) &&
empty($userdata['lastname'])) {
$this->error = lang("Name is missing");
return false;
}
if(empty($userdata['email'])) {
$this->error = lang("E-mail address is missing");
return false;
}
if(empty($userdata['nickname'])) {
$userdata['nickname'] = $userdata['email'];
}
if(eregi('[\\: \\|\\#\"\\!]', $userdata['nickname'])) {
$this->error = lang("Nickname contain illegal characters");
return false;
}
// Check that specified backend accept new entries
if(!$this->backends[$bnum]->writeable) {
$this->error = lang("Addressbook is read-only");
return false;
}
// Add address to backend
$res = $this->backends[$bnum]->add($userdata);
if($res) {
return $bnum;
} else {
$this->error = $this->backends[$bnum]->error;
return false;
}
return false; // Not reached
} // end of add()
// Remove the user identified by $alias from backend $bnum
// If $alias is an array, all users in the array are removed.
function remove($alias, $bnum) {
// Check input
if(empty($alias))
return true;
// Convert string to single element array
if(!is_array($alias))
$alias = array(0 => $alias);
// Check that specified backend is writable
if(!$this->backends[$bnum]->writeable) {
$this->error = lang("Addressbook is read-only");
return false;
}
// Remove user from backend
$res = $this->backends[$bnum]->remove($alias);
if($res) {
return $bnum;
} else {
$this->error = $this->backends[$bnum]->error;
return false;
}
return false; // Not reached
} // end of remove()
// Remove the user identified by $alias from backend $bnum
// If $alias is an array, all users in the array are removed.
function modify($alias, $userdata, $bnum) {
// Check input
if(empty($alias) || !is_string($alias))
return true;
// Validate data
if(!is_array($userdata)) {
$this->error = lang("Invalid input data");
return false;
}
if(empty($userdata['firstname']) &&
empty($userdata['lastname'])) {
$this->error = lang("Name is missing");
return false;
}
if(empty($userdata['email'])) {
$this->error = lang("E-mail address is missing");
return false;
}
if(eregi('[\\: \\|\\#"\\!]', $userdata['nickname'])) {
$this->error = lang("Nickname contain illegal characters");
return false;
}
if(empty($userdata['nickname'])) {
$userdata['nickname'] = $userdata['email'];
}
// Check that specified backend is writable
if(!$this->backends[$bnum]->writeable) {
$this->error = lang("Addressbook is read-only");;
return false;
}
// Modify user in backend
$res = $this->backends[$bnum]->modify($alias, $userdata);
if($res) {
return $bnum;
} else {
$this->error = $this->backends[$bnum]->error;
return false;
}
return false; // Not reached
} // end of modify()
} // End of class Addressbook
/**
** Generic backend that all other backends extend
**/
class addressbook_backend {
// Variables that all backends must provide.
var $btype = 'dummy';
var $bname = 'dummy';
var $sname = 'Dummy backend';
// Variables common for all backends, but that
// should not be changed by the backends.
var $bnum = -1;
var $error = '';
var $writeable = false;
function set_error($string) {
$this->error = '[' . $this->sname . '] ' . $string;
return false;
}
// ========================== Public ========================
function search($expression) {
$this->set_error('search not implemented');
return false;
}
function lookup($alias) {
$this->set_error('lookup not implemented');
return false;
}
function list_addr() {
$this->set_error('list_addr not implemented');
return false;
}
function add($userdata) {
$this->set_error('add not implemented');
return false;
}
function remove($alias) {
$this->set_error('delete not implemented');
return false;
}
function modify($alias, $newuserdata) {
$this->set_error('modify not implemented');
return false;
}
}
?>
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, (continued)
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1,
skwashd <=
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/07
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- [Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1, skwashd, 2005/05/08
- Prev by Date:
[Phpgroupware-cvs] old/squirrelmail/config config.php,1.1
- Next by Date:
[Phpgroupware-cvs] old/phpgwnetsaint/debian rules, 1.2 copyright, 1.2 control, 1.2 changelog, 1.2
- Previous by thread:
[Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1
- Next by thread:
[Phpgroupware-cvs] old/squirrelmail/functions abook_database.php, 1.1 abook_ldap_server.php, 1.1 abook_local_file.php, 1.1 strings.php, 1.1 addressbook.php, 1.1
- Index(es):