"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 }