You are viewing a plain text version of this content. The canonical link for it is here.
Posted to apache-bugdb@apache.org by Marc Slemko <ma...@znep.com> on 1997/06/21 00:30:02 UTC
Re: mod_imap/759: imap should read too! (fwd)
The following reply was made to PR mod_imap/759; it has been noted by GNATS.
From: Marc Slemko <ma...@znep.com>
To: apbugs@apache.org
Subject: Re: mod_imap/759: imap should read <MAP><AREA>*</MAP> too! (fwd)
Date: Fri, 20 Jun 1997 16:20:07 -0600 (MDT)
---------- Forwarded message ----------
Date: 20 Jun 1997 21:04:24 -0000
From: warwick@mmm.co.uk
To: marc@hyperreal.com
Subject: Re: mod_imap/759: imap should read <MAP><AREA>*</MAP> too!
You wrote:
> It wasn't entirely clear, but I assume what you mean is
> to allow mod_imap to parse something in the form of a
Sorry, yes. That's exactly what I meant.
> Status changed to suspended until some good patches magically
> arrive or (more likely) mod_imap is rewritten or dropped.
I worked out that one-line <AREA> tags translate straight into
.map type lines, so it's rather simpler than I'd imagined, and
actually faster than writing the wretched Perl script.
Does this qualify as `magic'? :)
.-----------------------------------. mailto:warwick@mmm.co.uk
! Tim Baverstock, Internet SysAdmin ! http://www.mmm.co.uk [/~warwick]
`-----------------------------------' plan:"Level 1 RFC1149 compliance."
--- mod_imap.c.orig Fri Jun 20 16:13:14 1997
+++ mod_imap.c Fri Jun 20 21:57:40 1997
@@ -84,6 +84,8 @@
* Map format and menu concept courtesy Joshua Bell, jsbell@acs.ucalgary.ca.
*
* Mark Cox, mark@ukweb.com, Allow relative URLs even when no base specified
+ *
+ * Tim Baverstock, warwick@mmm.co.uk, Interpreted <AREA> tags to .map format.
*/
#include "httpd.h"
@@ -597,6 +599,70 @@
kill_timeout(r);
}
+/* -------------------------------------------------------------- */
+
+/* Return length of this quotedstring/barevalue, and its startpointer */
+
+int len_attr ( char *found, char **from ) {
+ char rej[]=" \t\n\r>";
+ if ( !found || !*found || !from ) return 0;
+ if ( *found=='"' || *found=='\'' ) {
+ rej[0]=*found; rej[1]=0; *from=found+1;
+ }
+ else
+ *from=found;
+ return strcspn(*from,rej);
+}
+
+/* Find *find, with optional =; return something interesting or NULL */
+
+char *find_attr ( char *from, char *find, char equals ) {
+ int findlen=strlen(find);
+ while ( *from && !isalpha(*from) ) from++;
+ while ( *from && strlen(from)>=findlen ) {
+ if ( !strncasecmp(from,find,findlen)
+ && !isalpha(from[findlen]) ) { /* isalpha's not really right */
+ char *p=from+findlen;
+ while ( isspace(*p) ) p++;
+ if ( equals ) {
+ if ( *p == '=' ) {
+ p++;
+ while ( isspace(*p) ) p++;
+ return p;
+ }
+ }
+ else {
+ return p;
+ }
+ }
+ if ( *from ) from++; /* Eat a char (okayed in while(*from)) */
+ while ( isalpha(*from) ) from++;
+ while ( isspace(*from) ) from++;
+ if ( *from == '=' ) {
+ int len; char *p;
+ from++;
+ while ( isspace(*from) ) from++;
+ len=len_attr(from,&p);
+ if ( ( *from=='"' || *from=='\'' ) && p[len+1] ) len++;
+ from=p+len;
+ }
+ while ( isspace(*from) ) from++;
+ }
+ return NULL;
+}
+
+/* Find *find after *from; copy its attribute to *to, with <nul> term */
+
+char *copy_attr ( char *from, char *find, char *to ) {
+ char *found=find_attr(from,find,(to?'=':0));
+ int len=len_attr(found,&from);
+ if ( !len || len>=SMALLBUF ) return NULL; /* Huh? */
+ strncpy(to,from,len); to[len]=0;
+ return found;
+}
+
+/* -------------------------------------------------------------- */
+
int imap_handler(request_rec *r)
{
char input[LARGEBUF] = {'\0'};
@@ -678,6 +744,93 @@
} /* blank lines and comments are ignored if we aren't printing a menu */
+
+ if (input[0]=='<') { /* Assume it's an AREA tag on one line */
+ /* Translate this into a .map format (gets smaller :) */
+ if ( ! copy_attr(input,"SHAPE",directive) ) {
+
+ /* Define a CONTINUE which breaks out of nested loops, on error */
+#define CONTINUE goto AREA_CONTINUE
+AREA_CONTINUE:
+ continue;
+
+ }
+ if ( ! copy_attr(input,"HREF",value) ) {
+ if ( ! find_attr(input,"NOHREF",0) ) CONTINUE;
+ strcpy(value,"nocontent");
+ }
+ { char
+ *coords=find_attr(input,"COORDS",'='),
+ *alt=find_attr(input,"ALT",'=');
+
+ if ( alt && alt < coords ) { /* "alt" coords appeared first */
+ char *p; int len=len_attr(alt,&p);
+ input[0]='"';
+ memmove(input+1,p,len);
+ strcpy(input+len+1,"\" ");
+ alt=NULL;
+ }
+ else
+ input[0]=0; /* Ripe for strcat() */
+ string_pos=input+strlen(input);
+ if ( coords ) { /* Coords. Minor surgery for circles */
+ char quotes=(*coords=='"' || *coords=='\'');
+ char *p=coords+quotes;
+ char *p2;
+ if ( !strcasecmp(directive,"CIRCLE") ) {
+ long x,y,r;
+ p2=p; x=strtol(p,&p,10); if ( p2==p ) CONTINUE;
+ while ( isspace(*p) ) p++; if ( *p++!=',' ) CONTINUE;
+ p2=p; y=strtol(p,&p,10); if ( p2==p ) CONTINUE;
+ while ( isspace(*p) ) p++; if ( *p++!=',' ) CONTINUE;
+ p2=p; r=strtol(p,&p,10); if ( p2==p ) CONTINUE;
+ if ( quotes ) {
+ while ( isspace(*p) ) p++;
+ if ( *p!=*coords ) CONTINUE;
+ }
+ else {
+ if ( *p!='>' || *p!=' ' ) CONTINUE;
+ }
+ /* XX This is dodgy in a totally pathological case */
+ sprintf(string_pos,"%ld,%ld %ld,%ld ",x,y,x,y+r);
+ string_pos+=strlen(string_pos);
+ }
+ else { /* Not circle - take n,n,n,n -> n,n n,n */
+ long x,y;
+ do {
+ p2=p; x=strtol(p,&p,10); if ( p2==p ) CONTINUE;
+ while ( isspace(*p) ) p++; if ( *p++!=',' ) CONTINUE;
+ p2=p; y=strtol(p,&p,10); if ( p2==p ) CONTINUE;
+ while ( isspace(*p) ) p++;
+ sprintf(string_pos,"%ld,%ld ",x,y);
+ string_pos+=strlen(string_pos);
+ } while ( *p++==',' );
+ if ( quotes ) {
+ while ( isspace(*p) ) p++;
+ if ( *p!=*coords ) CONTINUE;
+ }
+ else {
+ if ( *p!='>' || *p!=' ' ) CONTINUE;
+ }
+ }
+ }
+ if ( alt ) { /* coords "alt" */
+ char *p; int len=len_attr(alt,&p);
+ *string_pos++='"';
+ memmove(string_pos,p,len);
+ strcpy(string_pos+len,"\"");
+ }
+ }
+ string_pos=input;
+
+ /* Don't need this any more */
+#undef CONTINUE
+ }
+
+
+
+ else {
+
if (sscanf(input, "%255s %255s", directive, value) != 2) {
continue; /* make sure we read two fields */
}
@@ -688,6 +841,7 @@
string_pos++;
while (!(isspace(*string_pos))) /* and value... have to watch it */
string_pos++; /* can have punctuation and stuff */
+ }
if ( ! strncasecmp(directive, "base", 4 ) ) { /* base, base_uri */
imap_url(r, NULL, value, base);