17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0f1702c5SYu Xiangning * Common Development and Distribution License (the "License"). 6*0f1702c5SYu Xiangning * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 217c478bd9Sstevel@tonic-gate /* 22*0f1702c5SYu Xiangning * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23*0f1702c5SYu Xiangning * Use is subject to license terms. 247c478bd9Sstevel@tonic-gate */ 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate #include <stdio.h> 277c478bd9Sstevel@tonic-gate #include <sys/stat.h> 287c478bd9Sstevel@tonic-gate #include <stdlib.h> 297c478bd9Sstevel@tonic-gate #include <unistd.h> 307c478bd9Sstevel@tonic-gate #include <string.h> 317c478bd9Sstevel@tonic-gate #include <ctype.h> 327c478bd9Sstevel@tonic-gate #include <locale.h> 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #define MAXLINELEN 4096 357c478bd9Sstevel@tonic-gate 367c478bd9Sstevel@tonic-gate /* 377c478bd9Sstevel@tonic-gate * Usage: 387c478bd9Sstevel@tonic-gate * sonconfig -f <file> 397c478bd9Sstevel@tonic-gate * Reads input from file. The file is structured as 40*0f1702c5SYu Xiangning * <fam> <type> <protocol> <path|module> 417c478bd9Sstevel@tonic-gate * <fam> <type> <protocol> 427c478bd9Sstevel@tonic-gate * with the first line registering and the second line 437c478bd9Sstevel@tonic-gate * deregistering. 447c478bd9Sstevel@tonic-gate * 45*0f1702c5SYu Xiangning * soconfig <fam> <type> <protocol> <path|module> 467c478bd9Sstevel@tonic-gate * registers 477c478bd9Sstevel@tonic-gate * 487c478bd9Sstevel@tonic-gate * soconfig <fam> <type> <protocol> 497c478bd9Sstevel@tonic-gate * deregisters 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate 527c478bd9Sstevel@tonic-gate static int parse_file(char *filename); 537c478bd9Sstevel@tonic-gate 547c478bd9Sstevel@tonic-gate static int split_line(char *line, char *argvec[], int maxargvec); 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate static int parse_params(char *famstr, char *typestr, char *protostr, 577c478bd9Sstevel@tonic-gate char *path, int line); 587c478bd9Sstevel@tonic-gate 597c478bd9Sstevel@tonic-gate static int parse_int(char *str); 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate static void usage(void); 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate int 647c478bd9Sstevel@tonic-gate main(argc, argv) 657c478bd9Sstevel@tonic-gate int argc; 667c478bd9Sstevel@tonic-gate char *argv[]; 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate int ret; 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate argc--; argv++; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, ""); 737c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) 747c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" 757c478bd9Sstevel@tonic-gate #endif 767c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN); 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate if (argc == 2 && strcmp(argv[0], "-f") == 0) { 797c478bd9Sstevel@tonic-gate ret = parse_file(argv[1]); 807c478bd9Sstevel@tonic-gate exit(ret); 817c478bd9Sstevel@tonic-gate } 827c478bd9Sstevel@tonic-gate if (argc == 3) { 837c478bd9Sstevel@tonic-gate ret = parse_params(argv[0], argv[1], argv[2], NULL, -1); 847c478bd9Sstevel@tonic-gate exit(ret); 857c478bd9Sstevel@tonic-gate } 867c478bd9Sstevel@tonic-gate if (argc == 4) { 877c478bd9Sstevel@tonic-gate ret = parse_params(argv[0], argv[1], argv[2], argv[3], -1); 887c478bd9Sstevel@tonic-gate exit(ret); 897c478bd9Sstevel@tonic-gate } 907c478bd9Sstevel@tonic-gate usage(); 917c478bd9Sstevel@tonic-gate exit(1); 927c478bd9Sstevel@tonic-gate /* NOTREACHED */ 937c478bd9Sstevel@tonic-gate } 947c478bd9Sstevel@tonic-gate 957c478bd9Sstevel@tonic-gate static void 967c478bd9Sstevel@tonic-gate usage(void) 977c478bd9Sstevel@tonic-gate { 987c478bd9Sstevel@tonic-gate fprintf(stderr, gettext( 997c478bd9Sstevel@tonic-gate "Usage: soconfig -f <file>\n" 100*0f1702c5SYu Xiangning "\tsoconfig <fam> <type> <protocol> <path|module>\n" 1017c478bd9Sstevel@tonic-gate "\tsoconfig <fam> <type> <protocol>\n")); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate 1047c478bd9Sstevel@tonic-gate /* 1057c478bd9Sstevel@tonic-gate * Open the specified file and parse each line. Skip comments (everything 1067c478bd9Sstevel@tonic-gate * after a '#'). Return 1 if at least one error was encountered; otherwise 0. 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate static int 1097c478bd9Sstevel@tonic-gate parse_file(char *filename) 1107c478bd9Sstevel@tonic-gate { 1117c478bd9Sstevel@tonic-gate char line[MAXLINELEN]; 1127c478bd9Sstevel@tonic-gate char pline[MAXLINELEN]; 1137c478bd9Sstevel@tonic-gate int argcount; 1147c478bd9Sstevel@tonic-gate char *argvec[20]; 1157c478bd9Sstevel@tonic-gate FILE *fp; 1167c478bd9Sstevel@tonic-gate int linecount = 0; 1177c478bd9Sstevel@tonic-gate int numerror = 0; 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate fp = fopen(filename, "r"); 1207c478bd9Sstevel@tonic-gate if (fp == NULL) { 1217c478bd9Sstevel@tonic-gate perror("soconfig: open"); 1227c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 1237c478bd9Sstevel@tonic-gate usage(); 1247c478bd9Sstevel@tonic-gate return (1); 1257c478bd9Sstevel@tonic-gate } 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate while (fgets(line, sizeof (line) - 1, fp) != NULL) { 1287c478bd9Sstevel@tonic-gate linecount++; 1297c478bd9Sstevel@tonic-gate strcpy(pline, line); 1307c478bd9Sstevel@tonic-gate argcount = split_line(pline, argvec, 1317c478bd9Sstevel@tonic-gate sizeof (argvec) / sizeof (argvec[0])); 1327c478bd9Sstevel@tonic-gate #ifdef DEBUG 1337c478bd9Sstevel@tonic-gate { 1347c478bd9Sstevel@tonic-gate int i; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate printf("scanned %d args\n", argcount); 1377c478bd9Sstevel@tonic-gate for (i = 0; i < argcount; i++) 1387c478bd9Sstevel@tonic-gate printf("arg[%d]: %s\n", i, argvec[i]); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 1417c478bd9Sstevel@tonic-gate switch (argcount) { 1427c478bd9Sstevel@tonic-gate case 0: 1437c478bd9Sstevel@tonic-gate /* Empty line - or comment only line */ 1447c478bd9Sstevel@tonic-gate break; 1457c478bd9Sstevel@tonic-gate case 3: 1467c478bd9Sstevel@tonic-gate numerror += parse_params(argvec[0], argvec[1], 1477c478bd9Sstevel@tonic-gate argvec[2], NULL, linecount); 1487c478bd9Sstevel@tonic-gate break; 1497c478bd9Sstevel@tonic-gate case 4: 1507c478bd9Sstevel@tonic-gate numerror += parse_params(argvec[0], argvec[1], 1517c478bd9Sstevel@tonic-gate argvec[2], argvec[3], linecount); 1527c478bd9Sstevel@tonic-gate break; 1537c478bd9Sstevel@tonic-gate default: 1547c478bd9Sstevel@tonic-gate numerror++; 1557c478bd9Sstevel@tonic-gate fprintf(stderr, 1567c478bd9Sstevel@tonic-gate gettext("Malformed line: <%s>\n"), line); 1577c478bd9Sstevel@tonic-gate fprintf(stderr, 1587c478bd9Sstevel@tonic-gate gettext("\ton line %d\n"), linecount); 1597c478bd9Sstevel@tonic-gate break; 1607c478bd9Sstevel@tonic-gate } 1617c478bd9Sstevel@tonic-gate } 1627c478bd9Sstevel@tonic-gate (void) fclose(fp); 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate if (numerror > 0) 1657c478bd9Sstevel@tonic-gate return (1); 1667c478bd9Sstevel@tonic-gate else 1677c478bd9Sstevel@tonic-gate return (0); 1687c478bd9Sstevel@tonic-gate } 1697c478bd9Sstevel@tonic-gate 1707c478bd9Sstevel@tonic-gate /* 1717c478bd9Sstevel@tonic-gate * Parse a line splitting it off at whitspace characters. 1727c478bd9Sstevel@tonic-gate * Modifies the content of the string by inserting NULLs. 1737c478bd9Sstevel@tonic-gate */ 1747c478bd9Sstevel@tonic-gate static int 1757c478bd9Sstevel@tonic-gate split_line(char *line, char *argvec[], int maxargvec) 1767c478bd9Sstevel@tonic-gate { 1777c478bd9Sstevel@tonic-gate int i = 0; 1787c478bd9Sstevel@tonic-gate char *cp; 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate /* Truncate at the beginning of a comment */ 1817c478bd9Sstevel@tonic-gate cp = strchr(line, '#'); 1827c478bd9Sstevel@tonic-gate if (cp != NULL) 1837c478bd9Sstevel@tonic-gate *cp = NULL; 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate /* CONSTCOND */ 1867c478bd9Sstevel@tonic-gate while (1) { 1877c478bd9Sstevel@tonic-gate /* Skip any whitespace */ 1887c478bd9Sstevel@tonic-gate while (isspace(*line) && *line != NULL) 1897c478bd9Sstevel@tonic-gate line++; 1907c478bd9Sstevel@tonic-gate 1917c478bd9Sstevel@tonic-gate if (i >= maxargvec) 1927c478bd9Sstevel@tonic-gate return (i); 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate argvec[i] = line; 1957c478bd9Sstevel@tonic-gate if (*line == NULL) 1967c478bd9Sstevel@tonic-gate return (i); 1977c478bd9Sstevel@tonic-gate i++; 1987c478bd9Sstevel@tonic-gate /* Skip until next whitespace */ 1997c478bd9Sstevel@tonic-gate while (!isspace(*line) && *line != NULL) 2007c478bd9Sstevel@tonic-gate line++; 2017c478bd9Sstevel@tonic-gate if (*line != NULL) { 2027c478bd9Sstevel@tonic-gate /* Break off argument */ 2037c478bd9Sstevel@tonic-gate *line++ = NULL; 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate /* NOTREACHED */ 2077c478bd9Sstevel@tonic-gate } 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate /* 2107c478bd9Sstevel@tonic-gate * Parse the set of parameters and issues the sockconfig syscall. 2117c478bd9Sstevel@tonic-gate * If line is not -1 it is assumed to be the line number in the file. 2127c478bd9Sstevel@tonic-gate */ 2137c478bd9Sstevel@tonic-gate static int 2147c478bd9Sstevel@tonic-gate parse_params(char *famstr, char *typestr, char *protostr, char *path, int line) 2157c478bd9Sstevel@tonic-gate { 2167c478bd9Sstevel@tonic-gate int fam, type, protocol; 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate fam = parse_int(famstr); 2197c478bd9Sstevel@tonic-gate if (fam == -1) { 2207c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Bad family number: %s\n"), famstr); 2217c478bd9Sstevel@tonic-gate if (line != -1) 2227c478bd9Sstevel@tonic-gate fprintf(stderr, 2237c478bd9Sstevel@tonic-gate gettext("\ton line %d\n"), line); 2247c478bd9Sstevel@tonic-gate else { 2257c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 2267c478bd9Sstevel@tonic-gate usage(); 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate return (1); 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate type = parse_int(typestr); 2327c478bd9Sstevel@tonic-gate if (type == -1) { 2337c478bd9Sstevel@tonic-gate fprintf(stderr, 2347c478bd9Sstevel@tonic-gate gettext("Bad socket type number: %s\n"), typestr); 2357c478bd9Sstevel@tonic-gate if (line != -1) 2367c478bd9Sstevel@tonic-gate fprintf(stderr, 2377c478bd9Sstevel@tonic-gate gettext("\ton line %d\n"), line); 2387c478bd9Sstevel@tonic-gate else { 2397c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 2407c478bd9Sstevel@tonic-gate usage(); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate return (1); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate protocol = parse_int(protostr); 2467c478bd9Sstevel@tonic-gate if (protocol == -1) { 2477c478bd9Sstevel@tonic-gate fprintf(stderr, 2487c478bd9Sstevel@tonic-gate gettext("Bad protocol number: %s\n"), protostr); 2497c478bd9Sstevel@tonic-gate if (line != -1) 2507c478bd9Sstevel@tonic-gate fprintf(stderr, 2517c478bd9Sstevel@tonic-gate gettext("\ton line %d\n"), line); 2527c478bd9Sstevel@tonic-gate else { 2537c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 2547c478bd9Sstevel@tonic-gate usage(); 2557c478bd9Sstevel@tonic-gate } 2567c478bd9Sstevel@tonic-gate return (1); 2577c478bd9Sstevel@tonic-gate } 2587c478bd9Sstevel@tonic-gate 2597c478bd9Sstevel@tonic-gate 2607c478bd9Sstevel@tonic-gate if (path != NULL) { 2617c478bd9Sstevel@tonic-gate struct stat stats; 2627c478bd9Sstevel@tonic-gate 263*0f1702c5SYu Xiangning if (strncmp(path, "/dev", strlen("/dev")) == 0 && 264*0f1702c5SYu Xiangning stat(path, &stats) == -1) { 2657c478bd9Sstevel@tonic-gate perror(path); 2667c478bd9Sstevel@tonic-gate if (line != -1) 2677c478bd9Sstevel@tonic-gate fprintf(stderr, 2687c478bd9Sstevel@tonic-gate gettext("\ton line %d\n"), line); 2697c478bd9Sstevel@tonic-gate else { 2707c478bd9Sstevel@tonic-gate fprintf(stderr, "\n"); 2717c478bd9Sstevel@tonic-gate usage(); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate return (1); 2747c478bd9Sstevel@tonic-gate } 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate 2777c478bd9Sstevel@tonic-gate #ifdef DEBUG 2787c478bd9Sstevel@tonic-gate printf("not calling sockconfig(%d, %d, %d, %s)\n", 2797c478bd9Sstevel@tonic-gate fam, type, protocol, path == NULL ? "(null)" : path); 2807c478bd9Sstevel@tonic-gate #else 2817c478bd9Sstevel@tonic-gate if (_sockconfig(fam, type, protocol, path) == -1) { 2827c478bd9Sstevel@tonic-gate perror("sockconfig"); 2837c478bd9Sstevel@tonic-gate return (1); 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate #endif 2867c478bd9Sstevel@tonic-gate return (0); 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate static int 2907c478bd9Sstevel@tonic-gate parse_int(char *str) 2917c478bd9Sstevel@tonic-gate { 2927c478bd9Sstevel@tonic-gate char *end; 2937c478bd9Sstevel@tonic-gate int res; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate res = strtol(str, &end, 0); 2967c478bd9Sstevel@tonic-gate if (end == str) 2977c478bd9Sstevel@tonic-gate return (-1); 2987c478bd9Sstevel@tonic-gate return (res); 2997c478bd9Sstevel@tonic-gate } 300