dummy.c | dummy.c | |||
---|---|---|---|---|
/* ======================================================================== | ||||
* Copyright 1988-2006 University of Washington | ||||
* | ||||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||||
* you may not use this file except in compliance with the License. | ||||
* You may obtain a copy of the License at | ||||
* | ||||
* http://www.apache.org/licenses/LICENSE-2.0 | ||||
* | ||||
* | ||||
* ======================================================================== | ||||
*/ | ||||
/* | /* | |||
* Program: Dummy routines | * Program: Dummy routines | |||
* | * | |||
* Author: Mark Crispin | * Author: Mark Crispin | |||
* Networks and Distributed Computing | * Networks and Distributed Computing | |||
* Computing & Communications | * Computing & Communications | |||
* University of Washington | * University of Washington | |||
* Administration Building, AG-44 | * Administration Building, AG-44 | |||
* Seattle, WA 98195 | * Seattle, WA 98195 | |||
* Internet: MRC@CAC.Washington.EDU | * Internet: MRC@CAC.Washington.EDU | |||
* | * | |||
* Date: 9 May 1991 | * Date: 9 May 1991 | |||
* Last Edited: 10 November 2004 | * Last Edited: 30 August 2006 | |||
* | ||||
* The IMAP toolkit provided in this Distribution is | ||||
* Copyright 1988-2004 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 <stdio.h> | |||
#include <ctype.h> | #include <ctype.h> | |||
#include <errno.h> | #include <errno.h> | |||
extern int errno; /* just in case */ | extern int errno; /* just in case */ | |||
#include "mail.h" | #include "mail.h" | |||
#include "osdep.h" | #include "osdep.h" | |||
#include <pwd.h> | #include <pwd.h> | |||
#include <sys/stat.h> | #include <sys/stat.h> | |||
#include "dummy.h" | #include "dummy.h" | |||
#include "misc.h" | #include "misc.h" | |||
#include "mx.h" /* highly unfortunate */ | ||||
/* Function prototypes */ | /* Function prototypes */ | |||
DRIVER *dummy_valid (char *name); | DRIVER *dummy_valid (char *name); | |||
void *dummy_parameters (long function,void *value); | void *dummy_parameters (long function,void *value); | |||
void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents , | void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents , | |||
long level); | long level); | |||
long dummy_listed (MAILSTREAM *stream,char delimiter,char *name, | long dummy_listed (MAILSTREAM *stream,char delimiter,char *name, | |||
long attributes,char *contents); | long attributes,char *contents); | |||
long dummy_subscribe (MAILSTREAM *stream,char *mailbox); | long dummy_subscribe (MAILSTREAM *stream,char *mailbox); | |||
MAILSTREAM *dummy_open (MAILSTREAM *stream); | MAILSTREAM *dummy_open (MAILSTREAM *stream); | |||
void dummy_close (MAILSTREAM *stream,long options); | void dummy_close (MAILSTREAM *stream,long options); | |||
long dummy_ping (MAILSTREAM *stream); | long dummy_ping (MAILSTREAM *stream); | |||
void dummy_check (MAILSTREAM *stream); | void dummy_check (MAILSTREAM *stream); | |||
void dummy_expunge (MAILSTREAM *stream); | long dummy_expunge (MAILSTREAM *stream,char *sequence,long options); | |||
long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long optio ns); | long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long optio ns); | |||
long dummy_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data) ; | long dummy_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data) ; | |||
/* Dummy routines */ | /* Dummy routines */ | |||
/* Driver dispatch used by MAIL */ | /* Driver dispatch used by MAIL */ | |||
DRIVER dummydriver = { | DRIVER dummydriver = { | |||
"dummy", /* driver name */ | "dummy", /* driver name */ | |||
DR_LOCAL|DR_MAIL, /* driver flags */ | DR_LOCAL|DR_MAIL, /* driver flags */ | |||
(DRIVER *) NIL, /* next driver */ | (DRIVER *) NIL, /* next driver */ | |||
skipping to change at line 222 | skipping to change at line 229 | |||
* Accepts: mail stream | * Accepts: mail stream | |||
* mailbox to add to subscription list | * mailbox to add to subscription list | |||
* Returns: T on success, NIL on failure | * Returns: T on success, NIL on failure | |||
*/ | */ | |||
long dummy_subscribe (MAILSTREAM *stream,char *mailbox) | long dummy_subscribe (MAILSTREAM *stream,char *mailbox) | |||
{ | { | |||
char *s,tmp[MAILTMPLEN]; | char *s,tmp[MAILTMPLEN]; | |||
struct stat sbuf; | struct stat sbuf; | |||
/* must be valid local mailbox */ | /* must be valid local mailbox */ | |||
if ((s = mailboxfile (tmp,mailbox)) && *s && !stat (s,&sbuf) | if ((s = mailboxfile (tmp,mailbox)) && *s && !stat (s,&sbuf) && | |||
#if 0 /* disable this temporarily for Netscape */ | ((sbuf.st_mode & S_IFMT) == S_IFREG)) return sm_subscribe (mailbox); | |||
&& | ||||
((sbuf.st_mode & S_IFMT) == S_IFREG) | ||||
#endif | ||||
) return sm_subscribe (mailbox); | ||||
sprintf (tmp,"Can't subscribe %.80s: not a mailbox",mailbox); | sprintf (tmp,"Can't subscribe %.80s: not a mailbox",mailbox); | |||
MM_LOG (tmp,ERROR); | MM_LOG (tmp,ERROR); | |||
return NIL; | return NIL; | |||
} | } | |||
/* Dummy list mailboxes worker routine | /* Dummy list mailboxes worker routine | |||
* Accepts: mail stream | * Accepts: mail stream | |||
* directory name to search | * directory name to search | |||
* search pattern | * search pattern | |||
* string to scan | * string to scan | |||
* search level | * search level | |||
*/ | */ | |||
void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents , | void dummy_list_work (MAILSTREAM *stream,char *dir,char *pat,char *contents , | |||
long level) | long level) | |||
{ | { | |||
DRIVER *drivers; | ||||
dirfmttest_t dt; | ||||
DIR *dp; | DIR *dp; | |||
struct direct *d; | struct direct *d; | |||
struct stat sbuf; | struct stat sbuf; | |||
int ismx; | ||||
char tmp[MAILTMPLEN]; | char tmp[MAILTMPLEN]; | |||
size_t len = 0; | ||||
/* punt if bogus name */ | /* punt if bogus name */ | |||
if (!mailboxdir (tmp,dir,NIL)) return; | if (!mailboxdir (tmp,dir,NIL)) return; | |||
if (dp = opendir (tmp)) { /* do nothing if can't open directory */ | if (dp = opendir (tmp)) { /* do nothing if can't open directory */ | |||
/* list it if not at top-level */ | /* see if a non-namespace directory format * | |||
/ | ||||
for (drivers = (DRIVER *) mail_parameters (NIL,GET_DRIVERS,NIL), dt = N | ||||
IL; | ||||
!dt && drivers; drivers = drivers->next) | ||||
if (!(drivers->flags & DR_DISABLE) && (drivers->flags & DR_DIRFMT) && | ||||
(*drivers->valid) (tmp)) | ||||
dt = mail_parameters ((*drivers->open) (NIL),GET_DIRFMTTEST,NIL); | ||||
/* list it if at top-level */ | ||||
if (!level && dir && pmatch_full (dir,pat,'/')) | if (!level && dir && pmatch_full (dir,pat,'/')) | |||
dummy_listed (stream,'/',dir,LATT_NOSELECT,contents); | dummy_listed (stream,'/',dir,dt ? NIL : LATT_NOSELECT,contents); | |||
/* scan directory, ignore . and .. */ | /* scan directory, ignore . and .. */ | |||
ismx = (!stat (strcat (tmp,MXINDEXNAME),&sbuf) && | if (!dir || dir[(len = strlen (dir)) - 1] == '/') while (d = readdir (d | |||
((sbuf.st_mode & S_IFMT) == S_IFREG)); | p)) | |||
if (!dir || dir[strlen (dir) - 1] == '/') while (d = readdir (dp)) | if ((!(dt && (*dt) (d->d_name))) && | |||
if (((d->d_name[0] != '.') || | ((d->d_name[0] != '.') || | |||
(((int) mail_parameters (NIL,GET_HIDEDOTFILES,NIL)) ? NIL : | (((int) mail_parameters (NIL,GET_HIDEDOTFILES,NIL)) ? NIL : | |||
(d->d_name[1] && (((d->d_name[1] != '.') || d->d_name[2]) && | (d->d_name[1] && (((d->d_name[1] != '.') || d->d_name[2]))))) && | |||
strcmp (d->d_name+1,MXINDEXNAME+2))))) && | ((len + strlen (d->d_name)) <= NETMAXMBX)) { | |||
(strlen (d->d_name) <= NETMAXMBX)) { | ||||
/* see if name is useful */ | /* see if name is useful */ | |||
if (dir) sprintf (tmp,"%s%s",dir,d->d_name); | if (dir) sprintf (tmp,"%s%s",dir,d->d_name); | |||
else strcpy (tmp,d->d_name); | else strcpy (tmp,d->d_name); | |||
/* make sure useful and can get info */ | /* make sure useful and can get info */ | |||
if ((pmatch_full (tmp,pat,'/') || | if ((pmatch_full (tmp,pat,'/') || | |||
pmatch_full (strcat (tmp,"/"),pat,'/') || dmatch (tmp,pat,'/')) && | pmatch_full (strcat (tmp,"/"),pat,'/') || dmatch (tmp,pat,'/')) && | |||
mailboxdir (tmp,dir,d->d_name) && tmp[0] && !stat (tmp,&sbuf)) { | mailboxdir (tmp,dir,d->d_name) && tmp[0] && !stat (tmp,&sbuf)) { | |||
/* now make name we'd return */ | /* now make name we'd return */ | |||
if (dir) sprintf (tmp,"%s%s",dir,d->d_name); | if (dir) sprintf (tmp,"%s%s",dir,d->d_name); | |||
else strcpy (tmp,d->d_name); | else strcpy (tmp,d->d_name); | |||
skipping to change at line 289 | skipping to change at line 298 | |||
} | } | |||
/* try again with trailing / */ | /* try again with trailing / */ | |||
else if (pmatch_full (strcat (tmp,"/"),pat,'/') && | else if (pmatch_full (strcat (tmp,"/"),pat,'/') && | |||
!dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents)) | !dummy_listed (stream,'/',tmp,LATT_NOSELECT,contents)) | |||
break; | break; | |||
if (dmatch (tmp,pat,'/') && | if (dmatch (tmp,pat,'/') && | |||
(level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))) | (level < (long) mail_parameters (NIL,GET_LISTMAXLEVEL,NIL))) | |||
dummy_list_work (stream,tmp,pat,contents,level+1); | dummy_list_work (stream,tmp,pat,contents,level+1); | |||
break; | break; | |||
case S_IFREG: /* ordinary name */ | case S_IFREG: /* ordinary name */ | |||
/* ignore all-digit names from mx */ | ||||
/* Must use ctime for systems that don't update mtime properly * / | /* Must use ctime for systems that don't update mtime properly * / | |||
if (!(ismx && mx_select (d)) && pmatch_full (tmp,pat,'/') && | if (pmatch_full (tmp,pat,'/') && compare_cstring (tmp,"INBOX")) | |||
compare_cstring (tmp,"INBOX")) | ||||
dummy_listed (stream,'/',tmp,LATT_NOINFERIORS + | dummy_listed (stream,'/',tmp,LATT_NOINFERIORS + | |||
((sbuf.st_size && (sbuf.st_atime < sbuf.st_ctime ))? | ((sbuf.st_size && (sbuf.st_atime < sbuf.st_ctime ))? | |||
LATT_MARKED : LATT_UNMARKED),contents); | LATT_MARKED : LATT_UNMARKED),contents); | |||
break; | break; | |||
} | } | |||
} | } | |||
} | } | |||
closedir (dp); /* all done, flush directory */ | closedir (dp); /* all done, flush directory */ | |||
} | } | |||
} | } | |||
/* Scan file for contents | /* Scan file for contents | |||
* Accepts: driver to use | ||||
* file name | ||||
* desired contents | ||||
* length of contents | ||||
* size of file | ||||
* Returns: NIL if contents not found, T if found | ||||
*/ | ||||
long scan_contents (DRIVER *dtb,char *name,char *contents, | ||||
unsigned long csiz,unsigned long fsiz) | ||||
{ | ||||
scancontents_t sc = dtb ? | ||||
(scancontents_t) (*dtb->parameters) (GET_SCANCONTENTS,NIL) : NIL; | ||||
return (*(sc ? sc : dummy_scan_contents)) (name,contents,csiz,fsiz); | ||||
} | ||||
/* Scan file for contents | ||||
* Accepts: file name | * Accepts: file name | |||
* desired contents | * desired contents | |||
* length of contents | ||||
* size of file | ||||
* Returns: NIL if contents not found, T if found | * Returns: NIL if contents not found, T if found | |||
*/ | */ | |||
#define BUFSIZE 4*MAILTMPLEN | #define BUFSIZE 4*MAILTMPLEN | |||
long dummy_scan_contents (char *name,char *contents,unsigned long csiz, | long dummy_scan_contents (char *name,char *contents,unsigned long csiz, | |||
unsigned long fsiz) | unsigned long fsiz) | |||
{ | { | |||
int fd; | int fd; | |||
unsigned long ssiz,bsiz; | unsigned long ssiz,bsiz; | |||
skipping to change at line 335 | skipping to change at line 361 | |||
(unsigned char *) contents,csiz)) break; | (unsigned char *) contents,csiz)) break; | |||
memcpy (buf,buf+BUFSIZE,ssiz); | memcpy (buf,buf+BUFSIZE,ssiz); | |||
fsiz -= bsiz; /* note that we read that much */ | fsiz -= bsiz; /* note that we read that much */ | |||
} | } | |||
fs_give ((void **) &buf); /* flush buffer */ | fs_give ((void **) &buf); /* flush buffer */ | |||
close (fd); /* finished with file */ | close (fd); /* finished with file */ | |||
if (fsiz) return T; /* found */ | if (fsiz) return T; /* found */ | |||
} | } | |||
return NIL; /* not found */ | return NIL; /* not found */ | |||
} | } | |||
/* Mailbox found | /* Mailbox found | |||
* Accepts: MAIL stream | * Accepts: MAIL stream | |||
* hierarchy delimiter | * hierarchy delimiter | |||
* mailbox name | * mailbox name | |||
* attributes | * attributes | |||
* contents to search before calling mm_list() | * contents to search before calling mm_list() | |||
* Returns: NIL if should abort hierarchy search, else T (currently always) | * Returns: NIL if should abort hierarchy search, else T (currently always) | |||
*/ | */ | |||
long dummy_listed (MAILSTREAM *stream,char delimiter,char *name, | long dummy_listed (MAILSTREAM *stream,char delimiter,char *name, | |||
skipping to change at line 359 | skipping to change at line 384 | |||
unsigned long csiz; | unsigned long csiz; | |||
struct stat sbuf; | struct stat sbuf; | |||
char *s,tmp[MAILTMPLEN]; | char *s,tmp[MAILTMPLEN]; | |||
/* don't \NoSelect dir if it has a driver */ | /* don't \NoSelect dir if it has a driver */ | |||
if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) && | if ((attributes & LATT_NOSELECT) && (d = mail_valid (NIL,name,NIL)) && | |||
(d != &dummydriver)) attributes &= ~LATT_NOSELECT; | (d != &dummydriver)) attributes &= ~LATT_NOSELECT; | |||
if (!contents || /* notify main program */ | if (!contents || /* notify main program */ | |||
(!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) && | (!(attributes & LATT_NOSELECT) && (csiz = strlen (contents)) && | |||
(s = mailboxfile (tmp,name)) && | (s = mailboxfile (tmp,name)) && | |||
(*s || (s = mail_parameters (NIL,GET_INBOXPATH,tmp))) && | (*s || (s = mail_parameters (NIL,GET_INBOXPATH,tmp))) && | |||
!stat (s,&sbuf) && (csiz <= sbuf.st_size) && | !stat (s,&sbuf) && (d || (csiz <= sbuf.st_size)) && | |||
SAFE_SCAN_CONTENTS (d,tmp,contents,csiz,sbuf.st_size))) | SAFE_SCAN_CONTENTS (d,tmp,contents,csiz,sbuf.st_size))) | |||
mm_list (stream,delimiter,name,attributes); | mm_list (stream,delimiter,name,attributes); | |||
return T; | return T; | |||
} | } | |||
/* Dummy create mailbox | /* Dummy create mailbox | |||
* Accepts: mail stream | * Accepts: mail stream | |||
* mailbox name to create | * mailbox name to create | |||
* Returns: T on success, NIL on failure | * Returns: T on success, NIL on failure | |||
*/ | */ | |||
skipping to change at line 464 | skipping to change at line 489 | |||
* new mailbox name | * new mailbox name | |||
* Returns: T on success, NIL on failure | * Returns: T on success, NIL on failure | |||
*/ | */ | |||
long dummy_rename (MAILSTREAM *stream,char *old,char *newname) | long dummy_rename (MAILSTREAM *stream,char *old,char *newname) | |||
{ | { | |||
struct stat sbuf; | struct stat sbuf; | |||
char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN]; | char c,*s,tmp[MAILTMPLEN],mbx[MAILTMPLEN],oldname[MAILTMPLEN]; | |||
/* no trailing / allowed */ | /* no trailing / allowed */ | |||
if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) || | if (!dummy_file (oldname,old) || !(s = dummy_file (mbx,newname)) || | |||
((s = strrchr (s,'/')) && !s[1])) { | stat (oldname,&sbuf) || ((s = strrchr (s,'/')) && !s[1] && | |||
((sbuf.st_mode & S_IFMT) != S_IFDIR))) { | ||||
sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",old,newname); | sprintf (mbx,"Can't rename %.80s to %.80s: invalid name",old,newname); | |||
MM_LOG (mbx,ERROR); | MM_LOG (mbx,ERROR); | |||
return NIL; | return NIL; | |||
} | } | |||
if (s) { /* found superior to destination name? */ | if (s) { /* found a directory delimiter? */ | |||
c = *++s; /* remember first character of inferior */ | if (!s[1]) *s = '\0'; /* ignore trailing delimiter */ | |||
*s = '\0'; /* tie off to get just superior */ | else { /* found superior to destination name? */ | |||
c = *++s; /* remember first character of infer | ||||
ior */ | ||||
*s = '\0'; /* tie off to get just superior */ | ||||
/* name doesn't exist, create it */ | /* name doesn't exist, create it */ | |||
if ((stat (mbx,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) && | if ((stat (mbx,&sbuf) || ((sbuf.st_mode & S_IFMT) != S_IFDIR)) && | |||
!dummy_create (stream,mbx)) return NIL; | !dummy_create (stream,mbx)) return NIL; | |||
*s = c; /* restore full name */ | *s = c; /* restore full name */ | |||
} | ||||
} | } | |||
/* rename of non-ex INBOX creates dest */ | /* rename of non-ex INBOX creates dest */ | |||
if (!compare_cstring (old,"INBOX") && stat (oldname,&sbuf)) | if (!compare_cstring (old,"INBOX") && stat (oldname,&sbuf)) | |||
return dummy_create (NIL,mbx); | return dummy_create (NIL,mbx); | |||
if (rename (oldname,mbx)) { | if (rename (oldname,mbx)) { | |||
sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",old,newname, | sprintf (tmp,"Can't rename mailbox %.80s to %.80s: %.80s",old,newname, | |||
strerror (errno)); | strerror (errno)); | |||
MM_LOG (tmp,ERROR); | MM_LOG (tmp,ERROR); | |||
return NIL; | return NIL; | |||
} | } | |||
skipping to change at line 589 | skipping to change at line 618 | |||
* No-op for readonly files, since read/writer can expunge it from under us ! | * No-op for readonly files, since read/writer can expunge it from under us ! | |||
*/ | */ | |||
void dummy_check (MAILSTREAM *stream) | void dummy_check (MAILSTREAM *stream) | |||
{ | { | |||
dummy_ping (stream); /* invoke ping */ | dummy_ping (stream); /* invoke ping */ | |||
} | } | |||
/* Dummy expunge mailbox | /* Dummy expunge mailbox | |||
* Accepts: MAIL stream | * Accepts: MAIL stream | |||
* sequence to expunge if non-NIL | ||||
* expunge options | ||||
* Returns: T, always | ||||
*/ | */ | |||
void dummy_expunge (MAILSTREAM *stream) | long dummy_expunge (MAILSTREAM *stream,char *sequence,long options) | |||
{ | { | |||
/* return silently */ | return LONGT; | |||
} | } | |||
/* Dummy copy message(s) | /* Dummy copy message(s) | |||
* Accepts: MAIL stream | * Accepts: MAIL stream | |||
* sequence | * sequence | |||
* destination mailbox | * destination mailbox | |||
* options | * options | |||
* Returns: T if copy successful, else NIL | * Returns: T if copy successful, else NIL | |||
*/ | */ | |||
long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long optio ns) | long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long optio ns) | |||
skipping to change at line 665 | skipping to change at line 697 | |||
/* Dummy canonicalize name | /* Dummy canonicalize name | |||
* Accepts: buffer to write name | * Accepts: buffer to write name | |||
* reference | * reference | |||
* pattern | * pattern | |||
* Returns: T if success, NIL if failure | * Returns: T if success, NIL if failure | |||
*/ | */ | |||
long dummy_canonicalize (char *tmp,char *ref,char *pat) | long dummy_canonicalize (char *tmp,char *ref,char *pat) | |||
{ | { | |||
unsigned long i; | ||||
char *s; | ||||
if (ref) { /* preliminary reference check */ | if (ref) { /* preliminary reference check */ | |||
if (*ref == '{') return NIL;/* remote reference not allowed */ | if (*ref == '{') return NIL;/* remote reference not allowed */ | |||
else if (!*ref) ref = NIL; /* treat empty reference as no reference */ | else if (!*ref) ref = NIL; /* treat empty reference as no reference */ | |||
} | } | |||
switch (*pat) { | switch (*pat) { | |||
case '#': /* namespace name */ | case '#': /* namespace name */ | |||
if (mailboxfile (tmp,pat)) strcpy (tmp,pat); | if (mailboxfile (tmp,pat)) strcpy (tmp,pat); | |||
else return NIL; /* unknown namespace */ | else return NIL; /* unknown namespace */ | |||
break; | break; | |||
case '{': /* remote names not allowed */ | case '{': /* remote names not allowed */ | |||
skipping to change at line 693 | skipping to change at line 727 | |||
default: /* apply reference for all other names */ | default: /* apply reference for all other names */ | |||
if (!ref) strcpy (tmp,pat); /* just copy if no namespace */ | if (!ref) strcpy (tmp,pat); /* just copy if no namespace */ | |||
else if ((*ref != '#') || mailboxfile (tmp,ref)) { | else if ((*ref != '#') || mailboxfile (tmp,ref)) { | |||
/* wants root of name? */ | /* wants root of name? */ | |||
if (*pat == '/') strcpy (strchr (strcpy (tmp,ref),'/'),pat); | if (*pat == '/') strcpy (strchr (strcpy (tmp,ref),'/'),pat); | |||
/* otherwise just append */ | /* otherwise just append */ | |||
else sprintf (tmp,"%s%s",ref,pat); | else sprintf (tmp,"%s%s",ref,pat); | |||
} | } | |||
else return NIL; /* unknown namespace */ | else return NIL; /* unknown namespace */ | |||
} | } | |||
/* count wildcards */ | ||||
for (i = 0, s = tmp; *s; *s++) if ((*s == '*') || (*s == '%')) ++i; | ||||
if (i > MAXWILDCARDS) { /* ridiculous wildcarding? */ | ||||
MM_LOG ("Excessive wildcards in LIST/LSUB",ERROR); | ||||
return NIL; | ||||
} | ||||
return T; | return T; | |||
} | } | |||
End of changes. 26 change blocks. | ||||
38 lines changed or deleted | 82 lines changed or added | |||
This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ |