示例#1
0
/*
**  Look for cached information for this news server
**  We store the information in a URL Tree so that we can have multiple
**  servers stored simultanously
*/
PRIVATE HTNewsCache * HTNewsCache_find (HTRequest * request, const char * url)
{
    HTUTree * tree = NULL;
    if (request && url) {
	char * newshost = NULL;
	HTNewsCache * element = NULL;
	if (!strncasecomp(url, "news:", 5)) {
	    HTUserProfile * up = HTRequest_userProfile(request);
	    StrAllocCopy(newshost, HTUserProfile_news(up));
	} else if (!strncasecomp(url, "nntp:", 5)) {
	    newshost = HTParse(url, "", PARSE_HOST);
	}

	/* If we have a news server then continue to find a URL tree */
	if (newshost) {
	    char * colon = strchr(newshost, ':');
	    int port = NEWS_PORT;
	    if (colon ) {
		*(colon++) = '\0';		     /* Chop off port number */
		port = atoi(colon);
	    }
	    tree = HTUTree_find(NEWS_TREE, newshost, port);
	    HT_FREE(newshost);
	    if (!tree) {
		HTTRACE(PROT_TRACE, "News Cache.. No information for `%s\'\n" _ url);
		return NULL;
	    }

	    /* Find a cache element (if any) */
	    element = (HTNewsCache *) HTUTree_findNode(tree, "", "/");
	    return element;
	}
    }
    return NULL;
}
int LYStringToKeycode(char *src)
{
    unsigned n;
    int key = -1;
    int len = (int) strlen(src);

    if (len == 1) {
	key = *src;
    } else if (len == 2 && *src == '^') {
	key = src[1] & 0x1f;
    } else if (len > 2 && !strncasecomp(src, "0x", 2)) {
	char *dst = 0;

	key = (int) strtol(src, &dst, 0);
	if (non_empty(dst))
	    key = -1;
    } else if (len > 6 && !strncasecomp(src, "key-", 4)) {
	char *dst = 0;

	key = (int) strtol(src + 4, &dst, 0);
	if (isEmpty(dst))
	    key = -1;
    }
    if (key < 0) {
	for (n = 0; n < TABLESIZE(named_keys); n++) {
	    if (!strcasecomp(named_keys[n].name, src)) {
		key = named_keys[n].key;
		break;
	    }
	}
    }
    return key;
}
示例#3
0
// create short icon label from full path/url
char *XFE_ComposeAttachFolderView::parseItemLabel(const char *url)
{
    // (alastair) code taken from libmsg/msgsend.cpp - be nice just to call into libmsg
    // modified slightly to avoid bug of trailing / generating empty name
    // modified to return truncated label for mail/news URL's

    if (!url || strlen(url)==0)
        return XP_STRDUP("(null)");

    char *s;
    char *s2;
    char *s3;
    
    /* If we know the URL doesn't have a sensible file name in it,
       don't bother emitting a content-disposition. */
    if (!strncasecomp (url, "news:", 5))
        return XP_STRDUP("news:");
    if (!strncasecomp (url, "snews:", 6))
        return XP_STRDUP("snews:");    
    if (!strncasecomp (url, "mailbox:", 8))
        return XP_STRDUP("mailbox:");

    char *tmpLabel = XP_STRDUP(url);

    s=tmpLabel;
    /* remove trailing / or \ */
    int len=strlen(s);
    if (s[len-1]=='/' || s[len-1]=='\\')
        s[len-1]='\0';
    
    s2 = XP_STRCHR (s, ':');
    if (s2) s = s2 + 1;
    /* Take the part of the file name after the last / or \ */
    s2 = XP_STRRCHR (s, '/');
    if (s2) s = s2+1;
    s2 = XP_STRRCHR (s, '\\');
    if (s2) s = s2+1;

    /* if it's a non-file url, strip off any named anchors or search data */
    if (XP_STRNCASECMP(url,"file:",5)!=0 && url[0]!='/') {
        /* Now trim off any named anchors or search data. */
        s3 = XP_STRCHR (s, '?');
        if (s3) *s3 = 0;
        s3 = XP_STRCHR (s, '#');
        if (s3) *s3 = 0;
    }

    /* Now lose the %XX crap. */
    NET_UnEscape (s);

    char *retLabel=XP_STRDUP(s);
    XP_FREE(tmpLabel);
    
    return retLabel;
}
示例#4
0
PRIVATE BOOL HTNewsCache_update (HTRequest * request,
				 const char * url, HTArray * array)
{
    HTUTree * tree = NULL;
    if (request && url) {
	char * newshost = NULL;
	if (!strncasecomp(url, "news:", 5)) {
	    HTUserProfile * up = HTRequest_userProfile(request);
	    StrAllocCopy(newshost, HTUserProfile_news(up));
	} else if (!strncasecomp(url, "nntp:", 5)) {
	    newshost = HTParse(url, "", PARSE_HOST);
	}

	/* 
	**  If the news server was found then update the data entry. Otherwise
	**  create a new entry
	*/
	if (newshost) {
	    char * colon = strchr(newshost, ':');
	    int port = NEWS_PORT;
	    if (colon ) {
		*(colon++) = '\0';		     /* Chop off port number */
		port = atoi(colon);
	    }
	    tree = HTUTree_new(NEWS_TREE, newshost, port, HTNewsCache_delete);
	    HT_FREE(newshost);
	    if (!tree) {
		HTTRACE(PROT_TRACE, "News Cache.. Can't create tree\n");
		return NO;
	    }

	    /* Add new cache information to the tree */
	    {
		HTNewsCache * element = NULL;
		BOOL status;
		if ((element=(HTNewsCache *) HTUTree_findNode(tree, "", "/"))){
		    element->cache = array;
		    status = YES;
		} else {
		    element = HTNewsCache_new(url, array);
		    status = HTUTree_addNode(tree, "", "/", element);
		}
		return status;
	    }
	}
    }
    return NO;
}
/*
 * Find the given command-name, accepting an abbreviation if it is unique.
 */
Kcmd *LYStringToKcmd(const char *name)
{
    size_t need = strlen(name);
    size_t j;
    BOOL exact = FALSE;
    Kcmd *result = 0;
    Kcmd *maybe = 0;

    if (non_empty(name)) {
	for (j = 0; revmap[j].name != 0; j++) {
	    if (!strcasecomp(revmap[j].name, name)) {
		result = revmap + j;
		break;
	    } else if (!exact
		       && !strncasecomp(revmap[j].name, name, (int) need)) {
		if (maybe == 0) {
		    maybe = revmap + j;
		} else {
		    if (revmap[j].name[need] != 0
			&& maybe->name[need] != 0) {
			maybe = 0;
			exact = TRUE;
		    }
		}
	    }
	}
    }
    return (result != 0) ? result : maybe;
}
示例#6
0
/*
 * Seek and handle a subject=foo.  - FM
 */
PRIVATE void extract_subject ARGS2(
    char *,	dst,
    char *,	src)
{
    CONST char *keyword = "subject=";
    int len = strlen(keyword);
    char *cp, *cp1;

    cp = (src + 1);
    while (*cp != '\0') {
	if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
	    !strncasecomp(cp, keyword, len))
	    break;
	cp++;
    }
    if (*cp) {
	cp += len;
	if ((cp1 = strchr(cp, '&')) != NULL) {
	    *cp1 = '\0';
	}
	if (*cp) {
	    strncpy(dst, cp, MAX_SUBJECT);
	    dst[MAX_SUBJECT] = '\0';
	    SafeHTUnEscape(dst);
	}
	if (cp1) {
	    *cp1 = '&';
	    cp1 = NULL;
	}
    }
    CTRACE((tfp, "extract_subject(%s) = '%s'\n", keyword, NONNULL(dst)));
}
示例#7
0
PRIVATE void extract_field ARGS3(
    char **,	dst,
    char *,	src,
    char *,	keyword)
{
    int len = strlen(keyword);
    char *cp, *cp1;

    cp = (src + 1);
    while (*cp != '\0') {
	if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
	    !strncasecomp(cp, keyword, len)) {
	    cp += len;
	    if ((cp1 = strchr(cp, '&')) != NULL) {
		*cp1 = '\0';
	    }
	    comma_append(dst, cp);
	    if (cp1) {
		*cp1 = '&';
		cp = cp1;
		cp1 = NULL;
	    } else {
		break;
	    }
	}
	cp++;
    }
    CTRACE((tfp, "extract_field(%s) = '%s'\n", keyword, NONNULL(*dst)));
}
示例#8
0
BOOLEAN LYgetEnum( Config_Enum *table, char *name, int *result )
{
  Config_Enum *found = 0;
  unsigned int len = strlen( name );
  int match = 0;
  if ( len )
  {
    for ( ; table->name[0]; table++ )
    {
      if ( strncasecomp( &table->name[0], name, (int)len ) == 0 )
      {
        found = table;
        if ( strcasecomp( &table->name[0], name ) == 0 )
        {
          match = 1;
          break;
        }
        else
          match++;
      }
      // table++;
    }
    if ( match == 1 )
    {
      result[0] = found->value;
      return 0;
    }
    table++;
  }
  return 0;
}
示例#9
0
int LYStringToKeycode( char *src )
{
  unsigned int n;
  int key = -1;
  int len = strlen( src );
  if ( len == 1 )
    key = src[0];
  else
  if ( len == 2 && src[0] == '^' )
    key = src[1] & 31;
  else
  if ( len > 2 && strncasecomp( src, "0x", 2 ) == 0 )
  {
    char *dst = 0;
    key = strtol( src, &dst, 0 );
    if ( dst && dst[0] )
      key = -1;
  }
  else
  if ( len > 6 && strncasecomp( src, "key-", 4 ) == 0 )
  {
    char *dst = 0;
    key = strtol( &src[4], &dst, 0 );
    if ( dst == 0 || dst[0] == 0 )
      key = -1;
  }
  if ( key < 0 )
  {
    n = 0;
    for ( ; n <= 23; n++ )
    {
      if ( strcasecomp( named_keys[ n ].name, src ) == 0 )
      {
        key = named_keys[ n ].key;
        break;
      }
      else
      {
        // n++;
      }
    }
  }
  return key;
}
示例#10
0
/* Helper function - added by MP. */
PRIVATE char* UnReSubject (char* subject)
{
    if (strlen(subject) >= 3 && strncasecomp(subject, "re:", 3) == 0)
    {
        char* p = subject + 3;  /* "Re:XXX" */
        if (*p == ' ')  p ++;   /* "Re: XXX" */
        return p;
    }
    return subject;
}
示例#11
0
文件: HTAssoc.c 项目: Distrotech/lynx
char *HTAssocList_lookup(HTAssocList *alist,
			 const char *name)
{
    HTAssocList *cur = alist;
    HTAssoc *assoc;

    while (NULL != (assoc = (HTAssoc *) HTList_nextObject(cur))) {
	if (!strncasecomp(assoc->name, name, (int) strlen(name)))
	    return assoc->value;
    }
    return NULL;
}
示例#12
0
/*	Date and Time Parser
**	--------------------
**	These functions are taken from the server written by Ari Luotonen
*/
static int make_month (char* s, char** ends)
{
    char* ptr = s;
    while (!isalpha((int) *ptr)) ptr++;
    if (*ptr) {
	int i;
	*ends = ptr+3;		
	for (i=0; i<12; i++)
	    if (!strncasecomp(months[i], ptr, 3)) return i;
    }
    return 0;
}
示例#13
0
PUBLIC char * HTAssocList_findObject (HTAssocList * list, const char * name)
{
    if (list && name) {
	HTAssocList * cur = list;
	HTAssoc * assoc;
	int len = strlen(name);
	while ((assoc = (HTAssoc *) HTList_nextObject(cur))) {
	    if (!strncasecomp(assoc->name, name, len))
		return assoc->value;
	}
    }
    return NULL;
}
示例#14
0
/* Added by MP. */
PUBLIC BOOL HTNewsDir_belongsToSet (HTNewsDir* dir, char* group)
{
    char* p;
    if (!dir->name || !*(dir->name))
        return YES;
    p = strrchr(dir->name, '*');
    if (!p)
        return strcasecomp(group, dir->name) == 0;
    else
    {
        int len = p - dir->name;
        return strncasecomp(group, dir->name, len) == 0;
    }
}
示例#15
0
/* Helper function added by MP. */
PRIVATE char* GetNewsGroupTitle (HTRequest* request)
{
    char * url = HTAnchor_physical(HTRequest_anchor(request));
    char * title = NULL;
    if (strrchr(url, '*'))
        StrAllocCopy(title, "Newsgroups: ");
    else
        StrAllocCopy(title, "Newsgroup: ");
    if (!strncasecomp(url, "news:", 5))
	StrAllocCat(title, url+5);
    else
	StrAllocCat(title, HTParse(url, "", PARSE_PATH));
    return title;
}
示例#16
0
PUBLIC NET_StreamClass * 
NET_ProxyConverter(int         format_out,
                   void       *data_obj,
                   URL_Struct *URL_s,
                   MWContext  *window_id)
{
    NET_StreamClass* stream;
    ProxyObj * obj;
    
    TRACEMSG(("Setting up display stream. Have URL: %s \n%s\n", 
									URL_s->address, URL_s->content_type));

    stream = XP_NEW(NET_StreamClass);
    if(stream == NULL) 
        return(NULL);

	obj = XP_NEW(ProxyObj);
    if(obj == NULL) 
	  {
		FREE(stream);
        return(NULL);
	  }

	XP_MEMSET(obj, 0, sizeof(ProxyObj));

	stream->data_object = obj;
	

    stream->name           = "ProxyWriter";
    stream->complete       = (MKStreamCompleteFunc) net_proxy_complete;
    stream->abort          = (MKStreamAbortFunc) net_proxy_abort;
    stream->put_block      = (MKStreamWriteFunc) net_proxy_write;
    stream->is_write_ready = (MKStreamWriteReadyFunc) net_proxy_WriteReady;
    stream->window_id      = window_id;

    TRACEMSG(("Returning stream from display_converter\n"));

    /* send HTTP headers if not already getting an HTTP doc 
	 */
    if(strncasecomp(URL_s->address,"http:",5))
      {
		obj->definately_send_headers = TRUE;
      }
	StrAllocCopy(obj->content_type, URL_s->content_type);
	StrAllocCopy(obj->content_encoding, URL_s->content_encoding);

    return stream;
}
示例#17
0
/*
**  Searches the whole list and removes all elements with this name
*/
PUBLIC BOOL HTAssocList_removeObject (HTAssocList * list, const char * name)
{
    BOOL found = NO;
    if (list && name) {
	HTAssocList * cur = list;
	HTAssoc * assoc;
	int len = strlen(name);
	while ((assoc = (HTAssoc *) HTList_nextObject(cur))) {
	    if (!strncasecomp(assoc->name, name, len)) {
		HTList_removeObject(list, assoc);
		HT_FREE(assoc);
		found = YES;
		cur = list;
	    }
	}
    }
    return found;
}
示例#18
0
PUBLIC BOOL HTAssocList_replaceObject (HTAssocList * list,
				       const char * name, const char * value)
{
    if (list && name) {
	HTAssocList * cur = list;
	HTAssoc * assoc;
	int len = strlen(name);
	while ((assoc = (HTAssoc *) HTList_nextObject(cur))) {
	    if (!strncasecomp(assoc->name, name, len)) {
		StrAllocCopy(assoc->name, name);
		if (value) StrAllocCopy(assoc->value, value);
		return YES;
	    }
	}
	return HTAssocList_addObject(list, name, value);
    }
    return NO;
}
示例#19
0
PRIVATE BOOL is_html (char * buf)
{
    char * p = strchr(buf,'<');

    if (p && (!strncasecomp(p, "<HTML>", 6) ||
	      !strncasecomp(p, "<!DOCTYPE HTML", 13) ||
	      !strncasecomp(p, "<HEAD", 5) ||
	      !strncasecomp(p, "<TITLE>", 7) ||
	      !strncasecomp(p, "<BODY>", 6) ||
	      !strncasecomp(p, "<PLAINTEXT>", 11) ||
	      (p[0]=='<' && TOUPPER(p[1]) == 'H' && p[3]=='>')))
	return YES;
    else
	return NO;
}
示例#20
0
Kcmd *LYStringToKcmd( char *name )
{
  unsigned int need = strlen( name );
  unsigned int j;
  BOOLEAN exact = 0;
  Kcmd *result = 0;
  Kcmd *maybe = 0;
  if ( name && name[0] )
  {
    j = 0;
    for ( ; revmap[ j ].name; j++ )
    {
      if ( strcasecomp( revmap[ j ].name, name ) == 0 )
      {
        result = &revmap[ j ];
        break;
      }
      else
      {
        if ( exact == 0 && strncasecomp( revmap[ j ].name, name, (int)need ) == 0 )
        {
          if ( maybe == 0 )
            maybe = &revmap[ j ];
          else
          if ( revmap[ j ].name[ need ] && maybe->name[ need ] )
          {
            maybe = 0;
            exact = 1;
          }
        }
        // j++;
      }
    }
  }
  return maybe;
}
示例#21
0
/*		Load by name					HTLoadFinger
 *		============
 */
int HTLoadFinger(const char *arg,
		 HTParentAnchor *anAnchor,
		 HTFormat format_out,
		 HTStream *stream)
{
    static char empty[1];

    char *username, *sitename;	/* Fields extracted from URL */
    char *slash, *at_sign;	/* Fields extracted from URL */
    char *command, *str, *param;	/* Buffers */
    int port;			/* Port number from URL */
    int status;			/* tcp return */
    int result = HT_LOADED;
    BOOL IsGopherURL = FALSE;
    const char *p1 = arg;

    CTRACE((tfp, "HTFinger: Looking for %s\n", (arg ? arg : "NULL")));

    if (!(arg && *arg)) {
	HTAlert(COULD_NOT_LOAD_DATA);
	return HT_NOT_LOADED;	/* Ignore if no name */
    }

    if (!initialized)
	initialized = initialize();
    if (!initialized) {
	HTAlert(gettext("Could not set up finger connection."));
	return HT_NOT_LOADED;	/* FAIL */
    }

    /*  Set up the host and command fields.
     */
    if (!strncasecomp(arg, "finger://", 9)) {
	p1 = arg + 9;		/* Skip "finger://" prefix */
    } else if (!strncasecomp(arg, "gopher://", 9)) {
	p1 = arg + 9;		/* Skip "gopher://" prefix */
	IsGopherURL = TRUE;
    }

    param = 0;
    sitename = StrAllocCopy(param, p1);
    if (param == 0) {
	HTAlert(COULD_NOT_LOAD_DATA);
	return HT_NOT_LOADED;
    } else if ((slash = StrChr(sitename, '/')) != NULL) {
	*slash++ = '\0';
	HTUnEscape(slash);
	if (IsGopherURL) {
	    if (*slash != '0') {
		HTAlert(COULD_NOT_LOAD_DATA);
		return HT_NOT_LOADED;	/* FAIL */
	    }
	    *slash++ = '\0';
	}
    }

    if ((at_sign = StrChr(sitename, '@')) != NULL) {
	if (IsGopherURL) {
	    HTAlert(COULD_NOT_LOAD_DATA);
	    return HT_NOT_LOADED;	/* FAIL */
	} else {
	    *at_sign++ = '\0';
	    username = sitename;
	    sitename = at_sign;
	    HTUnEscape(username);
	}
    } else if (slash) {
	username = slash;
    } else {
	username = empty;
    }

    if (*sitename == '\0') {
	HTAlert(gettext("Could not load data (no sitename in finger URL)"));
	result = HT_NOT_LOADED;	/* Ignore if no name */
    } else if (HTParsePort(sitename, &port) != NULL) {
	if (port != 79) {
	    HTAlert(gettext("Invalid port number - will only use port 79!"));
	    result = HT_NOT_LOADED;	/* Ignore if wrong port */
	}
    }

    if (result == HT_LOADED) {
	/* Load the string for making a connection/
	 */
	str = 0;
	HTSprintf0(&str, "lose://%s/", sitename);

	/* Load the command for the finger server.
	 */
	command = 0;
	if (at_sign && slash) {
	    if (*slash == 'w' || *slash == 'W') {
		HTSprintf0(&command, "/w %s%c%c", username, CR, LF);
	    } else {
		HTSprintf0(&command, "%s%c%c", username, CR, LF);
	    }
	} else if (at_sign) {
	    HTSprintf0(&command, "%s%c%c", username, CR, LF);
	} else if (*username == '/') {
	    if ((slash = StrChr((username + 1), '/')) != NULL) {
		*slash = ' ';
	    }
	    HTSprintf0(&command, "%s%c%c", username, CR, LF);
	} else if ((*username == 'w' || *username == 'W') &&
		   *(username + 1) == '/') {
	    if (*username + 2 != '\0') {
		*(username + 1) = ' ';
	    } else {
		*(username + 1) = '\0';
	    }
	    HTSprintf0(&command, "/%s%c%c", username, CR, LF);
	} else if ((*username == 'w' || *username == 'W') &&
		   *(username + 1) == '\0') {
	    HTSprintf0(&command, "/%s%c%c", username, CR, LF);
	} else if ((slash = StrChr(username, '/')) != NULL) {
	    *slash++ = '\0';
	    if (*slash == 'w' || *slash == 'W') {
		HTSprintf0(&command, "/w %s%c%c", username, CR, LF);
	    } else {
		HTSprintf0(&command, "%s%c%c", username, CR, LF);
	    }
	} else {
	    HTSprintf0(&command, "%s%c%c", username, CR, LF);
	}

	/* Now, let's get a stream setup up from the FingerHost:
	 * CONNECTING to finger host
	 */
	CTRACE((tfp, "HTFinger: doing HTDoConnect on '%s'\n", str));
	status = HTDoConnect(str, "finger", FINGER_PORT, &finger_fd);
	CTRACE((tfp, "HTFinger: Done DoConnect; status %d\n", status));

	if (status == HT_INTERRUPTED) {
	    /* Interrupt cleanly */
	    CTRACE((tfp,
		    "HTFinger: Interrupted on connect; recovering cleanly.\n"));
	    HTProgress(CONNECTION_INTERRUPTED);
	    result = HT_NOT_LOADED;
	} else if (status < 0) {
	    NETCLOSE(finger_fd);
	    finger_fd = -1;
	    CTRACE((tfp, "HTFinger: Unable to connect to finger host.\n"));
	    HTAlert(gettext("Could not access finger host."));
	    result = HT_NOT_LOADED;	/* FAIL */
	} else {
	    CTRACE((tfp, "HTFinger: Connected to finger host '%s'.\n", str));

	    /* Send the command, and process response if successful.
	     */
	    if (response(command, sitename, anAnchor, format_out, stream) != 0) {
		HTAlert(gettext("No response from finger server."));
		result = HT_NOT_LOADED;
	    }
	}
	FREE(str);
	FREE(command);
    }
    FREE(param);
    return result;
}
示例#22
0
/*      Scan a filename for its consituents.                    scan()
   **   ------------------------------------
   **
   ** On entry,
   **   name    points to a document name which may be incomplete.
   ** On exit,
   **      absolute or relative may be nonzero (but not both).
   **   host, anchor and access may be nonzero if they were specified.
   **   Any which are nonzero point to zero terminated strings.
 */
PRIVATE void    scan
ARGS2(char *, name, struct struct_parts *, parts)
{
    char           *after_access;
    char           *p;
    /* int length = strlen (name); */

    parts->access = NULL;
    parts->host = NULL;
    parts->absolute = NULL;
    parts->relative = NULL;
    parts->anchor = NULL;

    /* 
     **  Scan left-to-right for a scheme (access).
     */
    after_access = name;
    for (p = name; *p; p++) {
        if (*p == ':') {
            *p = '\0';
            parts->access = name;       /* Access name has been specified */
            after_access = (p + 1);
            break;
        }
        if (*p == '/' || *p == '#' || *p == ';' || *p == '?')
            break;
    }

#ifdef NOTDEFINED
    for (p = (name + length - 1); p >= name; p--) {
#endif                          /* NOTDEFINED */
        /* 
         **  Scan left-to-right for a fragment (anchor).
         */
        for (p = after_access; *p; p++) {
            if (*p == '#') {
                parts->anchor = (p + 1);
                *p = '\0';      /* terminate the rest */
            }
        }

        /* 
         **  Scan left-to-right for a host or absolute path.
         */
        p = after_access;
        if (*p == '/') {
            if (p[1] == '/') {
                parts->host = (p + 2);  /* host has been specified */
                *p = '\0';      /* Terminate access */
                p = strchr(parts->host, '/');   /* look for end of host name if any */
                if (p != NULL) {
                    *p = '\0';  /* Terminate host */
                    parts->absolute = (p + 1);  /* Root has been found */
                }
            } else {
                parts->absolute = (p + 1);      /* Root found but no host */
            }
        } else {
            parts->relative = (*after_access) ? after_access : NULL;    /* NULL for
                                                                         * "" */
        }

        /* 
         **  Check schemes that commonly have unescaped hashes.
         */
        if (parts->access && parts->anchor) {
            if ((!parts->host && strcasecomp(parts->access, "lynxcgi")) ||
                !strcasecomp(parts->access, "nntp") ||
                !strcasecomp(parts->access, "snews") ||
                !strcasecomp(parts->access, "news") ||
                !strcasecomp(parts->access, "data")) {
                /* 
                 *  Access specified but no host and not a lynxcgi URL, so the
                 *  anchor may not really be one, e.g., news:j462#[email protected],
                 *  or it's an nntp or snews URL, or news URL with a host.
                 *  Restore the '#' in the address.
                 */
                *(parts->anchor - 1) = '#';
                parts->anchor = NULL;
            }
        }
#ifdef NOT_DEFINED              /* search is just treated as part of path */
        {
            char           *p = (relative ? relative : absolute);
            if (p != NULL) {
                char           *q = strchr(p, '?');     /* Any search string? */
                if (q != NULL) {
                    *q = '\0';  /* If so, chop that off. */
                    parts->search = (q + 1);
                }
            }
        }
#endif                          /* NOT_DEFINED */
    }                           /* scan */


/*      Parse a Name relative to another name.                  HTParse()
   **   --------------------------------------
   **
   **   This returns those parts of a name which are given (and requested)
   **   substituting bits from the related name where necessary.
   **
   ** On entry,
   **   aName           A filename given
   **      relatedName     A name relative to which aName is to be parsed
   **      wanted          A mask for the bits which are wanted.
   **
   ** On exit,
   **   returns         A pointer to a malloc'd string which MUST BE FREED
 */
    PUBLIC char    *HTParse ARGS3(CONST char *, aName,
                                  CONST char *, relatedName, int, wanted) {
        char           *result = NULL;
        char           *return_value = NULL;
        int             len;
        char           *name = NULL;
        char           *rel = NULL;
        char           *p;
        char           *access;
        struct struct_parts given, related;

        if (TRACE)
            fprintf(stderr,
                    "HTParse: aName:%s   relatedName:%s\n", aName, relatedName);

        /* 
         **  Allocate the output string.
         */
        len = strlen(aName) + strlen(relatedName) + 10;
        result = (char *) malloc(len);  /* Lots of space: more than enough */
        if (result == NULL)
            outofmem(__FILE__, "HTParse");
        result[0] = '\0';       /* Clear string */

        /* 
         **  Make working copies of the input strings to cut up.
         */
        StrAllocCopy(name, aName);
        StrAllocCopy(rel, relatedName);

        /* 
         **  Cut up the strings into URL fields.
         */
        scan(name, &given);
        scan(rel, &related);

        /* 
         **  Handle the scheme (access) field.
         */
        if (given.access && given.host && !given.relative && !given.absolute) {
            if (!strcmp(given.access, "http") ||
                !strcmp(given.access, "https") || !strcmp(given.access, "ftp"))
                /* 
                 **  Assume root.
                 */
                given.absolute = "";
        }
        access = given.access ? given.access : related.access;
        if (wanted & PARSE_ACCESS) {
            if (access) {
                strcat(result, access);
                if (wanted & PARSE_PUNCTUATION)
                    strcat(result, ":");
            }
        }

        /* 
         **  If different schemes, inherit nothing.
         **
         **  We'll try complying with RFC 1808 and
         **  the Fielding draft, and inherit nothing
         **  if both schemes are given, rather than
         **  only when they differ, except for
         **  file URLs - FM
         **
         **  After trying it for a while, it's still
         **  premature, IHMO, to go along with it, so
         **  this is back to inheriting for identical
         **  schemes whether or not they are "file".
         **  If you want to try it again yourself,
         **  uncomment the strncasecomp() below. - FM
         */
        if ((given.access && related.access) && (       /* strcasecomp(given.access, 
                                                         * "file") || */
                                                    strcmp(given.access,
                                                           related.access))) {
            related.host = NULL;
            related.absolute = NULL;
            related.relative = NULL;
            related.anchor = NULL;
        }

        /* 
         **  Handle the host field.
         */
        if (wanted & PARSE_HOST)
            if (given.host || related.host) {
                char           *tail = result + strlen(result);
                if (wanted & PARSE_PUNCTUATION)
                    strcat(result, "//");
                strcat(result, given.host ? given.host : related.host);
#define CLEAN_URLS
#ifdef CLEAN_URLS
                /* 
                 **  Ignore default port numbers, and trailing dots on FQDNs,
                 **  which will only cause identical addresses to look different.
                 */
                {
                    char           *p, *h;
                    p = strchr(tail, ':');
                    if (p != NULL && !isdigit((unsigned char) p[1]))
                        /* 
                         **  Colon not followed by a port number.
                         */
                        *p = '\0';
                    if (p != NULL && p != '\0' && access != NULL) {
                        /* 
                         **  Port specified.
                         */
                        if ((!strcmp(access, "http") && !strcmp(p, ":80")) ||
                            (!strcmp(access, "gopher") && !strcmp(p, ":70")) ||
                            (!strcmp(access, "ftp") && !strcmp(p, ":21")) ||
                            (!strcmp(access, "wais") && !strcmp(p, ":210")) ||
                            (!strcmp(access, "nntp") && !strcmp(p, ":119")) ||
                            (!strcmp(access, "news") && !strcmp(p, ":119")) ||
                            (!strcmp(access, "snews") && !strcmp(p, ":563")) ||
                            (!strcmp(access, "finger") && !strcmp(p, ":79")) ||
                            (!strcmp(access, "cso") && !strcmp(p, ":105")))
                            *p = '\0';  /* It is the default: ignore it */
                    }
                    if (p == NULL) {
                        int             len = strlen(tail);

                        if (len > 0) {
                            h = tail + len - 1; /* last char of hostname */
                            if (*h == '.')
                                *h = '\0';      /* chop final . */
                        }
                    } else {
                        h = p;
                        h--;    /* End of hostname */
                        if (*h == '.') {
                            /* 
                             **  Slide p over h.
                             */
                            while (*p != '\0')
                                *h++ = *p++;
                            *h = '\0';  /* terminate */
                        }
                    }
                }
#endif                          /* CLEAN_URLS */
            }

        /* 
         **  If different hosts, inherit no path.
         */
        if (given.host && related.host)
            if (strcmp(given.host, related.host) != 0) {
                related.absolute = NULL;
                related.relative = NULL;
                related.anchor = NULL;
            }

        /* 
         **  Handle the path.
         */
        if (wanted & PARSE_PATH) {
            if (access && !given.absolute && given.relative) {
                if (!strcasecomp(access, "nntp") ||
                    !strcasecomp(access, "snews") ||
                    (!strcasecomp(access, "news") &&
                     !strncasecomp(result, "news://", 7))) {
                    /* 
                     *  Treat all given nntp or snews paths,
                     *  or given paths for news URLs with a host,
                     *  as absolute.
                     */
                    given.absolute = given.relative;
                    given.relative = NULL;
                }
            }
            if (given.absolute) {       /* All is given */
                if (wanted & PARSE_PUNCTUATION)
                    strcat(result, "/");
                strcat(result, given.absolute);
                if (TRACE)
                    fprintf(stderr, "1\n");
            } else if (related.absolute) {      /* Adopt path not name */
                strcat(result, "/");
                strcat(result, related.absolute);
                if (given.relative) {
                    p = strchr(result, '?');    /* Search part? */
                    if (p == NULL)
                        p = (result + strlen(result) - 1);
                    for (; *p != '/'; p--);     /* last / */
                    p[1] = '\0';        /* Remove filename */
                    strcat(result, given.relative);     /* Add given one */
                    HTSimplify(result);
                }
                if (TRACE)
                    fprintf(stderr, "2\n");
            } else if (given.relative) {
                strcat(result, given.relative); /* what we've got */
                if (TRACE)
                    fprintf(stderr, "3\n");
            } else if (related.relative) {
                strcat(result, related.relative);
                if (TRACE)
                    fprintf(stderr, "4\n");
            } else {            /* No inheritance */
                if (strncasecomp(aName, "lynxcgi:", 8) &&
                    strncasecomp(aName, "lynxexec:", 9) &&
                    strncasecomp(aName, "lynxprog:", 9)) {
                    strcat(result, "/");
                }
                if (!strcmp(result, "news:/"))
                    result[5] = '*';
                if (TRACE)
                    fprintf(stderr, "5\n");
            }
        }

        /* 
         **  Handle the fragment (anchor).
         */
        if (wanted & PARSE_ANCHOR)
            if ((given.anchor && *given.anchor) || (!given.anchor && related.anchor)) {
                if (wanted & PARSE_PUNCTUATION)
                    strcat(result, "#");
                strcat(result, (given.anchor) ? given.anchor : related.anchor);
            }
        if (TRACE)
            fprintf(stderr, "HTParse: result:%s\n", result);
        FREE(rel);
        FREE(name);

        StrAllocCopy(return_value, result);
        FREE(result);

        return return_value;    /* exactly the right length */
    }
示例#23
0
/*
**  mailmsg() sends a message to the owner of the file, if one is defined,
**  telling of errors (i.e., link not available).
*/
PUBLIC void mailmsg ARGS4(
	int,		cur,
	char *,		owner_address,
	char *,		filename,
	char *,		linkname)
{
    FILE *fd, *fp;
    char *address = NULL;
    char *searchpart = NULL;
    char *cmd = NULL, *cp;
#ifdef ALERTMAIL
    BOOLEAN skip_parsing = FALSE;
#endif
#if !CAN_PIPE_TO_MAILER
    char *ccaddr;
    char subject[128];
    char my_tmpfile[LY_MAXPATH];
#endif
#if USE_VMS_MAILER
    BOOLEAN isPMDF = LYMailPMDF();
    char hdrfile[LY_MAXPATH];
    char *command = NULL;

    CTRACE((tfp, "mailmsg(%d, \"%s\", \"%s\", \"%s\")\n", cur,
	NONNULL(owner_address),
	NONNULL(filename),
	NONNULL(linkname)));

#endif /* VMS */

    if (!LYSystemMail())
	return;

#ifdef ALERTMAIL
    if (owner_address == NULL) {
	owner_address = ALERTMAIL;
	skip_parsing = TRUE;
    }
#endif

    if (isEmpty(owner_address))
	return;
    if ((cp = (char *)strchr(owner_address,'\n')) != NULL) {
#ifdef ALERTMAIL
	if (skip_parsing)
	    return;		/* invalidly defined - ignore - kw */
#else
	*cp = '\0';
#endif
    }
    if (!strncasecomp(owner_address, "lynx-dev@", 9)) {
	/*
	 *  Silently refuse sending bad link messages to lynx-dev.
	 */
	return;
    }
    StrAllocCopy(address, owner_address);

#ifdef ALERTMAIL
    /*
     *  If we are using a fixed address given by ALERTMAIL, it is
     *  supposed to already be in usable form, without URL-isms like
     *  ?-searchpart and URL-escaping.  So skip some code. - kw
     */
    if (!skip_parsing)
#endif
    {
	/*
	 *	Check for a ?searchpart. - FM
	 */
	if ((cp = strchr(address, '?')) != NULL) {
	    StrAllocCopy(searchpart, cp);
	    *cp = '\0';
	    cp = (searchpart + 1);
	    if (*cp != '\0') {
		/*
		 * Seek and handle to=address(es) fields.
		 * Appends to address.  We ignore any other
		 * headers in the ?searchpart.  - FM
		 */
		extract_field(&address, searchpart, "to=");
	    }
	}

	convert_explorer(address);

	/*
	 *  Unescape the address field. - FM
	 */
	SafeHTUnEscape(address);
    }

    if (trim_comma(address)) {
	FREE(address);
	CTRACE((tfp, "mailmsg: No address in '%s'.\n", owner_address));
	return;
    }

#if CAN_PIPE_TO_MAILER
    if ((fd = LYPipeToMailer()) == 0) {
	FREE(address);
	CTRACE((tfp, "mailmsg: '%s' failed.\n", cmd));
	return;
    }

    fprintf(fd, "To: %s\n", address);
    fprintf(fd, "Subject: Lynx Error in %s\n", filename);
    if (!isEmpty(personal_mail_address)) {
	fprintf(fd, "Cc: %s\n", personal_mail_address);
    }
    fprintf(fd, "X-URL: %s\n", filename);
    fprintf(fd, "X-Mailer: %s, Version %s\n\n", LYNX_NAME, LYNX_VERSION);
#else
    if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
	CTRACE((tfp, "mailmsg: Could not fopen '%s'.\n", my_tmpfile));
	FREE(address);
	return;
    }
    sprintf(subject, "Lynx Error in %.56s", filename);
    ccaddr = personal_mail_address;
#if USE_VMS_MAILER
    if (isPMDF) {
	FILE *hfd;
	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
	    CTRACE((tfp, "mailmsg: Could not fopen '%s'.\n", hdrfile));
	    FREE(address);
	    return;
	}

	if (!isEmpty(personal_mail_address)) {
	    fprintf(fd, "Cc: %s\n", personal_mail_address);
	}
	fprintf(fd, "X-URL: %s\n", filename);
	fprintf(fd, "X-Mailer: %s, Version %s\n\n", LYNX_NAME, LYNX_VERSION);
	/*
	 *  For PMDF, put the subject in the
	 *  header file and close it. - FM
	 */
	fprintf(hfd, "Subject: Lynx Error in %.56s\n\n", filename);
	LYCloseTempFP(hfd);
    }
#endif /* USE_VMS_MAILER */
#endif /* CAN_PIPE_TO_MAILER */

    fprintf(fd, gettext("The link   %s :?: %s \n"),
		links[cur].lname, links[cur].target);
    fprintf(fd, gettext("called \"%s\"\n"), LYGetHiliteStr(cur, 0));
    fprintf(fd, gettext("in the file \"%s\" called \"%s\"\n"), filename, linkname);
    fprintf(fd, "%s\n\n", gettext("was requested but was not available."));
    fprintf(fd, "%s\n\n", gettext("Thought you might want to know."));

    fprintf(fd, "%s\n", gettext("This message was automatically generated by"));
    fprintf(fd, "%s %s", LYNX_NAME, LYNX_VERSION);
    if ((LynxSigFile != NULL) &&
	(fp = fopen(LynxSigFile, TXT_R)) != NULL) {
	fputs("-- \n", fd);
	while (LYSafeGets(&cmd, fp) != NULL)
	    fputs(cmd, fd);
	LYCloseInput(fp);
    }
#if CAN_PIPE_TO_MAILER
    pclose(fd);
#else
    LYCloseTempFP(fd);
#if USE_VMS_MAILER
    if (isPMDF) {
	/*
	 *  Now set up the command. - FM
	 */
	HTSprintf0(&command,
		"%s %s %s,%s ",
		system_mail,
		system_mail_flags,
		hdrfile,
		my_tmpfile);
    } else {
	/*
	 *  For "generic" VMS MAIL, include the
	 *  subject in the command. - FM
	 */
	HTSprintf0(&command,
		"%s %s/self/subject=\"Lynx Error in %.56s\" %s ",
		system_mail,
		system_mail_flags,
		filename,
		my_tmpfile);
    }
    vms_append_addrs(&command, address, "");

    LYSystem(command);	/* VMS */
    FREE(command);
    FREE(cmd);
    LYRemoveTemp(my_tmpfile);
    if (isPMDF) {
	LYRemoveTemp(hdrfile);
    }
#else /* DOS */
    LYSendMailFile (
	address,
	my_tmpfile,
	subject,
	ccaddr,
	"");
    LYRemoveTemp(my_tmpfile);
#endif /* USE_VMS_MAILER */
#endif /* CAN_PIPE_TO_MAILER */

    if (traversal) {
	FILE *ofp;

	if ((ofp = LYAppendToTxtFile(TRAVERSE_ERRORS)) == NULL) {
	    if ((ofp = LYNewTxtFile(TRAVERSE_ERRORS)) == NULL) {
		perror(NOOPEN_TRAV_ERR_FILE);
		exit_immediately(EXIT_FAILURE);
	    }
	}

	fprintf(ofp, "%s\t%s \tin %s\n",
		     links[cur].lname, links[cur].target, filename);
	LYCloseOutput(ofp);
    }

    FREE(address);
    return;
}
示例#24
0
PUBLIC BOOLEAN LYMailPMDF(void)
{
    return (system_mail != 0)
	    ? !strncasecomp(system_mail, "PMDF SEND", 9)
	    : FALSE;
}
示例#25
0
/*
**  mailform() sends form content to the mailto address(es). - FM
*/
PUBLIC void mailform ARGS4(
    CONST char *,	mailto_address,
    CONST char *,	mailto_subject,
    CONST char *,	mailto_content,
    CONST char *,	mailto_type)
{
    FILE *fd;
    char *address = NULL;
    char *ccaddr = NULL;
    char *keywords = NULL;
    char *cp = NULL;
    char self[MAX_SUBJECT + 10];
    char subject[MAX_SUBJECT + 10];
    char *searchpart = NULL;
    char buf[512];
    int ch, len, i;
#if USE_VMS_MAILER
    static char *cmd;
    char *command = NULL;
    BOOLEAN isPMDF = LYMailPMDF();
    char hdrfile[LY_MAXPATH];
#endif
#if !CAN_PIPE_TO_MAILER
    char my_tmpfile[LY_MAXPATH];
#endif

    CTRACE((tfp, "mailto_address: \"%s\"\n", NONNULL(mailto_address)));
    CTRACE((tfp, "mailto_subject: \"%s\"\n", NONNULL(mailto_subject)));
    CTRACE((tfp, "mailto_content: \"%s\"\n", NONNULL(mailto_content)));
    CTRACE((tfp, "mailto_type:    \"%s\"\n", NONNULL(mailto_type)));

    if (!LYSystemMail())
	return;

    if (!mailto_address || !mailto_content) {
	HTAlert(BAD_FORM_MAILTO);
	return;
    }
    subject[0] = '\0';
    self[0] = '\0';

    if ((cp = (char *)strchr(mailto_address,'\n')) != NULL)
	*cp = '\0';
    StrAllocCopy(address, mailto_address);

    /*
     *	Check for a ?searchpart. - FM
     */
    if ((cp = strchr(address, '?')) != NULL) {
	StrAllocCopy(searchpart, cp);
	*cp = '\0';
	cp = (searchpart + 1);
	if (*cp != '\0') {
	    /*
	     *	Seek and handle a subject=foo. - FM
	     */
	    extract_subject(subject, searchpart);

	    /*
	     *	Seek and handle to=address(es) fields.
	     *	Appends to address. - FM
	     */
	    extract_field(&address, searchpart, "to=");

	    /*
	     *	Seek and handle cc=address(es) fields.	Excludes
	     *	Bcc=address(es) as unsafe.  We may append our own
	     *	cc (below) as a list for the actual mailing. - FM
	     */
	    extract_field(&ccaddr, searchpart, "cc=");

	    /*
	     *	Seek and handle keywords=term(s) fields. - FM
	     */
	    extract_field(&keywords, searchpart, "keywords=");

	    if (keywords != NULL) {
		if (*keywords != '\0') {
		    SafeHTUnEscape(keywords);
		} else {
		    FREE(keywords);
		}
	    }

	    FREE(searchpart);
	}
    }

    if (convert_explorer(address)) {
	HTAlert(BAD_FORM_MAILTO);
	goto cleanup;
    }
    if (ccaddr != NULL) {
	if (convert_explorer(ccaddr)) {
	    FREE(ccaddr);
	}
    }

    /*
     *	Unescape the address and ccaddr fields. - FM
     */
    SafeHTUnEscape(address);
    if (ccaddr != NULL) {
	SafeHTUnEscape(ccaddr);
    }

    /*
     *	Allow user to edit the default Subject - FM
     */
    if (isEmpty(subject)) {
	if (!isEmpty(mailto_subject)) {
	    LYstrncpy(subject, mailto_subject, MAX_SUBJECT);
	} else {
	    sprintf(subject, "mailto:%.63s", address);
	}
    }
    _statusline(SUBJECT_PROMPT);
    if ((ch = LYgetstr(subject, VISIBLE, MAX_SUBJECT, NORECALL)) < 0) {
	/*
	 * User cancelled via ^G. - FM
	 */
	HTInfoMsg(FORM_MAILTO_CANCELLED);
	goto cleanup;
    }

    /*
     *	Allow user to specify a self copy via a CC:
     *	entry, if permitted. - FM
     */
    if (!LYNoCc) {
	sprintf(self, "%.*s", MAX_SUBJECT,
		isEmpty(personal_mail_address) ? "" : personal_mail_address);
	_statusline("Cc: ");
	if ((ch = LYgetstr(self, VISIBLE, MAX_SUBJECT, NORECALL)) < 0) {
	    /*
	     * User cancelled via ^G. - FM
	     */
	    HTInfoMsg(FORM_MAILTO_CANCELLED);
	    goto cleanup;
	}
	remove_tildes(self);
	if (ccaddr == NULL) {
	    StrAllocCopy(ccaddr, self);
	} else {
	    StrAllocCat(ccaddr, ",");
	    StrAllocCat(ccaddr, self);
	}
    }

#if CAN_PIPE_TO_MAILER
    if ((fd = LYPipeToMailer()) == 0) {
	HTAlert(FORM_MAILTO_FAILED);
	goto cleanup;
    }

    if (!isEmpty(mailto_type)) {
	fprintf(fd, "Mime-Version: 1.0\n");
	fprintf(fd, "Content-Type: %s\n", mailto_type);
    }
    fprintf(fd, "To: %s\n", address);
    if (!isEmpty(personal_mail_address))
	fprintf(fd, "From: %s\n", personal_mail_address);
    if (!isEmpty(ccaddr))
	fprintf(fd, "Cc: %s\n", ccaddr);
    fprintf(fd, "Subject: %s\n\n", subject);
    if (!isEmpty(keywords))
	fprintf(fd, "Keywords: %s\n", keywords);
    _statusline(SENDING_FORM_CONTENT);
#else	/* e.g., VMS, DOS */
    if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
	HTAlert(FORM_MAILTO_FAILED);
	goto cleanup;
    }
#if USE_VMS_MAILER
    if (isPMDF) {
	FILE *hfd;
	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
	    HTAlert(FORM_MAILTO_FAILED);
	    LYCloseTempFP(fd);
	    goto cleanup;
	}
	if (!isEmpty(mailto_type)) {
	    fprintf(hfd, "Mime-Version: 1.0\n");
	    fprintf(hfd, "Content-Type: %s\n", mailto_type);
	    if (!isEmpty(personal_mail_address))
		fprintf(hfd, "From: %s\n", personal_mail_address);
	}
	/*
	 *  For PMDF, put any keywords and the subject
	 *  in the header file and close it. - FM
	 */
	if (!isEmpty(keywords)) {
	    fprintf(hfd, "Keywords: %s\n", keywords);
	}
	fprintf(hfd, "Subject: %s\n\n", subject);
	LYCloseTempFP(hfd);
    } else if (mailto_type &&
	       !strncasecomp(mailto_type, "multipart/form-data", 19)) {
	/*
	 *  Ugh!  There's no good way to include headers while
	 *  we're still using "generic" VMS MAIL, so we'll put
	 *  this in the body of the message. - FM
	 */
	fprintf(fd, "X-Content-Type: %s\n\n", mailto_type);
    }
#else	/* !VMS (DOS) */
#if USE_BLAT_MAILER
    if (mail_is_blat) {
	if (strlen(subject) > MAX_SUBJECT)
	    subject[MAX_SUBJECT] = '\0';
    } else
#endif
    {
	if (!isEmpty(mailto_type)) {
	    fprintf(fd, "Mime-Version: 1.0\n");
	    fprintf(fd, "Content-Type: %s\n", mailto_type);
	}
	fprintf(fd,"To: %s\n", address);
	if (!isEmpty(personal_mail_address))
	    fprintf(fd,"From: %s\n", personal_mail_address);
	fprintf(fd,"Subject: %.70s\n\n", subject);
    }
#endif /* VMS */
#endif /* CAN_PIPE_TO_MAILER */

    /*
     *	Break up the content into lines with a maximum length of 78.
     *	If the ENCTYPE was text/plain, we have physical newlines and
     *	should take them into account.	Otherwise, the actual newline
     *	characters in the content are hex escaped. - FM
     */
    while((cp = strchr(mailto_content, '\n')) != NULL) {
	*cp = '\0';
	i = 0;
	len = strlen(mailto_content);
	while (len > 78) {
	    strncpy(buf, &mailto_content[i], 78);
	    buf[78] = '\0';
	    fprintf(fd, "%s\n", buf);
	    i += 78;
	    len = strlen(&mailto_content[i]);
	}
	fprintf(fd, "%s\n", &mailto_content[i]);
	mailto_content = (cp+1);
    }
    i = 0;
    len = strlen(mailto_content);
    while (len > 78) {
	strncpy(buf, &mailto_content[i], 78);
	buf[78] = '\0';
	fprintf(fd, "%s\n", buf);
	i += 78;
	len = strlen(&mailto_content[i]);
    }
    if (len)
	fprintf(fd, "%s\n", &mailto_content[i]);

#if CAN_PIPE_TO_MAILER
    pclose(fd);
    LYSleepMsg();
#else
    LYCloseTempFP(fd);
#if USE_VMS_MAILER
    /*
     *	Set the mail command. - FM
     */
    if (isPMDF) {
	/*
	 *  Now set up the command. - FM
	 */
	HTSprintf0(&cmd,
		"%s %s %s,%s ",
		system_mail,
		system_mail_flags,
		hdrfile,
		my_tmpfile);
    } else {
	/*
	 *  For "generic" VMS MAIL, include the subject in the
	 *  command, and ignore any keywords to minimize risk
	 *  of them making the line too long or having problem
	 *  characters. - FM
	 */
	HTSprintf0(&cmd,
		"%s %s%s/subject=\"%s\" %s ",
		system_mail,
		system_mail_flags,
		(strncasecomp(system_mail, "MAIL", 4) ? "" : "/noself"),
		subject,
		my_tmpfile);
    }
    StrAllocCopy(command, cmd);

    vms_append_addrs(&command, address, "");
    if (!isEmpty(ccaddr)) {
	vms_append_addrs(&command, ccaddr, "/CC");
    }

    stop_curses();
    printf("%s\n\n$ %s\n\n%s", SENDING_FORM_CONTENT, command, PLEASE_WAIT);
    LYSystem(command);	/* Mail (VMS) */
    FREE(command);
    LYSleepAlert();
    start_curses();
    LYRemoveTemp(my_tmpfile);
    if (isPMDF)
	LYRemoveTemp(hdrfile);
#else /* DOS */
    LYSendMailFile (
	address,
	my_tmpfile,
	subject,
	ccaddr,
	SENDING_FORM_CONTENT);
    LYRemoveTemp(my_tmpfile);
#endif /* USE_VMS_MAILER */
#endif /* CAN_PIPE_TO_MAILER */

cleanup:
    FREE(address);
    FREE(ccaddr);
    FREE(keywords);
    return;
}
示例#26
0
/*
 * Seek and handle body=foo fields.  - FM
 */
PRIVATE void extract_body ARGS2(
    char **,	dst,
    char *,	src)
{
    CONST char *keyword = "body=";
    int len = strlen(keyword);
    int i;
    char *cp, *cp0, *cp1, *temp = 0;

    cp = (src + 1);
    while (*cp != '\0') {
	if ((*(cp - 1) == '?' || *(cp - 1) == '&') &&
	    !strncasecomp(cp, keyword, len)) {
	    cp += len;
	    if ((cp1 = strchr(cp, '&')) != NULL) {
		*cp1 = '\0';
	    }
	    if (*cp) {
		/*
		 *  Break up the value into lines with
		 *  a maximum length of 78. - FM
		 */
		StrAllocCopy(temp, cp);
		HTUnEscape(temp);
		cp0 = temp;
		while((cp = strchr(cp0, '\n')) != NULL) {
		    *cp = '\0';
		    if (cp > cp0) {
			if (*(cp - 1) == '\r') {
			    *(cp - 1) = '\0';
			}
		    }
		    i = 0;
		    len = strlen(cp0);
		    while (len > 78) {
			HTSprintf(dst, "%.78s\n", &cp0[i]);
			i += 78;
			len = strlen(&cp0[i]);
		    }
		    HTSprintf(dst, "%s\n", &cp0[i]);
		    cp0 = (cp + 1);
		}
		i = 0;
		len = strlen(cp0);
		while (len > 78) {
		    HTSprintf(dst, "%.78s\n", &cp0[i]);
		    i += 78;
		    len = strlen(&cp0[i]);
		}
		if (len) {
		    HTSprintf(dst, "%s\n", &cp0[i]);
		}
		FREE(temp);
	    }
	    if (cp1) {
		*cp1 = '&';
		cp = cp1;
		cp1 = NULL;
	    } else {
		break;
	    }
	}
	cp++;
    }
    CTRACE((tfp, "extract_body(%s) = '%s'\n", keyword, NONNULL(*dst)));
}
示例#27
0
/*	Load one line of configuration
 *	------------------------------
 *
 *	Call this, for example, to load a X resource with config info.
 *
 * returns	0 OK, < 0 syntax error.
 */
int HTSetConfiguration(char *config)
{
    HTRuleOp op;
    char *line = NULL;
    char *pointer = line;
    char *word1;
    const char *word2;
    const char *word3;
    const char *cond_op = NULL;
    const char *cond = NULL;
    float quality, secs, secs_per_byte;
    int maxbytes;
    int status;

    StrAllocCopy(line, config);
    {
	char *p = strchr(line, '#');	/* Chop off comments */

	if (p)
	    *p = 0;
    }
    pointer = line;
    word1 = HTNextField(&pointer);
    if (!word1) {
	FREE(line);
	return 0;
    };				/* Comment only or blank */

    word2 = HTNextField(&pointer);

    if (0 == strcasecomp(word1, "defprot") ||
	0 == strcasecomp(word1, "protect"))
	word3 = pointer;	/* The rest of the line to be parsed by AA module */
    else
	word3 = HTNextField(&pointer);	/* Just the next word */

    if (!word2) {
	fprintf(stderr, "HTRule: %s %s\n", RULE_NEEDS_DATA, line);
	FREE(line);
	return -2;		/*syntax error */
    }

    if (0 == strcasecomp(word1, "suffix")) {
	char *encoding = HTNextField(&pointer);

	if (pointer)
	    status = sscanf(pointer, "%f", &quality);
	else
	    status = 0;
	HTSetSuffix(word2, word3,
		    encoding ? encoding : "binary",
		    status >= 1 ? quality : (float) 1.0);

    } else if (0 == strcasecomp(word1, "presentation")) {
	if (pointer)
	    status = sscanf(pointer, "%f%f%f%d",
			    &quality, &secs, &secs_per_byte, &maxbytes);
	else
	    status = 0;
	HTSetPresentation(word2, word3, NULL,
			  status >= 1 ? quality : 1.0,
			  status >= 2 ? secs : 0.0,
			  status >= 3 ? secs_per_byte : 0.0,
			  status >= 4 ? maxbytes : 0,
			  mediaCFG);

    } else if (0 == strncasecomp(word1, "htbin", 5) ||
	       0 == strncasecomp(word1, "bindir", 6)) {
	StrAllocCopy(HTBinDir, word2);	/* Physical /htbin location */

    } else if (0 == strncasecomp(word1, "search", 6)) {
	StrAllocCopy(HTSearchScript, word2);	/* Search script name */

    } else {
	op = 0 == strcasecomp(word1, "map") ? HT_Map
	    : 0 == strcasecomp(word1, "pass") ? HT_Pass
	    : 0 == strcasecomp(word1, "fail") ? HT_Fail
	    : 0 == strcasecomp(word1, "redirect") ? HT_Redirect
	    : 0 == strncasecomp(word1, "redirectperm", 12) ? HT_RedirectPerm
	    : 0 == strcasecomp(word1, "redirecttemp") ? HT_Redirect
	    : 0 == strcasecomp(word1, "permitredirection") ? HT_PermitRedir
	    : 0 == strcasecomp(word1, "useproxy") ? HT_UseProxy
	    : 0 == strcasecomp(word1, "alert") ? HT_Alert
	    : 0 == strcasecomp(word1, "alwaysalert") ? HT_AlwaysAlert
	    : 0 == strcasecomp(word1, "progress") ? HT_Progress
	    : 0 == strcasecomp(word1, "usermsg") ? HT_UserMsg
	    : 0 == strcasecomp(word1, "infomsg") ? HT_InfoMsg
	    : 0 == strcasecomp(word1, "defprot") ? HT_DefProt
	    : 0 == strcasecomp(word1, "protect") ? HT_Protect
	    : HT_Invalid;
	if (op == HT_Invalid) {
	    fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config);
	} else {
	    switch (op) {
	    case HT_Fail:	/* never a or other 2nd parameter */
	    case HT_PermitRedir:
		cond_op = word3;
		if (cond_op && *cond_op) {
		    word3 = NULL;
		    cond = HTNextField(&pointer);
		}
		break;

	    case HT_Pass:	/* possibly a URL2 */
		if (word3 && (!strcasecomp(word3, "if") ||
			      !strcasecomp(word3, "unless"))) {
		    cond_op = word3;
		    word3 = NULL;
		    cond = HTNextField(&pointer);
		    break;
		}
		/* else fall through */
	    case HT_Map:	/* always a URL2 (or other 2nd parameter) */
	    case HT_Redirect:
	    case HT_RedirectPerm:
	    case HT_UseProxy:
		cond_op = HTNextField(&pointer);
		/* check for extra status word in "Redirect" */
		if (op == HT_Redirect && 0 == strcasecomp(word1, "redirect") &&
		    cond_op &&
		    strcasecomp(cond_op, "if") &&
		    strcasecomp(cond_op, "unless")) {
		    if (0 == strcmp(word2, "301") ||
			0 == strcasecomp(word2, "permanent")) {
			op = HT_RedirectPerm;
		    } else if (!(0 == strcmp(word2, "302") ||
				 0 == strcmp(word2, "303") ||
				 0 == strcasecomp(word2, "temp") ||
				 0 == strcasecomp(word2, "seeother"))) {
			CTRACE((tfp, "Rule: Ignoring `%s' in Redirect\n", word2));
		    }
		    word2 = word3;
		    word3 = cond_op;	/* cond_op isn't condition op after all */
		    cond_op = HTNextField(&pointer);
		}
		if (cond_op && *cond_op)
		    cond = HTNextField(&pointer);
		break;

	    case HT_Progress:
	    case HT_InfoMsg:
	    case HT_UserMsg:
	    case HT_Alert:
	    case HT_AlwaysAlert:
		cond_op = HTNextField(&pointer);
		if (cond_op && *cond_op)
		    cond = HTNextField(&pointer);
		if (word3) {	/* Fix string with too may %s - kw */
		    const char *cp = word3;
		    char *cp1, *cp2;

		    while ((cp1 = strchr(cp, '%'))) {
			if (cp1[1] == '\0') {
			    *cp1 = '\0';
			    break;
			} else if (cp1[1] == '%') {
			    cp = cp1 + 2;
			    continue;
			} else
			    while ((cp2 = strchr(cp1 + 2, '%'))) {
				if (cp2[1] == '\0') {
				    *cp2 = '\0';
				    break;
				} else if (cp2[1] == '%') {
				    cp1 = cp2;
				} else {
				    *cp2 = '?';		/* replace bad % */
				    cp1 = cp2;
				}
			    }
			break;
		    }
		}
		break;

	    default:
		break;
	    }
	    if (cond_op && cond && *cond && !strcasecomp(cond_op, "unless")) {
		cond_op = "unless";
	    } else if (cond_op && cond && *cond &&
		       !strcasecomp(cond_op, "if")) {
		cond_op = "if";
	    } else if (cond_op || cond) {
		fprintf(stderr, "HTRule: %s '%s'\n", RULE_INCORRECT, config);
		FREE(line);	/* syntax error, condition is a mess - kw */
		return -2;	/* NB unrecognized cond passes here - kw */
	    }
	    if (cond && !strncasecomp(cond, "redirected", strlen(cond))) {
		cond = "redirected";	/* recognized, canonical case - kw */
	    } else if (cond && strlen(cond) >= 8 &&
		       !strncasecomp(cond, "userspecified", strlen(cond))) {
		cond = "userspec";	/* also allow abbreviation - kw */
	    }
	    HTAddRule(op, word2, word3, cond_op, cond);
	}
    }
    FREE(line);
    return 0;
}
示例#28
0
/*
**  reply_by_mail() invokes sendmail on Unix or mail on VMS to send
**  a comment from the users to the owner
*/
PUBLIC void reply_by_mail ARGS4(
	char *,		mail_address,
	char *,		filename,
	CONST char *,	title,
	CONST char *,	refid)
{
#ifndef NO_ANONYMOUS_EMAIL
    static char *personal_name = NULL;
#endif
    char user_input[LINESIZE];
    FILE *fd, *fp;
    char *label = NULL;
    char *from_address = NULL;
    char *cc_address = NULL;
    char *to_address = NULL;
    char *the_subject = NULL;
    char *ccaddr = NULL;
    char *keywords = NULL;
    char *searchpart = NULL;
    char *body = NULL;
    char *cp = NULL, *cp1 = NULL;
    int i;
    int c = 0;	/* user input */
    char my_tmpfile[LY_MAXPATH];
    char default_subject[MAX_SUBJECT + 10];
#if USE_VMS_MAILER
    char *command = NULL;
    BOOLEAN isPMDF = LYMailPMDF();
    char hdrfile[LY_MAXPATH];
    FILE *hfd = 0;
#else
#if !CAN_PIPE_TO_MAILER
    char tmpfile2[LY_MAXPATH];
#endif
    char buf[4096];	/* 512 */
    char *header = NULL;
    int n;
#endif /* USE_VMS_MAILER */

    CTRACE((tfp, "reply_by_mail(\"%s\", \"%s\", \"%s\", \"%s\")\n",
	NONNULL(mail_address),
	NONNULL(filename),
	NONNULL(title),
	NONNULL(refid)));

    term_letter = FALSE;

    if (!LYSystemMail())
	return;

    if (isEmpty(mail_address)) {
	HTAlert(NO_ADDRESS_IN_MAILTO_URL);
	return;
    }
    StrAllocCopy(to_address, mail_address);

    if ((fd = LYOpenTemp(my_tmpfile, ".txt", "w")) == NULL) {
	HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
	return;
    }
#if USE_VMS_MAILER
    if (isPMDF) {
	if ((hfd = LYOpenTemp(hdrfile, ".txt", "w")) == NULL) {
	    HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
	    return;
	}
    }
#endif /* VMS */
    default_subject[0] = '\0';

    /*
     *	Check for a ?searchpart. - FM
     */
    if ((cp = strchr(to_address, '?')) != NULL) {
	StrAllocCopy(searchpart, cp);
	*cp = '\0';
	cp = (searchpart + 1);
	if (*cp != '\0') {
	    /*
	     *	Seek and handle a subject=foo. - FM
	     */
	    extract_subject(default_subject, searchpart);

	    /*
	     *	Seek and handle to=address(es) fields.
	     *	Appends to address. - FM
	     */
	    extract_field(&to_address, searchpart, "to=");

	    /*
	     *	Seek and handle cc=address(es) fields.	Excludes
	     *	Bcc=address(es) as unsafe.  We may append our own
	     *	cc (below) as a list for the actual mailing. - FM
	     */
	    extract_field(&ccaddr, searchpart, "cc=");

	    /*
	     *	Seek and handle keywords=term(s) fields. - FM
	     */
	    extract_field(&keywords, searchpart, "keywords=");

	    if (keywords != NULL) {
		if (*keywords != '\0') {
		    SafeHTUnEscape(keywords);
		} else {
		    FREE(keywords);
		}
	    }

	    /*
	     *	Seek and handle body=foo fields. - FM
	     */
	    extract_body(&body, searchpart);

	    FREE(searchpart);
	}
    }

    if (convert_explorer(to_address)) {
	HTAlert(NO_ADDRESS_IN_MAILTO_URL);
	goto cancelled;
    }
    if (ccaddr != NULL) {
	if (convert_explorer(ccaddr)) {
	    FREE(ccaddr);
	}
    }

    /*
     *	Unescape the address and ccaddr fields. - FM
     */
    SafeHTUnEscape(to_address);
    if (ccaddr != NULL) {
	SafeHTUnEscape(ccaddr);
    }

    /*
     *	Set the default subject. - FM
     */
    if (isEmpty(default_subject) && !isEmpty(title)) {
	strncpy(default_subject, title, MAX_SUBJECT);
	default_subject[MAX_SUBJECT] = '\0';
    }

    /*
     *	Use ^G to cancel mailing of comment
     *	and don't let SIGINTs exit lynx.
     */
    signal(SIGINT, terminate_letter);

#if USE_VMS_MAILER
    if (isPMDF || !body) {
	/*
	 *  Put the X-URL and X-Mailer lines in the hdrfile
	 *  for PMDF or my_tmpfile for VMS MAIL. - FM
	 */
	fprintf((isPMDF ? hfd : fd),
		"X-URL: %s%s\n",
		isEmpty(filename) ? STR_MAILTO_URL : filename,
		isEmpty(filename) ? to_address : "");
	fprintf((isPMDF ? hfd : fd),
		"X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);
#ifdef NO_ANONYMOUS_EMAIL
	if (!isPMDF) {
	    fprintf(fd, "\n");
	}
#endif /* NO_ANONYMOUS_EMAIL */
    }
#else /* Unix/DOS/Windows */
    /*
     *	Put the To: line in the header.
     */
#ifndef DOSPATH
    asprintf(&header, "To: %s\n", to_address);
    if (!header) {
	fprintf(stderr, "Out of memory, you lose!\n");
	exit(1);
    }
#endif

    /*
     *	Put the Mime-Version, Content-Type and
     *	Content-Transfer-Encoding in the header.
     *	This assumes that the same character set is used
     *	for composing the mail which is currently selected
     *	as display character set...
     *	Don't send a charset if we have a CJK character set
     *	selected, since it may not be appropriate for mail...
     *	Also don't use an unofficial "x-" charset.
     *	Also if the charset would be "us-ascii" (7-bit replacements
     *	selected, don't send any MIME headers. - kw
     */
    if (strncasecomp(LYCharSet_UC[current_char_set].MIMEname,
		     "us-ascii", 8) != 0) {
	StrAllocCat(header, "Mime-Version: 1.0\n");
	if (!LYHaveCJKCharacterSet &&
	    strncasecomp(LYCharSet_UC[current_char_set].MIMEname, "x-", 2)
	    != 0) {
	    HTSprintf(&header, "Content-Type: text/plain; charset=%s\n",
		    LYCharSet_UC[current_char_set].MIMEname);
	}
	StrAllocCat(header, "Content-Transfer-Encoding: 8bit\n");
    }
    /*
     *	Put the X-URL and X-Mailer lines in the header.
     */
    if (!isEmpty(filename)) {
	HTSprintf(&header, "X-URL: %s\n", filename);
    } else {
	HTSprintf(&header, "X-URL: mailto:%s\n", to_address);
    }
    HTSprintf(&header, "X-Mailer: %s, Version %s\n", LYNX_NAME, LYNX_VERSION);

    if (!isEmpty(refid)) {
	HTSprintf(&header, "In-Reply-To: <%s>\n", refid);
    }
#endif /* VMS */

    /*
     *	Clear the screen and inform the user.
     */
    LYclear();
    LYmove(2,0);
    scrollok(LYwin, TRUE);	/* Enable scrolling. */
    if (body)
	LYaddstr(SENDING_MESSAGE_WITH_BODY_TO);
    else
	LYaddstr(SENDING_COMMENT_TO);
    show_addresses(to_address);
    if (
#if USE_VMS_MAILER
	(isPMDF == TRUE) &&
#endif /* VMS */
	(cp = ccaddr) != NULL)
    {
	if (strchr(cp, ',') != NULL) {
	    LYaddstr(WITH_COPIES_TO);
	} else {
	    LYaddstr(WITH_COPY_TO);
	}
	show_addresses(ccaddr);
    }
    LYaddstr(CTRL_G_TO_CANCEL_SEND);

#if USE_VMS_MAILER
    if (isPMDF || !body) {
#endif /* USE_VMS_MAILER */
#ifndef NO_ANONYMOUS_EMAIL
    /*
     *	Get the user's personal name.
     */
    LYaddstr(ENTER_NAME_OR_BLANK);
#if USE_VMS_MAILER
    if (isPMDF) {
	label = "Personal_name: ";
    } else {
	label = "X-Personal_name: ";
    }
#else
    label = "X-Personal_Name: ";
#endif /* USE_VMS_MAILER */
    if (!header_prompt(label, &personal_name, LINESIZE)) {
	goto cancelled;
    }
    if (*personal_name) {
#if USE_VMS_MAILER
	fprintf((isPMDF ? hfd : fd), "%s: %s\n", label, personal_name);
#else
	HTSprintf(&header, "%s: %s\n", label, personal_name);
#endif /* VMS */
    }

    /*
     *	Get the user's return address.
     */
    LYaddstr(ENTER_MAIL_ADDRESS_OR_OTHER);
    LYaddstr(MEANS_TO_CONTACT_FOR_RESPONSE);
#if USE_VMS_MAILER
    if (isPMDF) {
	label = "From";
    } else {
	label = "X-From";
    }
#else
    label = "From";
#endif /* VMS */
    /* Add the personal mail address if there is one. */
    if (personal_mail_address)
	StrAllocCopy(from_address, personal_mail_address);
    if (!header_prompt(label, &from_address, LINESIZE)) {
	goto cancelled;
    }
#if USE_VMS_MAILER
    if (*from_address) {
	fprintf(isPMDF ? hfd : fd, "%s: %s\n", label, from_address);
    }
    if (!isPMDF) {
	fprintf(fd, "\n");
    }
#else
    HTSprintf(&header, "%s: %s\n", label, from_address);
#endif /* USE_VMS_MAILER */
#endif /* !NO_ANONYMOUS_EMAIL */
#if USE_VMS_MAILER
    }
#endif /* USE_VMS_MAILER */

    /*
     *	Get the subject line.
     */
    LYaddstr(ENTER_SUBJECT_LINE);
    label = "Subject";
    if (*default_subject) {
	StrAllocCopy(the_subject, default_subject);
    } else if (!isEmpty(filename)) {
	HTSprintf(&the_subject, "%s", filename);
    } else {
	HTSprintf(&the_subject, "mailto:%s", to_address);
    }
    if (!header_prompt(label, &the_subject, MAX_SUBJECT)) {
	goto cancelled;
    }

    /*
     *	Offer a CC line, if permitted. - FM
     */
    if (!LYNoCc) {
	LYaddstr(ENTER_ADDRESS_FOR_CC);
	LYaddstr(BLANK_FOR_NO_COPY);
	if (personal_mail_address)
	    StrAllocCopy(cc_address, personal_mail_address);
	if (!header_prompt("Cc", &cc_address, LINESIZE)) {
	    goto cancelled;
	}
	comma_append(&ccaddr, cc_address);
    }

#if !USE_VMS_MAILER
    HTSprintf(&header, "%s: %s\n", label, the_subject);
#if !CAN_PIPE_TO_MAILER
    if (*to_address) {
	HTSprintf(&header, "To: %s\n", to_address);
    }
#endif

    /*
    **	Add the Cc: header. - FM
    */
    if (!isEmpty(ccaddr)) {
	HTSprintf(&header, "Cc: %s\n", ccaddr);
    }

    /*
    **	Add the Keywords: header. - FM
    */
    if (!isEmpty(keywords)) {
	HTSprintf(&header, "Keywords: %s\n", keywords);
    }

    /*
     *	Terminate the header.
     */
    StrAllocCat(header, "\n");
    CTRACE((tfp,"**header==\n%s",header));
#endif /* !VMS */

    if (!no_editor && !isEmpty(editor)) {

	if (body) {
	    cp1 = body;
	    while((cp = strchr(cp1, '\n')) != NULL) {
		*cp++ = '\0';
		fprintf(fd, "%s\n", cp1);
		cp1 = cp;
	    }
	} else if (strcmp(HTLoadedDocumentURL(), "")) {
	    /*
	     *	Ask if the user wants to include the original message.
	     */
	    BOOLEAN is_preparsed = (BOOL) (LYPreparsedSource &&
				    HTisDocumentSource());
	    if (HTConfirm(is_preparsed
		? INC_PREPARSED_MSG_PROMPT
		: INC_ORIG_MSG_PROMPT) == YES) {
		print_wwwfile_to_fd(fd, (BOOL) !is_preparsed);
	    }
	}
	LYCloseTempFP(fd);	/* Close the tmpfile. */
	scrollok(LYwin,FALSE);	/* Stop scrolling.    */

	if (term_letter || LYCharIsINTERRUPT(c))
	    goto cleanup;

	/*
	 *  Spawn the users editor on the mail file
	 */
	edit_temporary_file(my_tmpfile, "", SPAWNING_EDITOR_FOR_MAIL);

    } else if (body) {
	/*
	 *  Let user review the body. - FM
	 */
	LYclear();
	LYmove(0,0);
	LYaddstr(REVIEW_MESSAGE_BODY);
	LYrefresh();
	cp1 = body;
	i = (LYlines - 5);
	while((cp = strchr(cp1, '\n')) != NULL) {
	    if (i <= 0) {
		LYaddstr(RETURN_TO_CONTINUE);
		LYrefresh();
		c = LYgetch();
		LYaddstr("\n");
		if (term_letter || LYCharIsINTERRUPT(c)) {
		    goto cancelled;
		}
		i = (LYlines - 2);
	    }
	    *cp++ = '\0';
	    fprintf(fd, "%s\n", cp1);
	    LYaddstr(cp1);
	    LYaddstr("\n");
	    cp1 = cp;
	    i--;
	}
	while (i >= 0) {
	    LYaddstr("\n");
	    i--;
	}
	LYrefresh();
	LYCloseTempFP(fd);	/* Close the tmpfile.	  */
	scrollok(LYwin,FALSE);	/* Stop scrolling.	  */

    } else {
	/*
	 *  Use the internal line editor for the message.
	 */
	LYaddstr(ENTER_MESSAGE_BELOW);
	LYaddstr(ENTER_PERIOD_WHEN_DONE_A);
	LYaddstr(ENTER_PERIOD_WHEN_DONE_B);
	LYaddstr("\n\n");
	LYrefresh();
	*user_input = '\0';
	if (LYgetstr(user_input, VISIBLE, sizeof(user_input), NORECALL) < 0 ||
	    term_letter || STREQ(user_input, ".")) {
	    goto cancelled;
	}

	while (!STREQ(user_input, ".") && !term_letter) {
	    LYaddstr("\n");
	    remove_tildes(user_input);
	    fprintf(fd, "%s\n", user_input);
	    *user_input = '\0';
	    if (LYgetstr(user_input, VISIBLE,
			 sizeof(user_input), NORECALL) < 0) {
		goto cancelled;
	    }
	}

	fprintf(fd, "\n");	/* Terminate the message. */
	LYCloseTempFP(fd);	/* Close the tmpfile.	  */
	scrollok(LYwin,FALSE);	/* Stop scrolling.	  */
    }

#if !USE_VMS_MAILER
    /*
     *	Ignore CTRL-C on this last question.
     */
    signal(SIGINT, SIG_IGN);
#endif /* !VMS */
    LYStatusLine = (LYlines - 1);
    c = HTConfirm (body ? SEND_MESSAGE_PROMPT : SEND_COMMENT_PROMPT);
    LYStatusLine = -1;
    if (c != YES) {
	LYclear();  /* clear the screen */
	goto cleanup;
    }
    if ((body == NULL && LynxSigFile != NULL) &&
	(fp = fopen(LynxSigFile, TXT_R)) != NULL) {
	LYStatusLine = (LYlines - 1);
	if (term_letter) {
	    _user_message(APPEND_SIG_FILE, LynxSigFile);
	    c = 0;
	} else {
	    char *msg = NULL;
	    HTSprintf0(&msg, APPEND_SIG_FILE, LynxSigFile);
	    c = HTConfirm(msg);
	    FREE(msg);
	}
	LYStatusLine = -1;
	if (c == YES) {
	    if ((fd = fopen(my_tmpfile, TXT_A)) != NULL) {
		char *buffer = NULL;
		fputs("-- \n", fd);
		while (LYSafeGets(&buffer, fp) != NULL) {
		    fputs(buffer, fd);
		}
		LYCloseOutput(fd);
		FREE(buffer);
	    }
	}
	LYCloseInput(fp);
    }
    LYclear();  /* Clear the screen. */

    /*
     *	Send the message.
     */
#if USE_VMS_MAILER
    /*
     *	Set the mail command. - FM
     */
    if (isPMDF) {
	/*
	 *  For PMDF, put any keywords and the subject
	 *  in the header file and close it. - FM
	 */
	if (!isEmpty(keywords)) {
	    fprintf(hfd, "Keywords: %s\n", keywords);
	}
	fprintf(hfd, "Subject: %s\n\n", the_subject);
	LYCloseTempFP(hfd);
	/*
	 *  Now set up the command. - FM
	 */
	HTSprintf0(&command, "%s %s %s,%s ",
		system_mail,
		system_mail_flags,
		hdrfile,
		my_tmpfile);
    } else {
	/*
	 *  For "generic" VMS MAIL, include the subject in the
	 *  command, and ignore any keywords to minimize risk
	 *  of them making the line too long or having problem
	 *  characters. - FM
	 */
	HTSprintf0(&command, "%s %s%s/subject=\"%s\" %s ",
		system_mail,
		system_mail_flags,
		(strncasecomp(system_mail, "MAIL", 4) ? "" : "/noself"),
		the_subject,
		my_tmpfile);
    }

    vms_append_addrs(&command, to_address, "");
    if (!isEmpty(ccaddr)) {
	vms_append_addrs(&command, ccaddr, "/CC");
    }

    stop_curses();
    printf("%s\n\n$ %s\n\n%s", SENDING_COMMENT, command, PLEASE_WAIT);
    LYSystem(command);	/* SENDING COMMENT (VMS) */
    FREE(command);
    LYSleepAlert();
    start_curses();
#else /* Unix/DOS/Windows */
    /*
     *	Send the tmpfile into sendmail.
     */
    _statusline(SENDING_YOUR_MSG);
#if CAN_PIPE_TO_MAILER
    signal(SIGINT, SIG_IGN);
    if ((fp = LYPipeToMailer()) == 0) {
	HTInfoMsg(CANCELLED);
    }
#else
    if ((fp = LYOpenTemp(tmpfile2, ".txt", "w")) == NULL) {
	HTAlert(MAILTO_URL_TEMPOPEN_FAILED);
    }
#endif /* CAN_PIPE_TO_MAILER */
    if (fp != 0) {
	fd = fopen(my_tmpfile, TXT_R);
	if (fd == NULL) {
	    HTInfoMsg(CANCELLED);
#if CAN_PIPE_TO_MAILER
	    pclose(fp);
#else
	    LYCloseTempFP(fp);
#endif /* CAN_PIPE_TO_MAILER */
	} else {
#if USE_BLAT_MAILER
	    if (!mail_is_blat)
		fputs(header, fp);
#else
	    fputs(header, fp);
#endif
	    while ((n = fread(buf, 1, sizeof(buf), fd)) != 0) {
		fwrite(buf, 1, n, fp);
	    }
#if CAN_PIPE_TO_MAILER
	    pclose(fp);
#else
	    LYCloseTempFP(fp);	/* Close the tmpfile. */
	    LYSendMailFile (
		to_address,
		tmpfile2,
		the_subject,
		ccaddr,
		SENDING_COMMENT);
	    LYRemoveTemp(tmpfile2);	/* Delete the tmpfile. */
#endif /* CAN_PIPE_TO_MAILER */
	    LYCloseInput(fd); /* Close the tmpfile. */
	}
    }
#endif /* USE_VMS_MAILER */
    goto cleanup;

    /*
     *	Come here to cleanup and exit.
     */
cancelled:
    HTInfoMsg(CANCELLED);
    LYCloseTempFP(fd);		/* Close the tmpfile.	*/
    scrollok(LYwin,FALSE);	/* Stop scrolling.	*/
cleanup:
    signal(SIGINT, cleanup_sig);
    term_letter = FALSE;

#if USE_VMS_MAILER
    while (LYRemoveTemp(my_tmpfile) == 0)
	;		 /* Delete the tmpfile(s). */
    if (isPMDF) {
	LYRemoveTemp(hdrfile); /* Delete the hdrfile. */
    }
#else
    FREE(header);
    LYRemoveTemp(my_tmpfile);  /* Delete the tmpfile. */
#endif /* VMS */

    FREE(from_address);
    FREE(the_subject);
    FREE(cc_address);
    FREE(to_address);
    FREE(ccaddr);
    FREE(keywords);
    FREE(body);
    return;
}
示例#29
0
文件: HTParse.c 项目: ChatanW/WebDaM
/*
**	Canonicalizes the URL in the following manner starting from the host
**	pointer:
**
**	1) The host name is converted to lowercase
**	2) Chop off port if `:80' (http), `:70' (gopher), or `:21' (ftp)
**
**	Return: OK	The position of the current path part of the URL
**			which might be the old one or a new one.
*/
PRIVATE char * HTCanon (char ** filename, char * host)
{
    char *newname = NULL;
    char *port;
    char *strptr;
    char *path;
    char *access = host-3;

    while (access>*filename && *(access-1)!='/')       /* Find access method */
	access--;
    if ((path = strchr(host, '/')) == NULL)			/* Find path */
	path = host + strlen(host);
    if ((strptr = strchr(host, '@')) != NULL && strptr<path)	   /* UserId */
	host = strptr;
    if ((port = strchr(host, ':')) != NULL && port>path)      /* Port number */
	port = NULL;

    strptr = host;				    /* Convert to lower-case */
    while (strptr<path) {
	*strptr = TOLOWER(*strptr);
	strptr++;
    }
    
    /* Does the URL contain a full domain name? This also works for a
       numerical host name. The domain name is already made lower-case
       and without a trailing dot. */
#if 0
    if (((strptr = strchr(host, '.')) == NULL || strptr >= path) &&
	strncasecomp(host, "localhost", 9)) {
	const char *domain = HTGetDomainName();
	if (domain && *domain) {
	    if ((newname = (char *) HT_CALLOC(1, strlen(*filename) + strlen(domain)+2)) == NULL)
		HT_OUTOFMEM("HTCanon");
	    if (port)
		strncpy(newname, *filename, (int) (port-*filename));
	    else
		strncpy(newname, *filename, (int) (path-*filename));
	    strcat(newname, ".");
	    strcat(newname, domain);
	}
    } else 					  /* Look for a trailing dot */
#endif
    {
	char *dot = port ? port : path;
	if (dot > *filename && *--dot=='.') {
	    char *orig=dot, *dest=dot+1;
	    while((*orig++ = *dest++));
	    if (port) port--;
	    path--;
	}
    }
    /* Chop off port if `:', `:80' (http), `:70' (gopher), or `:21' (ftp) */
    if (port) {
	if (!*(port+1) || *(port+1)=='/') {
	    if (!newname) {
		char *orig=port, *dest=port+1;
		while((*orig++ = *dest++));
	    }
	} else if ((!strncmp(access, "http", 4) &&
	     (*(port+1)=='8'&&*(port+2)=='0'&&(*(port+3)=='/'||!*(port+3)))) ||
	    (!strncmp(access, "gopher", 6) &&
	     (*(port+1)=='7'&&*(port+2)=='0'&&(*(port+3)=='/'||!*(port+3)))) ||
	    (!strncmp(access, "ftp", 3) &&
	     (*(port+1)=='2'&&*(port+2)=='1'&&(*(port+3)=='/'||!*(port+3))))) {
	    if (!newname) {
		char *orig=port, *dest=port+3;
		while((*orig++ = *dest++));
		path -= 3;   	       /* Update path position, Henry Minsky */
	    }
	} else if (newname)
	    strncat(newname, port, (int) (path-port));
    }

    if (newname) {
	char *newpath = newname+strlen(newname);
	strcat(newname, path);
	path = newpath;
	HT_FREE(*filename);				    /* Free old copy */
	*filename = newname;
    }
    return path;
}
示例#30
0
void LYDownload(char *line)
{
    char *Line = NULL, *method, *file, *sug_file = NULL;
    int method_number;
    int count;
    char *the_command = 0;
    bstring *buffer = NULL;
    bstring *command = NULL;
    char *cp;
    lynx_list_item_type *download_command = 0;
    int ch;
    RecallType recall;
    int FnameTotal;
    int FnameNum;
    BOOLEAN FirstRecall = TRUE;
    BOOLEAN SecondS = FALSE;

#ifdef VMS
    LYDidRename = FALSE;
#endif /* VMS */

    /*
     * Make sure we have a valid download file comparison string loaded via the
     * download options menu.  - FM
     */
    if (LYValidDownloadFile[0] == '\0') {
	goto failed;
    }

    /*
     * Make a copy of the LYNXDOWNLOAD internal URL for parsing.  - FM
     */
    StrAllocCopy(Line, line);

    /*
     * Parse out the File, sug_file, and the Method.
     */
    if ((file = strstr(Line, "/File=")) == NULL)
	goto failed;
    *file = '\0';
    /*
     * Go past "File=".
     */
    file += 6;

    if ((sug_file = strstr(file + 1, "/SugFile=")) != NULL) {
	*sug_file = '\0';
	/*
	 * Go past "SugFile=".
	 */
	sug_file += 9;
	HTUnEscape(sug_file);
    }

    /*
     * Make sure that the file string is the one from the last displayed
     * download options menu.  - FM
     */
    if (strcmp(file, LYValidDownloadFile)) {
	goto failed;
    }
#if defined(DIRED_SUPPORT)
    /* FIXME: use HTLocalName */
    if (!StrNCmp(file, "file://localhost", 16)) {
#ifdef __DJGPP__
	if (!StrNCmp(file + 16, "/dev/", 5))
	    file += 16;
	else {
	    file += 17;
	    file = HTDOS_name(file);
	}
#else
	file += 16;
#endif /* __DJGPP__ */
    } else if (isFILE_URL(file))
	file += LEN_FILE_URL;
    HTUnEscape(file);
#else
#if defined(_WINDOWS)		/* 1997/10/15 (Wed) 16:27:38 */
    if (!StrNCmp(file, "file://localhost/", 17))
	file += 17;
    else if (!StrNCmp(file, "file:/", 6))
	file += 6;
    HTUnEscape(file);
#endif /* _WINDOWS */
#endif /* DIRED_SUPPORT */

    if ((method = strstr(Line, "Method=")) == NULL)
	goto failed;
    /*
     * Go past "Method=".
     */
    method += 7;
    method_number = atoi(method);

    /*
     * Set up the sug_filenames recall buffer.
     */
    FnameTotal = (sug_filenames ? HTList_count(sug_filenames) : 0);
    recall = ((FnameTotal >= 1) ? RECALL_URL : NORECALL);
    FnameNum = FnameTotal;

    if (method_number < 0) {
	/*
	 * Write to local file.
	 */
	_statusline(FILENAME_PROMPT);
      retry:
	if (sug_file) {
	    BStrCopy0(buffer, sug_file);
	} else {
	    BStrCopy0(buffer, "");
	}

      check_recall:
	if ((ch = LYgetBString(&buffer, FALSE, 0, recall)) < 0 ||
	    isBEmpty(buffer) ||
	    ch == UPARROW_KEY ||
	    ch == DNARROW_KEY) {

	    if (recall && ch == UPARROW_KEY) {
		if (FirstRecall) {
		    FirstRecall = FALSE;
		    /*
		     * Use the last Fname in the list.  - FM
		     */
		    FnameNum = 0;
		} else {
		    /*
		     * Go back to the previous Fname in the list.  - FM
		     */
		    FnameNum++;
		}
		if (FnameNum >= FnameTotal) {
		    /*
		     * Reset the FirstRecall flag, and use sug_file or a blank.
		     * - FM
		     */
		    FirstRecall = TRUE;
		    FnameNum = FnameTotal;
		    _statusline(FILENAME_PROMPT);
		    goto retry;
		} else if ((cp = (char *) HTList_objectAt(sug_filenames,
							  FnameNum)) != NULL) {
		    BStrCopy0(buffer, cp);
		    if (FnameTotal == 1) {
			_statusline(EDIT_THE_PREV_FILENAME);
		    } else {
			_statusline(EDIT_A_PREV_FILENAME);
		    }
		    goto check_recall;
		}
	    } else if (recall && ch == DNARROW_KEY) {
		if (FirstRecall) {
		    FirstRecall = FALSE;
		    /*
		     * Use the first Fname in the list.  - FM
		     */
		    FnameNum = FnameTotal - 1;
		} else {
		    /*
		     * Advance to the next Fname in the list.  - FM
		     */
		    FnameNum--;
		}
		if (FnameNum < 0) {
		    /*
		     * Set the FirstRecall flag, and use sug_file or a blank.
		     * - FM
		     */
		    FirstRecall = TRUE;
		    FnameNum = FnameTotal;
		    _statusline(FILENAME_PROMPT);
		    goto retry;
		} else if ((cp = (char *) HTList_objectAt(sug_filenames,
							  FnameNum)) != NULL) {
		    BStrCopy0(buffer, cp);
		    if (FnameTotal == 1) {
			_statusline(EDIT_THE_PREV_FILENAME);
		    } else {
			_statusline(EDIT_A_PREV_FILENAME);
		    }
		    goto check_recall;
		}
	    }

	    /*
	     * Save cancelled.
	     */
	    goto cancelled;
	}

	BStrCopy(command, buffer);
	if (!LYValidateFilename(&buffer, &command))
	    goto cancelled;
#ifdef HAVE_POPEN
	else if (LYIsPipeCommand(buffer->str)) {
	    /* I don't know how to download to a pipe */
	    HTAlert(CANNOT_WRITE_TO_FILE);
	    _statusline(NEW_FILENAME_PROMPT);
	    FirstRecall = TRUE;
	    FnameNum = FnameTotal;
	    goto retry;
	}
#endif

	/*
	 * See if it already exists.
	 */
	switch (LYValidateOutput(buffer->str)) {
	case 'Y':
	    break;
	case 'N':
	    _statusline(NEW_FILENAME_PROMPT);
	    FirstRecall = TRUE;
	    FnameNum = FnameTotal;
	    goto retry;
	default:
	    goto cleanup;
	}

	/*
	 * See if we can write to it.
	 */
	CTRACE((tfp, "LYDownload: filename is %s\n", buffer->str));

	SecondS = TRUE;

	HTInfoMsg(SAVING);
#ifdef VMS
	/*
	 * Try rename() first.  - FM
	 */
	CTRACE((tfp, "command: rename(%s, %s)\n", file, buffer->str));
	if (rename(file, buffer->str)) {
	    /*
	     * Failed.  Use spawned COPY_COMMAND.  - FM
	     */
	    CTRACE((tfp, "         FAILED!\n"));
	    LYCopyFile(file, buffer->str);
	} else {
	    /*
	     * We don't have the temporary file (it was renamed to a permanent
	     * file), so set a flag to pop out of the download menu.  - FM
	     */
	    LYDidRename = TRUE;
	}
	chmod(buffer->str, HIDE_CHMOD);
#else /* Unix: */

	LYCopyFile(file, buffer->str);
	LYRelaxFilePermissions(buffer->str);
#endif /* VMS */

    } else {
	/*
	 * Use configured download commands.
	 */
	BStrCopy0(buffer, "");
	for (count = 0, download_command = downloaders;
	     count < method_number;
	     count++, download_command = download_command->next) ;	/* null body */

	/*
	 * Commands have the form "command %s [etc]" where %s is the filename.
	 */
	if (download_command->command != NULL) {
	    /*
	     * Check for two '%s' and ask for the local filename if there is.
	     */
	    if (HTCountCommandArgs(download_command->command) >= 2) {
		_statusline(FILENAME_PROMPT);

	      again:
		if (sug_file) {
		    BStrCopy0(buffer, sug_file);
		} else {
		    BStrCopy0(buffer, "");
		}

	      check_again:
		if ((ch = LYgetBString(&buffer, FALSE, 0, recall)) < 0 ||
		    isBEmpty(buffer) ||
		    ch == UPARROW_KEY ||
		    ch == DNARROW_KEY) {

		    if (recall && ch == UPARROW_KEY) {
			if (FirstRecall) {
			    FirstRecall = FALSE;
			    /*
			     * Use the last Fname in the list.  - FM
			     */
			    FnameNum = 0;
			} else {
			    /*
			     * Go back to the previous Fname in the list.  - FM
			     */
			    FnameNum++;
			}
			if (FnameNum >= FnameTotal) {
			    /*
			     * Reset the FirstRecall flag, and use sug_file or
			     * a blank.  - FM
			     */
			    FirstRecall = TRUE;
			    FnameNum = FnameTotal;
			    _statusline(FILENAME_PROMPT);
			    goto again;
			} else if ((cp = (char *) HTList_objectAt(sug_filenames,
								  FnameNum))
				   != NULL) {
			    BStrCopy0(buffer, cp);
			    if (FnameTotal == 1) {
				_statusline(EDIT_THE_PREV_FILENAME);
			    } else {
				_statusline(EDIT_A_PREV_FILENAME);
			    }
			    goto check_again;
			}
		    } else if (recall && ch == DNARROW_KEY) {
			if (FirstRecall) {
			    FirstRecall = FALSE;
			    /*
			     * Use the first Fname in the list.  - FM
			     */
			    FnameNum = FnameTotal - 1;
			} else {
			    /*
			     * Advance to the next Fname in the list.  - FM
			     */
			    FnameNum--;
			}
			if (FnameNum < 0) {
			    /*
			     * Set the FirstRecall flag, and use sug_file or a
			     * blank.  - FM
			     */
			    FirstRecall = TRUE;
			    FnameNum = FnameTotal;
			    _statusline(FILENAME_PROMPT);
			    goto again;
			} else if ((cp = (char *) HTList_objectAt(sug_filenames,
								  FnameNum))
				   != NULL) {
			    BStrCopy0(buffer, cp);
			    if (FnameTotal == 1) {
				_statusline(EDIT_THE_PREV_FILENAME);
			    } else {
				_statusline(EDIT_A_PREV_FILENAME);
			    }
			    goto check_again;
			}
		    }

		    /*
		     * Download cancelled.
		     */
		    goto cancelled;
		}

		if (no_dotfiles || !show_dotfiles) {
		    if (*LYPathLeaf(buffer->str) == '.') {
			HTAlert(FILENAME_CANNOT_BE_DOT);
			_statusline(NEW_FILENAME_PROMPT);
			goto again;
		    }
		}
		/*
		 * Cancel if the user entered "/dev/null" on Unix, or an "nl:"
		 * path on VMS.  - FM
		 */
		if (LYIsNullDevice(buffer->str)) {
		    goto cancelled;
		}
		SecondS = TRUE;
	    }

	    /*
	     * The following is considered a bug by the community.  If the
	     * command only takes one argument on the command line, then the
	     * suggested file name is not used.  It actually is not a bug at
	     * all and does as it should, putting both names on the command
	     * line.
	     */
	    count = 1;
	    HTAddParam(&the_command, download_command->command, count, file);
	    if (HTCountCommandArgs(download_command->command) > 1)
		HTAddParam(&the_command, download_command->command, ++count, buffer->str);
	    HTEndParam(&the_command, download_command->command, count);

	} else {
	    HTAlert(MISCONF_DOWNLOAD_COMMAND);
	    goto failed;
	}

	CTRACE((tfp, "command: %s\n", the_command));
	stop_curses();
	LYSystem(the_command);
	FREE(the_command);
	start_curses();
	/* don't remove(file); */
    }

    if (SecondS == TRUE) {
#ifdef VMS
	if (0 == strncasecomp(buffer->str, "sys$disk:", 9)) {
	    if (0 == StrNCmp((buffer->str + 9), "[]", 2)) {
		HTAddSugFilename(buffer->str + 11);
	    } else {
		HTAddSugFilename(buffer->str + 9);
	    }
	} else {
	    HTAddSugFilename(buffer->str);
	}
#else
	HTAddSugFilename(buffer->str);
#endif /* VMS */
    }
    goto cleanup;

  failed:
    HTAlert(CANNOT_DOWNLOAD_FILE);
    goto cleanup;

  cancelled:
    HTInfoMsg(CANCELLING);

  cleanup:
    FREE(Line);
    BStrFree(buffer);
    return;
}