1 /* $NetBSD: fsinfo.c,v 1.1.1.2 2009/03/20 20:26:55 christos Exp $ */ 2 3 /* 4 * Copyright (c) 1997-2009 Erez Zadok 5 * Copyright (c) 1989 Jan-Simon Pendry 6 * Copyright (c) 1989 Imperial College of Science, Technology & Medicine 7 * Copyright (c) 1989 The Regents of the University of California. 8 * All rights reserved. 9 * 10 * This code is derived from software contributed to Berkeley by 11 * Jan-Simon Pendry at Imperial College, London. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 3. All advertising materials mentioning features or use of this software 22 * must display the following acknowledgment: 23 * This product includes software developed by the University of 24 * California, Berkeley and its contributors. 25 * 4. Neither the name of the University nor the names of its contributors 26 * may be used to endorse or promote products derived from this software 27 * without specific prior written permission. 28 * 29 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 30 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 31 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 32 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 33 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 34 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 35 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 36 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 37 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 38 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 39 * SUCH DAMAGE. 40 * 41 * 42 * File: am-utils/fsinfo/fsinfo.c 43 * 44 */ 45 46 /* 47 * fsinfo 48 */ 49 50 #ifdef HAVE_CONFIG_H 51 # include <config.h> 52 #endif /* HAVE_CONFIG_H */ 53 #include <am_defs.h> 54 #include <fsi_data.h> 55 #include <fsinfo.h> 56 #include <fsi_gram.h> 57 58 /* globals */ 59 char **g_argv; 60 char *autodir = "/a"; 61 char *progname; 62 char hostname[MAXHOSTNAMELEN + 1]; 63 char *username; 64 char idvbuf[1024]; 65 dict *dict_of_hosts; 66 dict *dict_of_volnames; 67 int errors; 68 int file_io_errors; 69 int parse_errors; 70 int verbose; 71 qelem *list_of_automounts; 72 qelem *list_of_hosts; 73 74 /* 75 * Output file prefixes 76 */ 77 char *bootparams_pref; 78 char *dumpset_pref; 79 char *exportfs_pref; 80 char *fstab_pref; 81 char *mount_pref; 82 83 84 /* 85 * Argument cracking... 86 */ 87 static void 88 fsi_get_args(int c, char *v[]) 89 { 90 int ch; 91 int usage = 0; 92 char *iptr = idvbuf; 93 94 /* 95 * Determine program name 96 */ 97 if (v[0]) { 98 progname = strrchr(v[0], '/'); 99 if (progname && progname[1]) 100 progname++; 101 else 102 progname = v[0]; 103 } 104 105 if (!progname) 106 progname = "fsinfo"; 107 108 while ((ch = getopt(c, v, "a:b:d:e:f:h:m:D:U:I:qv")) != -1) 109 110 switch (ch) { 111 112 case 'a': 113 autodir = optarg; 114 break; 115 116 case 'b': 117 if (bootparams_pref) 118 fatal("-b option specified twice"); 119 bootparams_pref = optarg; 120 break; 121 122 case 'd': 123 if (dumpset_pref) 124 fatal("-d option specified twice"); 125 dumpset_pref = optarg; 126 break; 127 128 case 'h': 129 xstrlcpy(hostname, optarg, sizeof(hostname)); 130 break; 131 132 case 'e': 133 if (exportfs_pref) 134 fatal("-e option specified twice"); 135 exportfs_pref = optarg; 136 break; 137 138 case 'f': 139 if (fstab_pref) 140 fatal("-f option specified twice"); 141 fstab_pref = optarg; 142 break; 143 144 case 'm': 145 if (mount_pref) 146 fatal("-m option specified twice"); 147 mount_pref = optarg; 148 break; 149 150 case 'q': 151 verbose = -1; 152 break; 153 154 case 'v': 155 verbose = 1; 156 break; 157 158 case 'I': 159 case 'D': 160 case 'U': 161 /* sizeof(iptr) is actually that of idvbuf. See declaration above */ 162 xsnprintf(iptr, sizeof(idvbuf), "-%c%s ", ch, optarg); 163 iptr += strlen(iptr); 164 break; 165 166 default: 167 usage++; 168 break; 169 } 170 171 if (c != optind) { 172 g_argv = v + optind - 1; 173 #ifdef yywrap 174 if (yywrap()) 175 #endif /* yywrap */ 176 fatal("Cannot read any input files"); 177 } else { 178 usage++; 179 } 180 181 if (usage) { 182 fprintf(stderr, 183 "\ 184 Usage: %s [-v] [-a autodir] [-h hostname] [-b bootparams] [-d dumpsets]\n\ 185 \t[-e exports] [-f fstabs] [-m automounts]\n\ 186 \t[-I dir] [-D|-U string[=string]] config ...\n", progname); 187 exit(1); 188 } 189 190 if (g_argv[0]) 191 fsi_log("g_argv[0] = %s", g_argv[0]); 192 else 193 fsi_log("g_argv[0] = (nil)"); 194 } 195 196 197 /* 198 * Determine username of caller 199 */ 200 static char * 201 find_username(void) 202 { 203 const char *u = getlogin(); 204 205 if (!u) { 206 struct passwd *pw = getpwuid(getuid()); 207 if (pw) 208 u = pw->pw_name; 209 } 210 211 if (!u) 212 u = getenv("USER"); 213 if (!u) 214 u = getenv("LOGNAME"); 215 if (!u) 216 u = "root"; 217 218 return strdup(u); 219 } 220 221 222 /* 223 * MAIN 224 */ 225 int 226 main(int argc, char *argv[]) 227 { 228 /* 229 * Process arguments 230 */ 231 fsi_get_args(argc, argv); 232 233 /* 234 * If no hostname given then use the local name 235 */ 236 if (!*hostname && gethostname(hostname, sizeof(hostname)) < 0) { 237 perror("gethostname"); 238 exit(1); 239 } 240 hostname[sizeof(hostname) - 1] = '\0'; 241 242 /* 243 * Get the username 244 */ 245 username = find_username(); 246 247 /* 248 * New hosts and automounts 249 */ 250 list_of_hosts = new_que(); 251 list_of_automounts = new_que(); 252 253 /* 254 * New dictionaries 255 */ 256 dict_of_volnames = new_dict(); 257 dict_of_hosts = new_dict(); 258 259 /* 260 * Parse input 261 */ 262 show_area_being_processed("read config", 11); 263 if (fsi_yyparse()) 264 errors = 1; 265 errors += file_io_errors + parse_errors; 266 267 if (errors == 0) { 268 /* 269 * Do semantic analysis of input 270 */ 271 analyze_hosts(list_of_hosts); 272 analyze_automounts(list_of_automounts); 273 } 274 275 /* 276 * Give up if errors 277 */ 278 if (errors == 0) { 279 /* 280 * Output data files 281 */ 282 283 write_atab(list_of_automounts); 284 write_bootparams(list_of_hosts); 285 write_dumpset(list_of_hosts); 286 write_exportfs(list_of_hosts); 287 write_fstab(list_of_hosts); 288 } 289 col_cleanup(1); 290 291 exit(errors); 292 return errors; /* should never reach here */ 293 } 294