Update of /cvsroot/mahogany/M/lib/imap/src/osdep/nt
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv9509/src/osdep/nt
Modified Files:
os_nt.c os_nt.h
Added Files:
auths.c ip_nt.c linkage.c linkage.h mhnt.c mhnt.h newsnt.c
newsnt.h
Log Message:
applied (still relevant) Mahogany patches from the previous versions; added VC7
project file; added some files normally built during the build process
--- NEW FILE ---
/*
Kerberos authentificator only works on W2K and so isn't built in usually.
#include "auth_gss.c"
*/
#include "auth_md5.c"
#include "auth_log.c"
#include "auth_pla.c"
--- NEW FILE ---
/*
* Program: UNIX IPv4 routines
*
* Author: Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: [EMAIL PROTECTED]
*
* Date: 18 December 2003
* Last Edited: 23 February 2004
*
* The IMAP toolkit provided in this Distribution is
* Copyright 2004 University of Washington.
* The full text of our legal notices is contained in the file called
* CPYRIGHT, included with this Distribution.
*/
#define SADRLEN sizeof (struct sockaddr)
#define SADR4(sadr) ((struct sockaddr_in *) sadr)
#define SADR4LEN sizeof (struct sockaddr_in)
#define SADR4ADR(sadr) SADR4 (sadr)->sin_addr
#define ADR4LEN sizeof (struct in_addr)
#define SADR4PORT(sadr) SADR4 (sadr)->sin_port
/* IP abstraction layer */
char *ip_sockaddrtostring (struct sockaddr *sadr);
long ip_sockaddrtoport (struct sockaddr *sadr);
void *ip_stringtoaddr (char *text,size_t *len,int *family);
struct sockaddr *ip_newsockaddr (size_t *len);
struct sockaddr *ip_sockaddr (int family,void *adr,size_t adrlen,
unsigned short port,size_t *len);
char *ip_sockaddrtoname (struct sockaddr *sadr);
void *ip_nametoaddr (char *name,size_t *len,int *family,char **canonical,
void **next);
/* Return IP address string from socket address
* Accepts: socket address
* Returns: IP address as name string
*/
char *ip_sockaddrtostring (struct sockaddr *sadr)
{
return (sadr->sa_family == PF_INET) ?
inet_ntoa (SADR4ADR (sadr)) : "NON-IPv4";
}
/* Return port from socket address
* Accepts: socket address
* Returns: port number or -1 if can't determine it
*/
long ip_sockaddrtoport (struct sockaddr *sadr)
{
return (sadr->sa_family == PF_INET) ? ntohs (SADR4PORT (sadr)) : -1;
}
/* Return IP address from string
* Accepts: name string
* pointer to returned length
* pointer to returned address family
* Returns: address if valid, length and family updated, or NIL
*/
void *ip_stringtoaddr (char *text,size_t *len,int *family)
{
unsigned long adr;
struct in_addr *ret;
/* get address */
if ((adr = inet_addr (text)) == -1) ret = NIL;
else { /* make in_addr */
ret = (struct in_addr *) fs_get (*len = ADR4LEN);
*family = AF_INET; /* IPv4 */
ret->s_addr = adr; /* set address */
}
return (void *) ret;
}
/* Create a maximum-size socket address
* Accepts: pointer to return maximum socket address length
* Returns: new, empty socket address of maximum size
*/
struct sockaddr *ip_newsockaddr (size_t *len)
{
return (struct sockaddr *) memset (fs_get (SADRLEN),0,*len = SADRLEN);
}
/* Stuff a socket address
* Accepts: address family
* IPv4 address
* length of address (always 4 in IPv4)
* port number
* pointer to return socket address length
* Returns: socket address or NIL if error
*/
struct sockaddr *ip_sockaddr (int family,void *adr,size_t adrlen,
unsigned short port,size_t *len)
{
struct sockaddr *sadr = ip_newsockaddr (len);
switch (family) { /* build socket address based upon family */
case AF_INET: /* IPv4 */
sadr->sa_family = PF_INET;
/* copy host address */
memcpy (&SADR4ADR (sadr),adr,adrlen);
/* copy port number in network format */
SADR4PORT (sadr) = htons (port);
*len = SADR4LEN;
break;
default: /* non-IP?? */
sadr->sa_family = PF_UNSPEC;
break;
}
return sadr;
}
/* Return name from socket address
* Accepts: socket address
* Returns: canonical name for that address or NIL if none
*/
char *ip_sockaddrtoname (struct sockaddr *sadr)
{
struct hostent *he;
return ((sadr->sa_family == PF_INET) &&
(he = gethostbyaddr ((char *) &SADR4ADR (sadr),ADR4LEN,AF_INET))) ?
(char *) he->h_name : NIL;
}
/* Return address from name
* Accepts: name or NIL to return next address
* pointer to previous/returned length
* pointer to previous/returned address family
* pointer to previous/returned canonical name
* pointer to previous/return state for next-address calls
* Returns: address with length/family/canonical updated if needed, or NIL
*/
void *ip_nametoaddr (char *name,size_t *len,int *family,char **canonical,
void **next)
{
char **adl,tmp[MAILTMPLEN];
struct hostent *he;
/* case-independent lookup */
if (name && (strlen (name) < MAILTMPLEN) &&
(he = gethostbyname (lcase (strcpy (tmp,name))))) {
adl = he->h_addr_list;
if (len) *len = he->h_length;
if (family) *family = he->h_addrtype;
if (canonical) *canonical = (char *) he->h_name;
if (next) *next = (void *) adl;
}
/* return next in series */
else if (next && (adl = (char **) *next)) *next = ++adl;
else adl = NIL; /* failure */
return adl ? (void *) *adl : NIL;
}
--- NEW FILE ---
mail_link (&imapdriver); /* link in the imap driver */
mail_link (&nntpdriver); /* link in the nntp driver */
mail_link (&pop3driver); /* link in the pop3 driver */
mail_link (&newsdriver); /* link in the news driver */
mail_link (&mhdriver); /* link in the mh driver */
mail_link (&mbxdriver); /* link in the mbx driver */
mail_link (&mtxdriver); /* link in the mtx driver */
mail_link (&tenexdriver); /* link in the tenex driver */
mail_link (&unixdriver); /* link in the unix driver */
mail_link (&dummydriver); /* link in the dummy driver */
/* auth_link (&auth_gss); don't link in the gss authenticator */
auth_link (&auth_md5); /* link in the md5 authenticator */
auth_link (&auth_pla); /* link in the pla authenticator */
auth_link (&auth_log); /* link in the log authenticator */
--- NEW FILE ---
extern DRIVER imapdriver;
extern DRIVER nntpdriver;
extern DRIVER pop3driver;
extern DRIVER mhdriver;
extern DRIVER mbxdriver;
extern DRIVER mtxdriver;
extern DRIVER tenexdriver;
extern DRIVER unixdriver;
extern DRIVER newsdriver;
extern DRIVER dummydriver;
extern AUTHENTICATOR auth_gss;
extern AUTHENTICATOR auth_md5;
extern AUTHENTICATOR auth_pla;
extern AUTHENTICATOR auth_log;
#define DEFAULTPROTO mbxproto
--- NEW FILE ---
/*
* Program: MH mail routines
*
* Author(s): Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: [EMAIL PROTECTED]
*
* Modified by: Vadim Zeitlin
* adopted mh.c for Win32
*
* Date: 23 February 1992
* Last Edited: 27 July 1999
*
* Copyright 1998 by the University of Washington
*
[...1008 lines suppressed...]
* Accepts: file name
* elt containing date
*/
void mh_setdate (char *file,MESSAGECACHE *elt)
{
struct _utimbuf times;
times.actime = time (0); /* atime is now */
times.modtime = mail_longdate (elt); /* modification time */
_utime (file,×); /* set the times */
}
/* Retrieve the MH path
*/
extern char *mh_getpath(void)
{
return mh_path;
}
/* vi: set ts=8 sta noet list sw=2: */
--- NEW FILE ---
/*
* Program: MH mail routines
*
* Author(s): Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: [EMAIL PROTECTED]
*
* Date: 23 February 1992
* Last Edited: 24 October 2000
*
* The IMAP toolkit provided in this Distribution is
* Copyright 2000 University of Washington.
* The full text of our legal notices is contained in the file called
* CPYRIGHT, included with this Distribution.
*/
/* Build parameters */
#define MHPROFILE ".mh_profile"
#define MHSEQUENCE ".mh_sequence"
#define MHPATH "Mail"
/* MH I/O stream local data */
typedef struct mh_local {
char *dir; /* spool directory name */
char *buf; /* temporary buffer */
unsigned long buflen; /* current size of temporary buffer */
unsigned long cachedtexts; /* total size of all cached texts */
time_t scantime; /* last time directory scanned */
} MHLOCAL;
/* Convenient access to local data */
#define LOCAL ((MHLOCAL *) stream->local)
/* Function prototypes */
DRIVER *mh_valid (char *name);
int mh_isvalid (char *name,char *tmp,long synonly);
void *mh_parameters (long function,void *value);
void mh_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);
void mh_list (MAILSTREAM *stream,char *ref,char *pat);
void mh_lsub (MAILSTREAM *stream,char *ref,char *pat);
void mh_list_work (MAILSTREAM *stream,char *dir,char *pat,long level);
long mh_subscribe (MAILSTREAM *stream,char *mailbox);
long mh_unsubscribe (MAILSTREAM *stream,char *mailbox);
long mh_create (MAILSTREAM *stream,char *mailbox);
long mh_delete (MAILSTREAM *stream,char *mailbox);
long mh_rename (MAILSTREAM *stream,char *old,char *newname);
MAILSTREAM *mh_open (MAILSTREAM *stream);
void mh_close (MAILSTREAM *stream,long options);
void mh_fast (MAILSTREAM *stream,char *sequence,long flags);
char *mh_header (MAILSTREAM *stream,unsigned long msgno,unsigned long *length,
long flags);
long mh_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);
long mh_ping (MAILSTREAM *stream);
void mh_check (MAILSTREAM *stream);
void mh_expunge (MAILSTREAM *stream);
long mh_copy (MAILSTREAM *stream,char *sequence,char *mailbox,
long options);
long mh_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);
int mh_select (struct _finddata_t *fileinfo);
int mh_numsort (const void *d1,const void *d2);
char *mh_file (char *dst,char *name);
long mh_canonicalize (char *pattern,char *ref,char *pat);
void mh_setdate (char *file,MESSAGECACHE *elt);
/* vi: set ts=8 sta noet list: */
--- NEW FILE ---
/*
* Program: News routines
*
* Author: Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: [EMAIL PROTECTED]
*
* Modified by: Vadim Zeitlin
* adopted news.c for Win32
*
* Date: 4 September 1991
* Last Edited: 24 October 2000
*
* The IMAP toolkit provided in this Distribution is
* Copyright 2000 University of Washington.
* The full text of our legal notices is contained in the file called
* CPYRIGHT, included with this Distribution.
*/
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
#include "mail.h"
#include "osdep.h"
#include <sys/stat.h>
#include "newsnt.h"
#include "misc.h"
#include "newsrc.h"
/* News routines */
/* Driver dispatch used by MAIL */
DRIVER newsdriver = {
"news", /* driver name */
/* driver flags */
DR_NEWS|DR_READONLY|DR_NOFAST|DR_NAMESPACE,
(DRIVER *) NIL, /* next driver */
news_valid, /* mailbox is valid for us */
news_parameters, /* manipulate parameters */
news_scan, /* scan mailboxes */
news_list, /* find mailboxes */
news_lsub, /* find subscribed mailboxes */
#include <fcntl.h> /* _O_RDONLY and friends */
#define O_RDONLY _O_RDONLY
news_subscribe, /* subscribe to mailbox */
news_unsubscribe, /* unsubscribe from mailbox */
news_create, /* create mailbox */
news_delete, /* delete mailbox */
news_rename, /* rename mailbox */
NIL, /* status of mailbox */
news_open, /* open mailbox */
news_close, /* close mailbox */
news_fast, /* fetch message "fast" attributes */
news_flags, /* fetch message flags */
NIL, /* fetch overview */
NIL, /* fetch message envelopes */
news_header, /* fetch message header */
news_text, /* fetch message body */
NIL, /* fetch partial message text */
NIL, /* unique identifier */
NIL, /* message number */
NIL, /* modify flags */
news_flagmsg, /* per-message modify flags */
NIL, /* search for message based on criteria */
NIL, /* sort messages */
NIL, /* thread messages */
news_ping, /* ping mailbox to see if still alive */
news_check, /* check for new messages */
news_expunge, /* expunge deleted messages */
news_copy, /* copy messages to another mailbox */
news_append, /* append string message to mailbox */
NIL /* garbage collect stream */
};
/* prototype stream */
MAILSTREAM newsproto = {&newsdriver};
/* News validate mailbox
* Accepts: mailbox name
* Returns: our driver if name is valid, NIL otherwise
*/
DRIVER *news_valid (char *name)
{
int fd;
char *s,*t,*u;
struct stat sbuf;
/* MAHOGANY: changed the code to return newsdriver if the active file doesn't
exist (we do it because leafnode doesn't have one yet we still want to use
Mahogany with it */
if ((name[0] == '#') && (name[1] == 'n') && (name[2] == 'e') &&
(name[3] == 'w') && (name[4] == 's') && (name[5] == '.') &&
!strchr (name,'/') ) {
if ( !stat ((char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL),&sbuf) &&
((fd = open ((char *) mail_parameters (NIL,GET_NEWSACTIVE,NIL),O_RDONLY,
NIL)) >= 0)) {
fstat (fd,&sbuf); /* get size of active file */
/* slurp in active file */
read (fd,t = s = (char *) fs_get (sbuf.st_size+1),sbuf.st_size);
s[sbuf.st_size] = '\0'; /* tie off file */
close (fd); /* flush file */
while (*t && (u = strchr (t,' '))) {
*u++ = '\0'; /* tie off at end of name */
if (!strcmp (name+6,t)) {
fs_give ((void **) &s); /* flush data */
return &newsdriver;
}
t = 1 + strchr (u,'\n'); /* next line */
}
fs_give ((void **) &s); /* flush data */
}
else {
return &newsdriver; /* assume it's a newsgroup, no way to check */
}
}
return NIL; /* return status */
}
/* News manipulate driver parameters
* Accepts: function code
* function-dependent value
* Returns: function-dependent return value
*/
void *news_parameters (long function,void *value)
{
return NIL;
}
/* News scan mailboxes
* Accepts: mail stream
* reference
* pattern to search
* string to scan
*/
void news_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents)
{
char tmp[MAILTMPLEN];
if (news_canonicalize (ref,pat,tmp))
mm_log ("Scan not valid for news mailboxes",ERROR);
}
/* News find list of newsgroups
* Accepts: mail stream
* reference
* pattern to search
*/
void news_list (MAILSTREAM *stream,char *ref,char *pat)
{
int fd;
int i;
char *s,*t,*u,*lcl,pattern[MAILTMPLEN],name[MAILTMPLEN];
struct stat sbuf;
if (!pat || !*pat) { /* empty pattern? */
if (news_canonicalize (ref,"*",pattern)) {
/* tie off name at root */
if (s = strchr (pattern,'.')) *++s = '\0';
else pattern[0] = '\0';
mm_list (stream,'.',pattern,LATT_NOSELECT);
}
}
if (news_canonicalize (ref,pat,pattern) &&
!stat ((char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL),&sbuf) &&
((fd = open ((char *) mail_parameters (NIL,GET_NEWSACTIVE,NIL),O_RDONLY,
NIL)) >= 0)) {
fstat (fd,&sbuf); /* get file size and read data */
read (fd,s = (char *) fs_get (sbuf.st_size + 1),sbuf.st_size);
close (fd); /* close file */
s[sbuf.st_size] = '\0'; /* tie off string */
/* point after prefix */
lcl = strcpy (name,"#news.") + 6;
i = strlen (pattern); /* length of pattern */
if (pattern[--i] != '%') i = 0;
if (t = strtok (s,"\n")) do if (u = strchr (t,' ')) {
*u = '\0'; /* tie off at end of name */
strcpy (lcl,t); /* make full form of name */
if (pmatch_full (name,pattern,'.')) mm_list (stream,'.',name,NIL);
else if (i && (u = strchr (name + i,'.'))) {
*u = '\0'; /* tie off at delimiter, see if matches */
if (pmatch_full (name,pattern,'.'))
mm_list (stream,'.',name,LATT_NOSELECT);
}
} while (t = strtok (NIL,"\n"));
fs_give ((void **) &s);
}
}
/* News find list of subscribed newsgroups
* Accepts: mail stream
* reference
* pattern to search
*/
void news_lsub (MAILSTREAM *stream,char *ref,char *pat)
{
char pattern[MAILTMPLEN];
/* return data from newsrc */
if (news_canonicalize (ref,pat,pattern)) newsrc_lsub (stream,pattern);
}
/* News canonicalize newsgroup name
* Accepts: reference
* pattern
* returned single pattern
* Returns: T on success, NIL on failure
*/
long news_canonicalize (char *ref,char *pat,char *pattern)
{
if (ref && *ref) { /* have a reference */
strcpy (pattern,ref); /* copy reference to pattern */
/* # overrides mailbox field in reference */
if (*pat == '#') strcpy (pattern,pat);
/* pattern starts, reference ends, with . */
else if ((*pat == '.') && (pattern[strlen (pattern) - 1] == '.'))
strcat (pattern,pat + 1); /* append, omitting one of the period */
else strcat (pattern,pat); /* anything else is just appended */
}
else strcpy (pattern,pat); /* just have basic name */
return ((pattern[0] == '#') && (pattern[1] == 'n') && (pattern[2] == 'e') &&
(pattern[3] == 'w') && (pattern[4] == 's') && (pattern[5] == '.') &&
!strchr (pattern,'/')) ? T : NIL;
}
/* News subscribe to mailbox
* Accepts: mail stream
* mailbox to add to subscription list
* Returns: T on success, NIL on failure
*/
long news_subscribe (MAILSTREAM *stream,char *mailbox)
{
return news_valid (mailbox) ? newsrc_update (stream,mailbox+6,':') : NIL;
}
/* NEWS unsubscribe to mailbox
* Accepts: mail stream
* mailbox to delete from subscription list
* Returns: T on success, NIL on failure
*/
long news_unsubscribe (MAILSTREAM *stream,char *mailbox)
{
return news_valid (mailbox) ? newsrc_update (stream,mailbox+6,'!') : NIL;
}
/* News create mailbox
* Accepts: mail stream
* mailbox name to create
* Returns: T on success, NIL on failure
*/
long news_create (MAILSTREAM *stream,char *mailbox)
{
return NIL; /* never valid for News */
}
/* News delete mailbox
* mailbox name to delete
* Returns: T on success, NIL on failure
*/
long news_delete (MAILSTREAM *stream,char *mailbox)
{
return NIL; /* never valid for News */
}
/* News rename mailbox
* Accepts: mail stream
* old mailbox name
* new mailbox name
* Returns: T on success, NIL on failure
*/
long news_rename (MAILSTREAM *stream,char *old,char *newname)
{
return NIL; /* never valid for News */
}
/* News status of mailbox default handler
* Accepts: mail stream
* mailbox name
* status flags
* Returns: T on success, NIL on failure
*/
long news_status (MAILSTREAM *stream,char *mbx,long flags)
{
MAILSTATUS status;
unsigned long i;
MAILSTREAM *tstream = NIL;
/* make temporary stream (unless this mbx) */
if ((!stream || strcmp (stream->mailbox,mbx)) &&
!(stream = tstream = mail_open (NIL,mbx,OP_READONLY|OP_SILENT)))
return NIL;
status.flags = flags; /* return status values */
status.messages = stream->nmsgs;
status.recent = stream->recent;
if (flags & SA_UNSEEN) /* must search to get unseen messages */
for (i = 1,status.unseen = 0; i <= stream->nmsgs; i++)
if (!mail_elt (stream,i)->deleted) status.unseen++;
status.uidnext = stream->uid_last + 1;
status.uidvalidity = stream->uid_validity;
/* pass status to main program */
mm_status (stream,mbx,&status);
if (tstream) mail_close (tstream);
return T; /* success */
}
/* News open
* Accepts: stream to open
* Returns: stream on success, NIL on failure
*/
MAILSTREAM *news_open (MAILSTREAM *stream)
{
long i,nmsgs;
char c = NIL,*s,tmp[MAILTMPLEN];
struct _finddata_t **names = NIL;
/* return prototype for OP_PROTOTYPE call */
if (!stream) return &newsproto;
if (stream->local) fatal ("news recycle stream");
/* build directory name */
sprintf (s = tmp,"%s/%s",(char *) mail_parameters (NIL,GET_NEWSSPOOL,NIL),
stream->mailbox + 6);
while (s = strchr (s,'.')) *s = '/';
/* scan directory */
if ((nmsgs = scandir (tmp,&names,news_select,news_numsort)) >= 0) {
mail_exists (stream,nmsgs); /* notify upper level that messages exist */
stream->local = fs_get (sizeof (NEWSLOCAL));
LOCAL->dirty = NIL; /* no update to .newsrc needed yet */
LOCAL->dir = cpystr (tmp); /* copy directory name for later */
/* make temporary buffer */
LOCAL->buf = (char *) fs_get ((LOCAL->buflen = MAXMESSAGESIZE) + 1);
LOCAL->name = cpystr (stream->mailbox + 6);
for (i = 0; i < nmsgs; ++i) {
stream->uid_last = mail_elt (stream,i+1)->private.uid =
atoi (names[i]->name);
fs_give ((void **) &names[i]);
}
s = (void *) names; /* stupid language */
fs_give ((void **) &s); /* free directory */
LOCAL->cachedtexts = 0; /* no cached texts */
stream->sequence++; /* bump sequence number */
stream->rdonly = stream->perm_deleted = T;
/* UIDs are always valid */
stream->uid_validity = 0xbeefface;
/* read .newsrc entries */
mail_recent (stream,newsrc_read (LOCAL->name,stream));
/* notify if empty newsgroup */
if (!(stream->nmsgs || stream->silent)) {
sprintf (tmp,"Newsgroup %s is empty",LOCAL->name);
mm_log (tmp,WARN);
}
}
else mm_log ("Unable to scan newsgroup spool directory",ERROR);
return LOCAL ? stream : NIL; /* if stream is alive, return to caller */
}
/* News file name selection test
* Accepts: candidate directory entry
* Returns: T to use file name, NIL to skip it
*/
int news_select (struct _finddata_t *fileinfo)
{
char c;
char *s = fileinfo->name;
while (c = *s++) if (!isdigit (c)) return NIL;
return T;
}
/* News file name comparision
* Accepts: first candidate directory entry
* second candidate directory entry
* Returns: negative if d1 < d2, 0 if d1 == d2, postive if d1 > d2
*/
int news_numsort (const void *d1,const void *d2)
{
return atoi ((*(struct _finddata_t **) d1)->name) -
atoi ((*(struct _finddata_t **) d2)->name);
}
/* News close
* Accepts: MAIL stream
* option flags
*/
void news_close (MAILSTREAM *stream,long options)
{
if (LOCAL) { /* only if a file is open */
news_check (stream); /* dump final checkpoint */
if (LOCAL->dir) fs_give ((void **) &LOCAL->dir);
/* free local scratch buffer */
if (LOCAL->buf) fs_give ((void **) &LOCAL->buf);
if (LOCAL->name) fs_give ((void **) &LOCAL->name);
/* nuke the local data */
fs_give ((void **) &stream->local);
stream->dtb = NIL; /* log out the DTB */
}
}
/* News fetch fast information
* Accepts: MAIL stream
* sequence
* option flags
*/
void news_fast (MAILSTREAM *stream,char *sequence,long flags)
{
unsigned long i,j;
/* ugly and slow */
if (stream && LOCAL && ((flags & FT_UID) ?
mail_uid_sequence (stream,sequence) :
mail_sequence (stream,sequence)))
for (i = 1; i <= stream->nmsgs; i++)
if (mail_elt (stream,i)->sequence) news_header (stream,i,&j,NIL);
}
/* News fetch flags
* Accepts: MAIL stream
* sequence
* option flags
*/
void news_flags (MAILSTREAM *stream,char *sequence,long flags)
{
unsigned long i;
if ((flags & FT_UID) ? /* validate all elts */
mail_uid_sequence (stream,sequence) : mail_sequence (stream,sequence))
for (i = 1; i <= stream->nmsgs; i++) mail_elt (stream,i)->valid = T;
}
/* News fetch message header
* Accepts: MAIL stream
* message # to fetch
* pointer to returned header text length
* option flags
* Returns: message header in RFC822 format
*/
char *news_header (MAILSTREAM *stream,unsigned long msgno,
unsigned long *length,long flags)
{
unsigned long i,hdrsize;
int fd;
char *t;
struct stat sbuf;
struct tm *tm;
MESSAGECACHE *elt;
*length = 0; /* default to empty */
if (flags & FT_UID) return "";/* UID call "impossible" */
/* get elt */
(elt = mail_elt (stream,msgno))->valid = T;
if (!elt->private.msg.header.text.data) {
/* build message file name */
sprintf (LOCAL->buf,"%s/%lu",LOCAL->dir,elt->private.uid);
if ((fd = open (LOCAL->buf,O_RDONLY,NIL)) < 0) return "";
fstat (fd,&sbuf); /* get size of message */
/* make plausible IMAPish date string */
tm = gmtime (&sbuf.st_mtime);
elt->day = tm->tm_mday; elt->month = tm->tm_mon + 1;
elt->year = tm->tm_year + 1900 - BASEYEAR;
elt->hours = tm->tm_hour; elt->minutes = tm->tm_min;
elt->seconds = tm->tm_sec;
elt->zhours = 0; elt->zminutes = 0;
/* is buffer big enough? */
if ((unsigned)sbuf.st_size > LOCAL->buflen) {
fs_give ((void **) &LOCAL->buf);
LOCAL->buf = (char *) fs_get ((LOCAL->buflen = sbuf.st_size) + 1);
}
/* slurp message */
read (fd,LOCAL->buf,sbuf.st_size);
/* tie off file */
LOCAL->buf[sbuf.st_size] = '\0';
close (fd); /* flush message file */
/* find end of header */
for (i = 0,t = LOCAL->buf; *t && !(i && (*t == '\n')); i = (*t++ == '\n'));
/* number of header bytes */
hdrsize = (*t ? ++t : t) - LOCAL->buf;
elt->rfc822_size = /* size of entire message in CRLF form */
(elt->private.msg.header.text.size =
strcrlfcpy ((char **) &elt->private.msg.header.text.data,&i,LOCAL->buf,
hdrsize)) +
(elt->private.msg.text.text.size =
strcrlfcpy ((char **) &elt->private.msg.text.text.data,&i,t,
sbuf.st_size - hdrsize));
}
*length = elt->private.msg.header.text.size;
return (char *) elt->private.msg.header.text.data;
}
/* News fetch message text (body only)
* Accepts: MAIL stream
* message # to fetch
* pointer to returned stringstruct
* option flags
* Returns: T on success, NIL on failure
*/
long news_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags)
{
unsigned long i;
MESSAGECACHE *elt;
/* UID call "impossible" */
if (flags & FT_UID) return NIL;
elt = mail_elt (stream,msgno);/* get elt */
/* snarf message if don't have it yet */
if (!elt->private.msg.text.text.data) {
news_header (stream,msgno,&i,flags);
if (!elt->private.msg.text.text.data) return NIL;
}
if (!(flags & FT_PEEK)) { /* mark as seen */
mail_elt (stream,msgno)->seen = T;
mm_flags (stream,msgno);
}
if (!elt->private.msg.text.text.data) return NIL;
INIT (bs,mail_string,elt->private.msg.text.text.data,
elt->private.msg.text.text.size);
return T;
}
/* News per-message modify flag
* Accepts: MAIL stream
* message cache element
*/
void news_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt)
{
if (!LOCAL->dirty) { /* only bother checking if not dirty yet */
if (elt->valid) { /* if done, see if deleted changed */
if (elt->sequence != elt->deleted) LOCAL->dirty = T;
elt->sequence = T; /* leave the sequence set */
}
/* note current setting of deleted flag */
else elt->sequence = elt->deleted;
}
}
/* News ping mailbox
* Accepts: MAIL stream
* Returns: T if stream alive, else NIL
*/
long news_ping (MAILSTREAM *stream)
{
return T; /* always alive */
}
/* News check mailbox
* Accepts: MAIL stream
*/
void news_check (MAILSTREAM *stream)
{
/* never do if no updates */
if (LOCAL->dirty) newsrc_write (LOCAL->name,stream);
LOCAL->dirty = NIL;
}
/* News expunge mailbox
* Accepts: MAIL stream
*/
void news_expunge (MAILSTREAM *stream)
{
if (!stream->silent) mm_log ("Expunge ignored on news",NIL);
}
/* News copy message(s)
* Accepts: MAIL stream
* sequence
* destination mailbox
* option flags
* Returns: T if copy successful, else NIL
*/
long news_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options)
{
mailproxycopy_t pc =
(mailproxycopy_t) mail_parameters (stream,GET_MAILPROXYCOPY,NIL);
if (pc) return (*pc) (stream,sequence,mailbox,options);
mm_log ("Copy not valid for News",ERROR);
return NIL;
}
/* News append message from stringstruct
* Accepts: MAIL stream
* destination mailbox
* append callback function
* data for callback
* Returns: T if append successful, else NIL
*/
long news_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data)
{
mm_log ("Append not valid for news",ERROR);
return NIL;
}
/* vi: set ts=8 sta noet list sw=2: */
--- NEW FILE ---
/*
* Program: Netnews mail routines
*
* Author: Mark Crispin
* Networks and Distributed Computing
* Computing & Communications
* University of Washington
* Administration Building, AG-44
* Seattle, WA 98195
* Internet: [EMAIL PROTECTED]
*
* Modified by: Vadim Zeitlin
* adopted news.h for Win32
*
* Date: 4 September 1991
* Last Edited: 24 October 2000
*
* The IMAP toolkit provided in this Distribution is
* Copyright 2000 University of Washington.
* The full text of our legal notices is contained in the file called
* CPYRIGHT, included with this Distribution.
*/
/* NEWS I/O stream local data */
typedef struct news_local {
unsigned int dirty : 1; /* disk copy of .newsrc needs updating */
char *dir; /* spool directory name */
char *name; /* local mailbox name */
char *buf; /* scratch buffer */
unsigned long buflen; /* current size of scratch buffer */
unsigned long cachedtexts; /* total size of all cached texts */
} NEWSLOCAL;
/* Convenient access to local data */
#define LOCAL ((NEWSLOCAL *) stream->local)
/* Function prototypes */
DRIVER *news_valid (char *name);
DRIVER *news_isvalid (char *name,char *mbx);
void *news_parameters (long function,void *value);
void news_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents);
void news_list (MAILSTREAM *stream,char *ref,char *pat);
void news_lsub (MAILSTREAM *stream,char *ref,char *pat);
long news_canonicalize (char *ref,char *pat,char *pattern);
long news_subscribe (MAILSTREAM *stream,char *mailbox);
long news_unsubscribe (MAILSTREAM *stream,char *mailbox);
long news_create (MAILSTREAM *stream,char *mailbox);
long news_delete (MAILSTREAM *stream,char *mailbox);
long news_rename (MAILSTREAM *stream,char *old,char *newname);
long news_status (MAILSTREAM *stream,char *mbx,long flags);
MAILSTREAM *news_open (MAILSTREAM *stream);
int news_select (struct _finddata_t *fileinfo);
int news_numsort (const void *d1,const void *d2);
void news_close (MAILSTREAM *stream,long options);
void news_fast (MAILSTREAM *stream,char *sequence,long flags);
void news_flags (MAILSTREAM *stream,char *sequence,long flags);
char *news_header (MAILSTREAM *stream,unsigned long msgno,
unsigned long *length,long flags);
long news_text (MAILSTREAM *stream,unsigned long msgno,STRING *bs,long flags);
void news_flagmsg (MAILSTREAM *stream,MESSAGECACHE *elt);
long news_ping (MAILSTREAM *stream);
void news_check (MAILSTREAM *stream);
void news_expunge (MAILSTREAM *stream);
long news_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options);
long news_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data);
Index: os_nt.c
===================================================================
RCS file: /cvsroot/mahogany/M/lib/imap/src/osdep/nt/os_nt.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -b -u -2 -r1.1.1.1 -r1.2
--- os_nt.c 24 Apr 2004 21:46:54 -0000 1.1.1.1
+++ os_nt.c 24 Apr 2004 23:12:57 -0000 1.2
@@ -39,2 +39,46 @@
#include "ssl_nt.c"
#include "tcp_nt.c"
+
+/* Emulator for BSD scandir() call
+ * Accepts: directory name
+ * destination pointer of names array
+ * selection function
+ * comparison function
+ * Returns: number of elements in the array or -1 if error
+ */
+
+int scandir (char *dirname,struct _finddata_t ***namelist,select_t select,
+ compar_t compar)
+{
+ struct _finddata_t *p, d, **names;
+ int nitems;
+ long nlmax;
+ long hDir;
+ char *filemask = (char *)fs_get((strlen(dirname) + 5) * sizeof(char));
+ strcpy(filemask, dirname);
+ strcat(filemask, "/*.*");
+ hDir = _findfirst(filemask, &d);/* open directory */
+ fs_give((void **)&filemask);
+ if (hDir == -1) return -1;
+ nlmax = 100; /* FIXME how to get number of files in dir? */
+ names = (struct _finddata_t **) fs_get (nlmax * sizeof (struct _finddata_t *));
+ nitems = 0; /* initially none found */
+ do { /* loop over all files */
+ /* matches select criterion? */
+ if (select && !(*select) (&d)) continue;
+ p = (struct _finddata_t *)fs_get(sizeof(d));
+ strcpy (p->name,d.name);
+ if (++nitems >= nlmax) { /* if out of space, try bigger guesstimate */
+ nlmax *= 2; /* double it */
+ fs_resize ((void **) &names,nlmax * sizeof (struct _finddata_t *));
+ }
+ names[nitems - 1] = p; /* store this file there */
+ }
+ while (_findnext(hDir, &d) == 0);
+ _findclose(hDir); /* done with directory */
+ /* sort if necessary */
+ if (nitems && compar) qsort (names,nitems,sizeof (struct _finddata_t *),compar);
+ *namelist = names; /* return directory */
+ return nitems; /* and size */
+}
+
Index: os_nt.h
===================================================================
RCS file: /cvsroot/mahogany/M/lib/imap/src/osdep/nt/os_nt.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -b -u -2 -r1.1.1.1 -r1.2
--- os_nt.h 24 Apr 2004 21:46:53 -0000 1.1.1.1
+++ os_nt.h 24 Apr 2004 23:12:57 -0000 1.2
@@ -43,2 +43,6 @@
#undef noErr
#undef MAC
+
+typedef int (*select_t) (struct _finddata_t *name);
+typedef int (*compar_t) (const void *d1,const void *d2);
+int scandir (char *dirname,struct _finddata_t ***namelist,select_t select, compar_t
compar);
-------------------------------------------------------
This SF.net email is sponsored by: The Robotic Monkeys at ThinkGeek
For a limited time only, get FREE Ground shipping on all orders of $35
or more. Hurry up and shop folks, this offer expires April 30th!
http://www.thinkgeek.com/freeshipping/?cpg=12297
_______________________________________________
Mahogany-cvsupdates mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/mahogany-cvsupdates