[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/06
- [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/06
- [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/06
- [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/06
- [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/06
- [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/06
- [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/06
- [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/06
- [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/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
- Prev by Date:
[Phpgroupware-cvs] packages/lint/infos changelog.info, 1.2 copyright.info, 1.3 doc.info, 1.3
- Next by Date:
[Phpgroupware-cvs] old/anthill CHANGES, 1.1 enterbug.php, 1.1 faq.php, 1.1 editversions.php, 1.1 editusers.php, 1.1 editproducts.php, 1.1 gpgupload.php, 1.1 index.php, 1.1 postbug.php, 1.1 newuser.php, 1.1 logout.php, 1.1 login.php, 1.1 editcomponents.php, 1.1 createattachment.php, 1.1 README.1st, 1.1 README, 1.1 COPYING, 1.1 README.OSX, 1.1 THANKS, 1.1 buglist.php, 1.1 admin.php, 1.1 activity.php, 1.1 TODO, 1.1 pref.php, 1.1 TRANSLATORS, 1.1 query.php, 1.1 textreport.php, 1.1 reports.php, 1.1 showattachment.php, 1.1 setup.php, 1.1
- 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):