util.c (da52b4caaf187775f6b56a72c6b16e94ad728f7b) util.c (6d8484b0d0191b66f9bfd0dfa89c06a29647f02a)
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 38 unchanged lines hidden (view full) ---

47 */
48
49static char *save2str(char *, char *);
50
51/*
52 * Return a pointer to a dynamic copy of the argument.
53 */
54char *
1/*
2 * Copyright (c) 1980, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 38 unchanged lines hidden (view full) ---

47 */
48
49static char *save2str(char *, char *);
50
51/*
52 * Return a pointer to a dynamic copy of the argument.
53 */
54char *
55savestr(str)
56 char *str;
55savestr(char *str)
57{
58 char *new;
59 int size = strlen(str) + 1;
60
61 if ((new = salloc(size)) != NULL)
62 bcopy(str, new, size);
63 return (new);
64}
65
66/*
67 * Make a copy of new argument incorporating old one.
68 */
69static char *
56{
57 char *new;
58 int size = strlen(str) + 1;
59
60 if ((new = salloc(size)) != NULL)
61 bcopy(str, new, size);
62 return (new);
63}
64
65/*
66 * Make a copy of new argument incorporating old one.
67 */
68static char *
70save2str(str, old)
71 char *str, *old;
69save2str(char *str, char *old)
72{
73 char *new;
74 int newsize = strlen(str) + 1;
75 int oldsize = old ? strlen(old) + 1 : 0;
76
77 if ((new = salloc(newsize + oldsize)) != NULL) {
78 if (oldsize) {
79 bcopy(old, new, oldsize);

--- 5 unchanged lines hidden (view full) ---

85}
86
87/*
88 * Touch the named message by setting its MTOUCH flag.
89 * Touched messages have the effect of not being sent
90 * back to the system mailbox on exit.
91 */
92void
70{
71 char *new;
72 int newsize = strlen(str) + 1;
73 int oldsize = old ? strlen(old) + 1 : 0;
74
75 if ((new = salloc(newsize + oldsize)) != NULL) {
76 if (oldsize) {
77 bcopy(old, new, oldsize);

--- 5 unchanged lines hidden (view full) ---

83}
84
85/*
86 * Touch the named message by setting its MTOUCH flag.
87 * Touched messages have the effect of not being sent
88 * back to the system mailbox on exit.
89 */
90void
93touch(mp)
94 struct message *mp;
91touch(struct message *mp)
95{
96
97 mp->m_flag |= MTOUCH;
98 if ((mp->m_flag & MREAD) == 0)
99 mp->m_flag |= MREAD|MSTATUS;
100}
101
102/*
103 * Test to see if the passed file name is a directory.
104 * Return true if it is.
105 */
106int
92{
93
94 mp->m_flag |= MTOUCH;
95 if ((mp->m_flag & MREAD) == 0)
96 mp->m_flag |= MREAD|MSTATUS;
97}
98
99/*
100 * Test to see if the passed file name is a directory.
101 * Return true if it is.
102 */
103int
107isdir(name)
108 char name[];
104isdir(char name[])
109{
110 struct stat sbuf;
111
112 if (stat(name, &sbuf) < 0)
113 return (0);
114 return (S_ISDIR(sbuf.st_mode));
115}
116
117/*
118 * Count the number of arguments in the given string raw list.
119 */
120int
105{
106 struct stat sbuf;
107
108 if (stat(name, &sbuf) < 0)
109 return (0);
110 return (S_ISDIR(sbuf.st_mode));
111}
112
113/*
114 * Count the number of arguments in the given string raw list.
115 */
116int
121argcount(argv)
122 char **argv;
117argcount(char **argv)
123{
124 char **ap;
125
126 for (ap = argv; *ap++ != NULL;)
127 ;
128 return (ap - argv - 1);
129}
130
131/*
132 * Return the desired header line from the passed message
133 * pointer (or NULL if the desired header field is not available).
134 */
135char *
118{
119 char **ap;
120
121 for (ap = argv; *ap++ != NULL;)
122 ;
123 return (ap - argv - 1);
124}
125
126/*
127 * Return the desired header line from the passed message
128 * pointer (or NULL if the desired header field is not available).
129 */
130char *
136hfield(field, mp)
137 const char *field;
138 struct message *mp;
131hfield(const char *field, struct message *mp)
139{
140 FILE *ibuf;
141 char linebuf[LINESIZE];
142 int lc;
143 char *hfield;
144 char *colon, *oldhfield = NULL;
145
146 ibuf = setinput(mp);

--- 12 unchanged lines hidden (view full) ---

159
160/*
161 * Return the next header field found in the given message.
162 * Return >= 0 if something found, < 0 elsewise.
163 * "colon" is set to point to the colon in the header.
164 * Must deal with \ continuations & other such fraud.
165 */
166int
132{
133 FILE *ibuf;
134 char linebuf[LINESIZE];
135 int lc;
136 char *hfield;
137 char *colon, *oldhfield = NULL;
138
139 ibuf = setinput(mp);

--- 12 unchanged lines hidden (view full) ---

152
153/*
154 * Return the next header field found in the given message.
155 * Return >= 0 if something found, < 0 elsewise.
156 * "colon" is set to point to the colon in the header.
157 * Must deal with \ continuations & other such fraud.
158 */
159int
167gethfield(f, linebuf, rem, colon)
168 FILE *f;
169 char linebuf[];
170 int rem;
171 char **colon;
160gethfield(FILE *f, char linebuf[], int rem, char **colon)
172{
173 char line2[LINESIZE];
174 char *cp, *cp2;
175 int c;
176
177 for (;;) {
178 if (--rem < 0)
179 return (-1);

--- 38 unchanged lines hidden (view full) ---

218}
219
220/*
221 * Check whether the passed line is a header line of
222 * the desired breed. Return the field body, or 0.
223 */
224
225char*
161{
162 char line2[LINESIZE];
163 char *cp, *cp2;
164 int c;
165
166 for (;;) {
167 if (--rem < 0)
168 return (-1);

--- 38 unchanged lines hidden (view full) ---

207}
208
209/*
210 * Check whether the passed line is a header line of
211 * the desired breed. Return the field body, or 0.
212 */
213
214char*
226ishfield(linebuf, colon, field)
227 char linebuf[];
228 char *colon;
229 const char *field;
215ishfield(char linebuf[], char *colon, const char *field)
230{
231 char *cp = colon;
232
233 *cp = 0;
234 if (strcasecmp(linebuf, field) != 0) {
235 *cp = ':';
236 return (0);
237 }
238 *cp = ':';
239 for (cp++; *cp == ' ' || *cp == '\t'; cp++)
240 ;
241 return (cp);
242}
243
244/*
245 * Copy a string and lowercase the result.
246 * dsize: space left in buffer (including space for NULL)
247 */
248void
216{
217 char *cp = colon;
218
219 *cp = 0;
220 if (strcasecmp(linebuf, field) != 0) {
221 *cp = ':';
222 return (0);
223 }
224 *cp = ':';
225 for (cp++; *cp == ' ' || *cp == '\t'; cp++)
226 ;
227 return (cp);
228}
229
230/*
231 * Copy a string and lowercase the result.
232 * dsize: space left in buffer (including space for NULL)
233 */
234void
249istrncpy(dest, src, dsize)
250 char *dest;
251 const char *src;
252 size_t dsize;
235istrncpy(char *dest, const char *src, size_t dsize)
253{
254
255 strlcpy(dest, src, dsize);
256 while (*dest)
257 *dest++ = tolower((unsigned char)*dest);
258}
259
260/*

--- 12 unchanged lines hidden (view full) ---

273static struct sstack sstack[SSTACK_SIZE];
274
275/*
276 * Pushdown current input file and switch to a new one.
277 * Set the global flag "sourcing" so that others will realize
278 * that they are no longer reading from a tty (in all probability).
279 */
280int
236{
237
238 strlcpy(dest, src, dsize);
239 while (*dest)
240 *dest++ = tolower((unsigned char)*dest);
241}
242
243/*

--- 12 unchanged lines hidden (view full) ---

256static struct sstack sstack[SSTACK_SIZE];
257
258/*
259 * Pushdown current input file and switch to a new one.
260 * Set the global flag "sourcing" so that others will realize
261 * that they are no longer reading from a tty (in all probability).
262 */
263int
281source(arglist)
282 char **arglist;
264source(char **arglist)
283{
284 FILE *fi;
285 char *cp;
286
287 if ((cp = expand(*arglist)) == NULL)
288 return (1);
289 if ((fi = Fopen(cp, "r")) == NULL) {
290 warn("%s", cp);

--- 15 unchanged lines hidden (view full) ---

306 return (0);
307}
308
309/*
310 * Pop the current input back to the previous level.
311 * Update the "sourcing" flag as appropriate.
312 */
313int
265{
266 FILE *fi;
267 char *cp;
268
269 if ((cp = expand(*arglist)) == NULL)
270 return (1);
271 if ((fi = Fopen(cp, "r")) == NULL) {
272 warn("%s", cp);

--- 15 unchanged lines hidden (view full) ---

288 return (0);
289}
290
291/*
292 * Pop the current input back to the previous level.
293 * Update the "sourcing" flag as appropriate.
294 */
295int
314unstack()
296unstack(void)
315{
316 if (ssp <= 0) {
317 printf("\"Source\" stack over-pop.\n");
318 sourcing = 0;
319 return (1);
320 }
321 (void)Fclose(input);
322 if (cond != CANY)

--- 7 unchanged lines hidden (view full) ---

330 return (0);
331}
332
333/*
334 * Touch the indicated file.
335 * This is nifty for the shell.
336 */
337void
297{
298 if (ssp <= 0) {
299 printf("\"Source\" stack over-pop.\n");
300 sourcing = 0;
301 return (1);
302 }
303 (void)Fclose(input);
304 if (cond != CANY)

--- 7 unchanged lines hidden (view full) ---

312 return (0);
313}
314
315/*
316 * Touch the indicated file.
317 * This is nifty for the shell.
318 */
319void
338alter(name)
339 char *name;
320alter(char *name)
340{
341 struct stat sb;
342 struct timeval tv[2];
343
344 if (stat(name, &sb))
345 return;
346 (void)gettimeofday(&tv[0], (struct timezone *)NULL);
347 tv[0].tv_sec++;
348 TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
349 (void)utimes(name, tv);
350}
351
352/*
353 * Get sender's name from this message. If the message has
354 * a bunch of arpanet stuff in it, we may have to skin the name
355 * before returning it.
356 */
357char *
321{
322 struct stat sb;
323 struct timeval tv[2];
324
325 if (stat(name, &sb))
326 return;
327 (void)gettimeofday(&tv[0], (struct timezone *)NULL);
328 tv[0].tv_sec++;
329 TIMESPEC_TO_TIMEVAL(&tv[1], &sb.st_mtim);
330 (void)utimes(name, tv);
331}
332
333/*
334 * Get sender's name from this message. If the message has
335 * a bunch of arpanet stuff in it, we may have to skin the name
336 * before returning it.
337 */
338char *
358nameof(mp, reptype)
359 struct message *mp;
360 int reptype;
339nameof(struct message *mp, int reptype)
361{
362 char *cp, *cp2;
363
364 cp = skin(name1(mp, reptype));
365 if (reptype != 0 || charcount(cp, '!') < 2)
366 return (cp);
367 cp2 = strrchr(cp, '!');
368 cp2--;

--- 4 unchanged lines hidden (view full) ---

373 return (cp);
374}
375
376/*
377 * Start of a "comment".
378 * Ignore it.
379 */
380char *
340{
341 char *cp, *cp2;
342
343 cp = skin(name1(mp, reptype));
344 if (reptype != 0 || charcount(cp, '!') < 2)
345 return (cp);
346 cp2 = strrchr(cp, '!');
347 cp2--;

--- 4 unchanged lines hidden (view full) ---

352 return (cp);
353}
354
355/*
356 * Start of a "comment".
357 * Ignore it.
358 */
359char *
381skip_comment(cp)
382 char *cp;
360skip_comment(char *cp)
383{
384 int nesting = 1;
385
386 for (; nesting > 0 && *cp; cp++) {
387 switch (*cp) {
388 case '\\':
389 if (cp[1])
390 cp++;

--- 9 unchanged lines hidden (view full) ---

400 return (cp);
401}
402
403/*
404 * Skin an arpa net address according to the RFC 822 interpretation
405 * of "host-phrase."
406 */
407char *
361{
362 int nesting = 1;
363
364 for (; nesting > 0 && *cp; cp++) {
365 switch (*cp) {
366 case '\\':
367 if (cp[1])
368 cp++;

--- 9 unchanged lines hidden (view full) ---

378 return (cp);
379}
380
381/*
382 * Skin an arpa net address according to the RFC 822 interpretation
383 * of "host-phrase."
384 */
385char *
408skin(name)
409 char *name;
386skin(char *name)
410{
411 char *nbuf, *bufend, *cp, *cp2;
412 int c, gotlt, lastsp;
413
414 if (name == NULL)
415 return (NULL);
416 if (strchr(name, '(') == NULL && strchr(name, '<') == NULL
417 && strchr(name, ' ') == NULL)

--- 94 unchanged lines hidden (view full) ---

512/*
513 * Fetch the sender's name from the passed message.
514 * Reptype can be
515 * 0 -- get sender's name for display purposes
516 * 1 -- get sender's name for reply
517 * 2 -- get sender's name for Reply
518 */
519char *
387{
388 char *nbuf, *bufend, *cp, *cp2;
389 int c, gotlt, lastsp;
390
391 if (name == NULL)
392 return (NULL);
393 if (strchr(name, '(') == NULL && strchr(name, '<') == NULL
394 && strchr(name, ' ') == NULL)

--- 94 unchanged lines hidden (view full) ---

489/*
490 * Fetch the sender's name from the passed message.
491 * Reptype can be
492 * 0 -- get sender's name for display purposes
493 * 1 -- get sender's name for reply
494 * 2 -- get sender's name for Reply
495 */
496char *
520name1(mp, reptype)
521 struct message *mp;
522 int reptype;
497name1(struct message *mp, int reptype)
523{
524 char namebuf[LINESIZE];
525 char linebuf[LINESIZE];
526 char *cp, *cp2;
527 FILE *ibuf;
528 int first = 1;
529
530 if ((cp = hfield("from", mp)) != NULL)

--- 42 unchanged lines hidden (view full) ---

573 }
574 return (savestr(namebuf));
575}
576
577/*
578 * Count the occurances of c in str
579 */
580int
498{
499 char namebuf[LINESIZE];
500 char linebuf[LINESIZE];
501 char *cp, *cp2;
502 FILE *ibuf;
503 int first = 1;
504
505 if ((cp = hfield("from", mp)) != NULL)

--- 42 unchanged lines hidden (view full) ---

548 }
549 return (savestr(namebuf));
550}
551
552/*
553 * Count the occurances of c in str
554 */
555int
581charcount(str, c)
582 char *str;
583 int c;
556charcount(char *str, int c)
584{
585 char *cp;
586 int i;
587
588 for (i = 0, cp = str; *cp != '\0'; cp++)
589 if (*cp == c)
590 i++;
591 return (i);
592}
593
594/*
595 * See if the given header field is supposed to be ignored.
596 */
597int
557{
558 char *cp;
559 int i;
560
561 for (i = 0, cp = str; *cp != '\0'; cp++)
562 if (*cp == c)
563 i++;
564 return (i);
565}
566
567/*
568 * See if the given header field is supposed to be ignored.
569 */
570int
598isign(field, ignore)
599 const char *field;
600 struct ignoretab ignore[2];
571isign(const char *field, struct ignoretab ignore[2])
601{
602 char realfld[LINESIZE];
603
604 if (ignore == ignoreall)
605 return (1);
606 /*
607 * Lower-case the string, so that "Status" and "status"
608 * will hash to the same place.
609 */
610 istrncpy(realfld, field, sizeof(realfld));
611 if (ignore[1].i_count > 0)
612 return (!member(realfld, ignore + 1));
613 else
614 return (member(realfld, ignore));
615}
616
617int
572{
573 char realfld[LINESIZE];
574
575 if (ignore == ignoreall)
576 return (1);
577 /*
578 * Lower-case the string, so that "Status" and "status"
579 * will hash to the same place.
580 */
581 istrncpy(realfld, field, sizeof(realfld));
582 if (ignore[1].i_count > 0)
583 return (!member(realfld, ignore + 1));
584 else
585 return (member(realfld, ignore));
586}
587
588int
618member(realfield, table)
619 char *realfield;
620 struct ignoretab *table;
589member(char *realfield, struct ignoretab *table)
621{
622 struct ignore *igp;
623
624 for (igp = table->i_head[hash(realfield)]; igp != NULL; igp = igp->i_link)
625 if (*igp->i_field == *realfield &&
626 equal(igp->i_field, realfield))
627 return (1);
628 return (0);
629}
590{
591 struct ignore *igp;
592
593 for (igp = table->i_head[hash(realfield)]; igp != NULL; igp = igp->i_link)
594 if (*igp->i_field == *realfield &&
595 equal(igp->i_field, realfield))
596 return (1);
597 return (0);
598}