xref: /openbsd/usr.sbin/cron/misc.c (revision 5af055cd)
1 /*	$OpenBSD: misc.c,v 1.71 2015/11/14 13:09:14 millert Exp $	*/
2 
3 /* Copyright 1988,1990,1993,1994 by Paul Vixie
4  * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
5  * Copyright (c) 1997,2000 by Internet Software Consortium, Inc.
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
17  * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/types.h>
21 #include <sys/wait.h>
22 
23 #include <bitstring.h>		/* for structs.h */
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <time.h>		/* for structs.h */
28 
29 #include "macros.h"
30 #include "structs.h"
31 #include "funcs.h"
32 #include "globals.h"
33 
34 int LineNumber;
35 
36 /* get_char(file) : like getc() but increment LineNumber on newlines
37  */
38 int
39 get_char(FILE *file)
40 {
41 	int ch;
42 
43 	ch = getc(file);
44 	if (ch == '\n')
45 		Set_LineNum(LineNumber + 1)
46 	return (ch);
47 }
48 
49 /* unget_char(ch, file) : like ungetc but do LineNumber processing
50  */
51 void
52 unget_char(int ch, FILE *file)
53 {
54 	ungetc(ch, file);
55 	if (ch == '\n')
56 		Set_LineNum(LineNumber - 1)
57 }
58 
59 /* get_string(str, max, file, termstr) : like fgets() but
60  *		(1) has terminator string which should include \n
61  *		(2) will always leave room for the null
62  *		(3) uses get_char() so LineNumber will be accurate
63  *		(4) returns EOF or terminating character, whichever
64  */
65 int
66 get_string(char *string, int size, FILE *file, char *terms)
67 {
68 	int ch;
69 
70 	while (EOF != (ch = get_char(file)) && !strchr(terms, ch)) {
71 		if (size > 1) {
72 			*string++ = ch;
73 			size--;
74 		}
75 	}
76 
77 	if (size > 0)
78 		*string = '\0';
79 
80 	return (ch);
81 }
82 
83 /* skip_comments(file) : read past comment (if any)
84  */
85 void
86 skip_comments(FILE *file)
87 {
88 	int ch;
89 
90 	while (EOF != (ch = get_char(file))) {
91 		/* ch is now the first character of a line.
92 		 */
93 
94 		while (ch == ' ' || ch == '\t')
95 			ch = get_char(file);
96 
97 		if (ch == EOF)
98 			break;
99 
100 		/* ch is now the first non-blank character of a line.
101 		 */
102 
103 		if (ch != '\n' && ch != '#')
104 			break;
105 
106 		/* ch must be a newline or comment as first non-blank
107 		 * character on a line.
108 		 */
109 
110 		while (ch != '\n' && ch != EOF)
111 			ch = get_char(file);
112 
113 		/* ch is now the newline of a line which we're going to
114 		 * ignore.
115 		 */
116 	}
117 	if (ch != EOF)
118 		unget_char(ch, file);
119 }
120 
121 /* char *first_word(char *s, char *t)
122  *	return pointer to first word
123  * parameters:
124  *	s - string we want the first word of
125  *	t - terminators, implicitly including \0
126  * warnings:
127  *	(1) this routine is fairly slow
128  *	(2) it returns a pointer to static storage
129  */
130 char *
131 first_word(char *s, char *t)
132 {
133 	static char retbuf[2][MAX_TEMPSTR + 1];	/* sure wish C had GC */
134 	static int retsel = 0;
135 	char *rb, *rp;
136 
137 	/* select a return buffer */
138 	retsel = 1-retsel;
139 	rb = &retbuf[retsel][0];
140 	rp = rb;
141 
142 	/* skip any leading terminators */
143 	while (*s && (NULL != strchr(t, *s))) {
144 		s++;
145 	}
146 
147 	/* copy until next terminator or full buffer */
148 	while (*s && (NULL == strchr(t, *s)) && (rp < &rb[MAX_TEMPSTR])) {
149 		*rp++ = *s++;
150 	}
151 
152 	/* finish the return-string and return it */
153 	*rp = '\0';
154 	return (rb);
155 }
156