chkgrp.c (a2c16fbcd05e3b6aae06ec63d49418627ad9ccac) | chkgrp.c (83bc6a110657328dea5039ffa37ea447a295cb2d) |
---|---|
1/*- 2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3 * 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 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products | 1/*- 2 * Copyright (c) 1998 Dag-Erling Co�dan Sm�rgrav 3 * 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 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products |
15 * derived from this software without specific prior written permission | 15 * derived from this software withough specific prior written permission |
16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 * 28 * $Id$ |
|
27 */ 28 | 29 */ 30 |
29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD$"); | 31static const char CVSID[] = "$Id$"; |
31 32#include <err.h> 33#include <ctype.h> 34#include <stdio.h> 35#include <stdlib.h> 36#include <string.h> 37#include <sysexits.h> 38 | 32 33#include <err.h> 34#include <ctype.h> 35#include <stdio.h> 36#include <stdlib.h> 37#include <string.h> 38#include <sysexits.h> 39 |
39static char empty[] = { 0 }; | 40extern char *__progname; |
40 | 41 |
41static void | 42void |
42usage(void) 43{ | 43usage(void) 44{ |
44 fprintf(stderr, "usage: chkgrp [groupfile]\n"); | 45 fprintf(stderr, "usage: %s [groupfile]\n", __progname); |
45 exit(EX_USAGE); 46} 47 48int 49main(int argc, char *argv[]) 50{ | 46 exit(EX_USAGE); 47} 48 49int 50main(int argc, char *argv[]) 51{ |
51 unsigned int i; 52 size_t len; 53 int n = 0, k, e = 0; 54 char *line, *f[4], *p; 55 const char *cp, *gfn; | 52 unsigned int len; 53 int n = 0, i, k, e = 0; 54 char *gfn, *line, *f[4], *p; |
56 FILE *gf; 57 58 /* check arguments */ 59 switch (argc) { 60 case 1: 61 gfn = "/etc/group"; 62 break; 63 case 2: 64 gfn = argv[1]; 65 break; 66 default: 67 gfn = NULL; /* silence compiler */ 68 usage(); 69 } 70 71 /* open group file */ 72 if ((gf = fopen(gfn, "r")) == NULL) | 55 FILE *gf; 56 57 /* check arguments */ 58 switch (argc) { 59 case 1: 60 gfn = "/etc/group"; 61 break; 62 case 2: 63 gfn = argv[1]; 64 break; 65 default: 66 gfn = NULL; /* silence compiler */ 67 usage(); 68 } 69 70 /* open group file */ 71 if ((gf = fopen(gfn, "r")) == NULL) |
73 err(EX_IOERR, "%s", gfn); /* XXX - is IO_ERR the correct exit code? */ | 72 err(EX_IOERR, gfn); /* XXX - is IO_ERR the correct exit code? */ |
74 75 /* check line by line */ 76 while (++n) { 77 if ((line = fgetln(gf, &len)) == NULL) 78 break; | 73 74 /* check line by line */ 75 while (++n) { 76 if ((line = fgetln(gf, &len)) == NULL) 77 break; |
79 if (len > 0 && line[len - 1] != '\n') { 80 warnx("%s: line %d: no newline character", gfn, n); 81 e++; 82 } | |
83 while (len && isspace(line[len-1])) 84 len--; 85 86 /* ignore blank lines and comments */ 87 for (p = line; p < (line + len); p++) 88 if (!isspace(*p)) break; 89 if (!len || (*p == '#')) { 90#if 0 --- 10 unchanged lines hidden (view full) --- 101 */ 102 for (i = k = 0; k < 4; k++) { 103 for (f[k] = line+i; (i < len) && (line[i] != ':'); i++) 104 /* nothing */ ; 105 if ((k < 3) && (line[i] != ':')) 106 break; 107 line[i++] = 0; 108 } | 78 while (len && isspace(line[len-1])) 79 len--; 80 81 /* ignore blank lines and comments */ 82 for (p = line; p < (line + len); p++) 83 if (!isspace(*p)) break; 84 if (!len || (*p == '#')) { 85#if 0 --- 10 unchanged lines hidden (view full) --- 96 */ 97 for (i = k = 0; k < 4; k++) { 98 for (f[k] = line+i; (i < len) && (line[i] != ':'); i++) 99 /* nothing */ ; 100 if ((k < 3) && (line[i] != ':')) 101 break; 102 line[i++] = 0; 103 } |
109 110 if (k < 4) { 111 warnx("%s: line %d: missing field(s)", gfn, n); 112 for ( ; k < 4; k++) 113 f[k] = empty; 114 e++; 115 } 116 117 for (cp = f[0] ; *cp ; cp++) { 118 if (!isalnum(*cp) && *cp != '.' && *cp != '_' && *cp != '-' && 119 (cp > f[0] || *cp != '+')) { 120 warnx("%s: line %d: '%c' invalid character", gfn, n, *cp); 121 e++; 122 } | 104 if (k < 4) { 105 warnx("%s: line %d: missing field(s)", gfn, n); 106 e++; 107 continue; |
123 } 124 | 108 } 109 |
125 for (cp = f[3] ; *cp ; cp++) { 126 if (!isalnum(*cp) && *cp != '.' && *cp != '_' && *cp != '-' && 127 *cp != ',') { 128 warnx("%s: line %d: '%c' invalid character", gfn, n, *cp); 129 e++; 130 } 131 } 132 | |
133 /* check if fourth field ended with a colon */ 134 if (i < len) { 135 warnx("%s: line %d: too many fields", gfn, n); 136 e++; | 110 /* check if fourth field ended with a colon */ 111 if (i < len) { 112 warnx("%s: line %d: too many fields", gfn, n); 113 e++; |
114 continue; |
|
137 } 138 139 /* check that none of the fields contain whitespace */ | 115 } 116 117 /* check that none of the fields contain whitespace */ |
140 for (k = 0; k < 4; k++) { 141 if (strcspn(f[k], " \t") != strlen(f[k])) { | 118 for (k = 0; k < 4; k++) 119 if (strcspn(f[k], " \t") != strlen(f[k])) |
142 warnx("%s: line %d: field %d contains whitespace", 143 gfn, n, k+1); | 120 warnx("%s: line %d: field %d contains whitespace", 121 gfn, n, k+1); |
144 e++; 145 } 146 } | |
147 148 /* check that the GID is numeric */ 149 if (strspn(f[2], "0123456789") != strlen(f[2])) { 150 warnx("%s: line %d: GID is not numeric", gfn, n); 151 e++; | 122 123 /* check that the GID is numeric */ 124 if (strspn(f[2], "0123456789") != strlen(f[2])) { 125 warnx("%s: line %d: GID is not numeric", gfn, n); 126 e++; |
127 continue; |
|
152 } 153 154#if 0 155 /* entry is correct, so print it */ 156 printf("%s:%s:%s:%s\n", f[0], f[1], f[2], f[3]); 157#endif 158 } 159 160 /* check what broke the loop */ 161 if (ferror(gf)) 162 err(EX_IOERR, "%s: line %d", gfn, n); 163 164 /* done */ 165 fclose(gf); | 128 } 129 130#if 0 131 /* entry is correct, so print it */ 132 printf("%s:%s:%s:%s\n", f[0], f[1], f[2], f[3]); 133#endif 134 } 135 136 /* check what broke the loop */ 137 if (ferror(gf)) 138 err(EX_IOERR, "%s: line %d", gfn, n); 139 140 /* done */ 141 fclose(gf); |
166 if (e == 0) 167 printf("%s is fine\n", gfn); | |
168 exit(e ? EX_DATAERR : EX_OK); 169} | 142 exit(e ? EX_DATAERR : EX_OK); 143} |