"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "petidomo-4.0b6/librfc822/address_sep.c" of archive petidomo-4.0b6.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /*
    2    $Source: /e/ossp/cvs/ossp-pkg/petidomo/librfc822/address_sep.c,v $
    3    $Revision: 1.2 $
    4 
    5    Copyright (C) 2000 by CyberSolutions GmbH, Germany.
    6 
    7    This file is part of OpenPetidomo.
    8 
    9    OpenPetidomo is free software; you can redistribute it and/or modify
   10    it under the terms of the GNU General Public License as published by
   11    the Free Software Foundation; either version 2, or (at your option)
   12    any later version.
   13 
   14    OpenPetidomo is distributed in the hope that it will be useful, but
   15    WITHOUT ANY WARRANTY; without even the implied warranty of
   16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
   17    General Public License for more details.
   18 */
   19 
   20 #include <stdio.h>
   21 #include <stdlib.h>
   22 #include <errno.h>
   23 #include <assert.h>
   24 #ifdef DEBUG_DMALLOC
   25 #  include <dmalloc.h>
   26 #endif
   27 
   28 #include "rfc822.h"
   29 
   30 static char *
   31 read_until_next_quote(char * p)
   32 {
   33     while (*p) {
   34 	if (*p == '"') {
   35 	    p++;
   36 	    break;
   37 	}
   38 	if (*p == '\\' && p[1] != '\0') {
   39 	    p += 2;
   40 	    continue;
   41 	}
   42 	p++;
   43     }
   44     return p;
   45 }
   46 
   47 static char *
   48 read_until_close_bracket(char * p)
   49 {
   50     while (*p) {
   51 	if (*p == ')') {
   52 	    p++;
   53 	    break;
   54 	}
   55 	if (*p == '(') {
   56 	    p = read_until_close_bracket(p+1);
   57 	    continue;
   58 	}
   59 	else if (*p == '\\' && p[1] != '\0') {
   60 	    p += 2;
   61 	    continue;
   62 	}
   63 	else if (*p == '"') {
   64 	    p = read_until_next_quote(p+1);
   65 	    continue;
   66 	}
   67 	p++;
   68     }
   69     return p;
   70 }
   71 
   72 static int
   73 is_source_routing(char * p)
   74 {
   75     while (*p) {
   76 	if (*p == '(')
   77 	  p = read_until_close_bracket(p+1);
   78 
   79 	else if (*p == ' ' || *p == '\t')
   80 	  p++;
   81 
   82 	else if (*p == '@' || *p == '<')
   83 	  return 1;
   84 
   85 	else
   86 	  return 0;
   87     }
   88     return 0;
   89 }
   90 
   91 /* Split an RFC822 address line.
   92 
   93    This routine breaks an address line, as specified by RFC822, up
   94    into separate addresses. The used delimiter is the comma (",").
   95 
   96    The usage of the routine is very similar to strsep(3). More text to
   97    come.
   98 
   99    AUTHOR: Peter Simons <simons@rhein.de>
  100 
  101  */
  102 
  103 char *
  104 rfc822_address_sep(struct rfc822_address_sep_state *   state)
  105 {
  106     char *   p,
  107          *   old;
  108     int      allow_groups;
  109 
  110     /* Sanity checks. */
  111 
  112     assert(state != NULL);
  113     if (!state) {
  114 	errno = EINVAL;
  115 	return NULL;
  116     }
  117 
  118     if (*(state->address_line) == '\0')
  119       return NULL;
  120 
  121     old = p = state->address_line;
  122     allow_groups = !is_source_routing(p);
  123 
  124     while(*p) {
  125 	if (*p == ',') {
  126 	    *p = '\0';
  127 	    state->address_line = p+1;
  128 	    return old;
  129 	}
  130 	else if (*p == ':' && allow_groups) {
  131 	    old = p+1;
  132 	    state->group_nest++;
  133 	    allow_groups = !is_source_routing(p+1);
  134 	}
  135 	else if (*p == ';') {
  136 
  137 	    /* If we are inside an address group, the ';' character is
  138 	       interpreted like a comma. */
  139 
  140 	    if (state->group_nest > 0) {
  141 		state->group_nest--;
  142 		*p = ',';
  143 		continue;
  144 	    }
  145 	    else
  146 	      /* do nothing */;
  147 	}
  148 	else if (*p == '(') {
  149 	    p = read_until_close_bracket(p+1);
  150 	    continue;
  151 	}
  152 	else if (*p == '\\' && p[1] != '\0')
  153 	  p++;
  154 	else if (*p == '"') {
  155 	    p = read_until_next_quote(p+1);
  156 	    continue;
  157 	}
  158 	p++;
  159     }
  160     state->address_line = p;
  161     return old;
  162 }