]> diplodocus.org Git - nmh/blob - docs/historical/mh-jun-1982/progs/adrparse.c
Replaced use of snprintf() with memcpy()/memmove().
[nmh] / docs / historical / mh-jun-1982 / progs / adrparse.c
1 #ifdef COMMENT
2 Proprietary Rand Corporation, 1981.
3 Further distribution of this software
4 subject to the terms of the Rand
5 license agreement.
6 #endif
7
8 #include <stdio.h>
9 #include <whoami.h>
10 #include "../mh.h"
11 #include "../adrparse.h"
12
13 extern char *strcpy(), *strncpy();
14
15 #ifndef ARPANET
16 #define HOSTTBL "/dev/null"
17 #else
18 #include <imp.h>
19 #endif
20 #include <ctype.h>
21
22 char *malloc(), *calloc(), *getncpy();
23
24
25 char *
26 getname(addrs)
27 char *addrs;
28 {
29 register char *tp;
30 static char name[256];
31 static char *getaddrs;
32
33 if(!getaddrs)
34 getaddrs = addrs;
35 tp = name;
36
37 while(*getaddrs && isspace(*getaddrs))
38 getaddrs++;
39 if(!*getaddrs) {
40 getaddrs = 0;
41 return NULL;
42 }
43 while(*getaddrs && *getaddrs != ',') {
44 if(isspace(*getaddrs))
45 *tp++ = ' ';
46 else
47 *tp++ = *getaddrs;
48 getaddrs++;
49 }
50 if(*getaddrs) getaddrs++;
51 *tp = 0;
52 while(isspace(tp[-1]) && tp > name)
53 *--tp = 0;
54 tp = name;
55 while(*tp == ' ' || *tp == '\t')
56 tp++;
57 if(*tp == 0)
58 return NULL;
59 return tp;
60 }
61
62
63 struct mailname *
64 getm(str, defaulthost) /* WHY isn't it just taken from HOSTNAME?*/
65 /* Answer: REPLY uses foreign site */
66 char *str;
67 char *defaulthost;
68 {
69 register char *cp;
70 register char *mbp = 0, *mbe = 0;
71 register char *hp = 0, *he = 0;
72 register struct mailname *mp;
73 int lbrkt = 0;
74
75 if(!hosts.nh_next)
76 gethosts();
77 mp = (struct mailname *) calloc(1, sizeof *mp);
78 mp->m_headali = "";
79 mp->m_text = cp = getcpy(str);
80 while(*cp) {
81 switch(*cp) {
82 #ifdef FOO
83 case '"':
84 if(!mbp) mbp = cp;
85 do {
86 cp++;
87 } while(*cp && *cp != '"');
88 break;
89 #endif
90 case '<':
91 mbp = mbe = hp = he = mp->m_at = 0;
92 lbrkt++;
93 break;
94 case '>':
95 if(!lbrkt) {
96 fprintf(stderr, "adrparse: extraneous '>'\n");
97 goto line;
98 }
99 if(mbp && !mbe) {
100 fprintf(stderr, "adrparse: Missing host within <> spec.\n");
101 goto line;
102 } else if(hp && !he)
103 he = cp - 1;
104 goto gotaddr;
105 case ' ': if(!HOSTNUM) break;
106 if(strncmp(cp, " at ", 4) == 0 ||
107 strncmp(cp, " At ", 4) == 0 ||
108 strncmp(cp, " AT ", 4) == 0) {
109 cp++;
110 at: if (!HOSTNUM)break; /* Host 0 means no arpanet */
111 if(!mbp) {
112 fprintf(stderr, "adrparse: at without mbox\n");
113 goto line;
114 }
115 if(!mbe)
116 mbe = cp - 1;
117 if(mp->m_at) {
118 if (*mp->m_at == '!')
119 mbp = hp; /* uusite!person@site */
120 else
121 mbe = cp - 1; /* [x!]y@q@z */
122 }
123 mp->m_at = cp;
124 if(*cp != '@')
125 cp += 2;
126 hp = he = 0;
127 }
128 break;
129 case '@':
130 goto at;
131 case '!': /* uusite!otherstuff */
132 if (!mbp && !hp) break; /* Ignore leading '!'s */
133 if(mbp && !hp) { /* No other '!'s so far...*/
134 hp=mbp; /* Host name */
135 he=cp-1;
136
137 mbp = 0;
138 mp->m_at = cp;
139 }
140 break;
141 case '(':
142 if(mbp && !mbe)
143 mbe = cp - 1;
144 else if(hp && !he)
145 he = cp - 1;
146 while(*cp && *cp != ')') cp++;
147 break;
148 default:
149 if(isalnum(*cp) || *cp == '-' || *cp == '.' ||
150 *cp == '_') {
151 if(!mbp)
152 mbp = cp;
153 else if(mp->m_at && !hp)
154 hp = cp;
155 } else {
156 fprintf(stderr, "adrparse: address err: %s\n", cp);
157 goto line;
158 }
159 break;
160 }
161 cp++;
162 }
163 gotaddr:
164 if(mbp && !mbe)
165 mbe = cp - 1;
166 else if(hp && !he)
167 he = cp - 1;
168 if(!mp->m_at) {
169 if(hp) {
170 fprintf(stderr, "adrparse: HUH? host wo @\n");
171 return(0);
172 }
173 mp->m_nohost++;
174 if(defaulthost == 0) {
175 fprintf(stderr, "adrparse: Missing host\n");
176 return(0);
177 }
178 mp->m_host = getcpy(defaulthost);
179 } else {
180 while(*he == ' ') --he;
181 mp->m_host = getncpy(hp, he-hp+1);
182 mp->m_hs = hp;
183 mp->m_he = he;
184 if (*mp->m_at == '!') /* It's a uucp addr, not arpa */
185 mp->m_nohost++; /* So formatter will glue on local name*/
186 }
187 if(!mbp) {
188 fprintf(stderr, "adrparse: No mailbox: %s\n", str);
189 return(0);
190 }
191 while(*mbe == ' ') --mbe;
192 mp->m_mbox = getncpy(mbp, mbe-mbp+1);
193 if (*mp->m_at == '!') /* Going out over UUCP */
194 {
195 mp->m_hnum = -1; /* UUCP addresses are basically local*/
196 return mp;
197 }
198 #ifndef ARPANET
199 mp->m_hnum = 0;
200 return mp;
201 #else
202 if((mp->m_hnum = gethnum(mp->m_host)) == -1) {
203 fprintf(stderr, "adrparse: Unknown host: %s\n", mp->m_host);
204 #endif
205 line: fprintf(stderr, "adrparse: In address: %s\n", str);
206 return(0);
207 #ifdef ARPANET
208 }
209 if(mp->m_at && (mp->m_hnum == HOSTNUM))
210 /* Local! Try to reparse in case of UUCP address */
211 {
212 char localname[32];
213
214 strcpy(localname, mp->m_mbox); /* not same struct */
215 mnfree(mp);
216 if((mp = getm(localname,HOSTNAME)) == 0) /* Really local */
217 return(0);
218 }
219 return mp;
220 #endif
221 }
222
223
224 char *
225 getncpy(str, len)
226 char *str;
227 int len;
228 {
229 register char *cp;
230
231 cp = calloc(1, (unsigned)len + 1);
232 strncpy(cp, str, len);
233 return cp;
234 }
235
236
237 gethosts()
238 {
239 register FILE *ht;
240 register struct hosts *hp = &hosts;
241 char buf[32], hostname[16];
242 int hn;
243
244 if((ht = fopen(HOSTTBL, "r")) == NULL) {
245 hte: perror(HOSTTBL);
246 exit(1);
247 }
248 while(fgets(buf, sizeof buf, ht)) {
249 if(sscanf(buf, "%o %s", &hn, hostname) != 2)
250 goto hte;
251 hp->nh_next = (struct hosts *) calloc(1, sizeof *hp);
252 hp = hp->nh_next;
253 hp->nh_name = getcpy(hostname);
254 hp->nh_num = hn;
255 }
256 VOID fclose(ht);
257 }
258
259 long
260 gethnum(host)
261 char *host;
262 {
263 register struct hosts *hp;
264
265 for (hp = hosts.nh_next; hp; hp = hp->nh_next)
266 if(uleq(host, hp->nh_name))
267 return hp->nh_num;
268 return -1;
269 }
270
271
272 mnfree(mn)
273 register struct mailname *mn;
274 {
275 free(mn->m_mbox);
276 free(mn->m_host);
277 free(mn->m_text);
278 cndfree(mn->m_headali);
279 free((char *)mn);
280 }
281
282 #ifdef COMMENT
283 /* Eventually we should do something more like this (from tn.c) */
284 if ((hnum>>24) == 0) { /* Old format */
285 netparm.no_imp = hnum&077;
286 netparm.no_host = hnum>>6;
287 }
288 else { /* New format */
289 netparm.no_imp = hnum&0177777;
290 netparm.no_host = hnum>>16;
291 }