utils.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright (c) 1999 - 2002 by Sun Microsystems, Inc.
* All rights reserved.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* utils.c -- Generic variable modification functions
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <libintl.h>
#include <conflib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <ctype.h>
#include "utils.h"
/*
* Function: ynFunc
*
* Arguments: char *configFile, char *Section, char *Label, int command
* int argc, char *argv[]
*
* Description: This function implements all the manipulation functions
* for any yes no options
*
* Returns: int
*/
int
ynFunc(char *configFile, char *Section, char *Label, int command,
int argc, char *argv[])
{
char *validStrings[] = {
"yes",
"no",
NULL
};
char *usageString = " (yes or no)";
return (strFunc(configFile, Section, Label, command, argc, argv,
validStrings, usageString));
} /* ynFunc */
/*
* Function: fhFunc
*
* Arguments: char *configFile, char *Section, char *Label, int command
* int argc, char *argv[]
*
* Description: This function implements all the manipulation functions
* for any no/neither, fa, ha, both/yes options
*
* Returns: int
*/
int
fhFunc(char *configFile, char *Section, char *Label, int command,
int argc, char *argv[])
{
char *validStrings[] = {
"yes",
"both",
"ha",
"fa",
"neither",
"no",
NULL
};
char *usageString = " (yes|both, ha, fa, neither|no)";
return (strFunc(configFile, Section, Label, command, argc, argv,
validStrings, usageString));
} /* fin fhFunc() */
/*
* Function: strFunc
*
* Arguments: char *configFile, char *Section, char *Label, int command,
* int argc, char *argv[], char *validStrings[], char *usageString
*
* Description: This function is called by wrapper functions needing to
* validate, and manipulate string data. It compares the
* user-setting to validStrings, then either returning
* usageString, passed in by each wrapper depending on the
* acceptable settings, or performing command appropriately.
*
* Note: Due to internationalization issues, this function can not print
* usage messages, etc, to the console - there are too many possible
* string combinations to consider. The wrapper functions, therefore,
* spit out there own usage functions on error.
*
* Return: 0 on success
* -1 on error
*/
static int
strFunc(char *configFile, char *Section, char *Label, int command, int argc,
char *argv[], char *validStrings[], char *usageString)
{
char buffer[MAX_VALUE_LEN] = {0};
int rc, LabelExists;
/* Check to see if label already exists */
rc = GetPrivateProfileString(Section, Label, "", buffer,
MAX_VALUE_LEN-1, configFile);
if (!rc)
LabelExists = TRUE;
else
LabelExists = FALSE;
switch (command) {
case Add:
/* Now, check for the parameters. */
if (argc != 1) {
(void) fprintf(stderr,
gettext("Error: invalid configuration for %s. "
"Please specify any of: %s.\n"),
Label, gettext(usageString));
return (-1);
}
/* Now, check to make sure the item isn't already here */
if (LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is already configured in [%s]:\n"
"\t%s = %s\n"),
Label, Section, Label, buffer);
return (-1);
}
if (!checkValidStrings(validStrings, argv[0])) {
/* Add it! */
rc = WritePrivateProfileString(Section, Label,
argv[0], configFile);
if (rc) {
(void) fprintf(stderr, "%s\n", ErrorString);
return (rc);
}
return (0);
} else {
(void) fprintf(stderr,
gettext("Error: value must be one of ("));
printValidStrings(validStrings);
(void) fprintf(stderr, ").\n");
return (-1);
}
break;
case Delete:
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
rc = DeletePrivateProfileLabel(Section, Label, configFile);
if (rc) {
(void) fprintf(stderr,
"Error: %s\n", ErrorString);
}
return (rc);
break;
case Change:
/* Now, check for the parameters. */
if (argc != 1) {
(void) fprintf(stderr,
gettext("Error: new value for %s unspecified. "
"Please specify any of: %s.\n"),
Label, gettext(usageString));
return (-1);
}
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
if (!checkValidStrings(validStrings, argv[0])) {
/* Change it! */
rc = WritePrivateProfileString(Section, Label,
argv[0], configFile);
if (rc) {
(void) fprintf(stderr, "%s\n", ErrorString);
return (rc);
}
return (0);
} else {
(void) fprintf(stderr,
gettext("Error: value must be one of ("));
printValidStrings(validStrings);
(void) fprintf(stderr, ").\n");
return (-1);
}
break;
case Get:
rc = GetPrivateProfileString(Section, Label, "",
buffer, MAX_VALUE_LEN-1, configFile);
if (rc) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
(void) printf(gettext("[%s]\n\t%s = %s\n"),
Section, Label, buffer);
return (0);
break;
default:
(void) fprintf(stderr,
gettext("Error: Invalid command code!\n"));
return (-1);
} /* switch (command) */
} /* strFunc */
/*
* Function: posIntFunc
*
* Arguments: char *configFile, char *Section, char *Label, int command,
* int argc, char *argv[]
*
* Description: This function implements all the manipulation functions
* for any positive integer functions.
*
* Returns: int
*/
int
posIntFunc(char *configFile, char *Section, char *Label, int command, int argc,
char *argv[])
{
char buffer[MAX_VALUE_LEN] = {0};
int rc, LabelExists;
int value;
/* Check to see if label already exists */
rc = GetPrivateProfileString(Section, Label, "", buffer,
MAX_VALUE_LEN-1, configFile);
if (!rc)
LabelExists = TRUE;
else
LabelExists = FALSE;
switch (command) {
case Add:
/* Check for the parameters. */
if (argc != 1) {
(void) fprintf(stderr,
gettext("Error: value for %s was not specified. "
"Please specify value.\n"), Label);
return (-1);
}
/* Now, check to make sure it is not already here */
if (LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is already configured in [%s].\n"
"\tvalue = %s\n"),
Label, Section, Label, buffer);
return (-1);
}
value = atoi(argv[0]);
if (value > 0) {
/* Add it! */
rc = WritePrivateProfileInt(Section, Label,
value, configFile);
if (rc) {
(void) fprintf(stderr, "%s\n", ErrorString);
return (rc);
}
return (0);
} else {
(void) fprintf(stderr,
gettext("Error: value must be a positive,"
" non-zero integer.\n"));
return (-1);
}
break;
case Delete:
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
rc = DeletePrivateProfileLabel(Section, Label, configFile);
if (rc)
(void) fprintf(stderr, "Error: %s\n", ErrorString);
return (rc);
break;
case Change:
/* Now, check for the parameters. */
if (argc != 1) {
(void) fprintf(stderr,
gettext("Error: New value for %s was not specified."
" Please specify a value.\n"));
return (-1);
}
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
value = atoi(argv[0]);
if (value > 0) {
/* Change it! */
rc = WritePrivateProfileString(Section, Label,
argv[0], configFile);
if (rc) {
(void) fprintf(stderr, "%s\n", ErrorString);
return (rc);
}
return (0);
} else {
(void) fprintf(stderr,
gettext("Error: value must be a positive,"
" non-zero integer.\n"));
return (-1);
}
break;
case Get:
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
(void) printf(gettext("[%s]\n\t%s = %s\n"),
Section, Label, buffer);
return (0);
break;
default:
(void) fprintf(stderr,
gettext("Error: Invalid command code!\n"));
return (-1);
} /* switch (command) */
} /* posIntFunc */
/*
* Function: ipFunc
*
* Arguments: char *configFile, char *Section, char *Label, int command,
* int argc, char *argv[]
*
* Description: This function implements all the manipulation functions
* for any ip numbers or masks
*
* Returns: int
*/
int
ipFunc(char *configFile, char *Section, char *Label, int command, int argc,
char *argv[])
{
char buffer[MAX_VALUE_LEN] = {0};
int rc, LabelExists;
/* Check to see if label already exists */
rc = GetPrivateProfileString(Section, Label, "", buffer,
MAX_VALUE_LEN-1, configFile);
if (!rc)
LabelExists = TRUE;
else
LabelExists = FALSE;
switch (command) {
case Add:
/* Check for the parameters. */
if (argc != 1) {
(void) fprintf(stderr,
gettext("Error: value for %s was not specified. "
"Please specify a value.\n"), Label);
return (-1);
}
if (LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is already configured in [%s]:\n"
"\tvalue = %s\n"),
Label, Section, Label, buffer);
return (-1);
}
if (ipValid(argv[0])) {
/* Add it! */
rc = WritePrivateProfileString(Section, Label, argv[0],
configFile);
if (rc) {
(void) fprintf(stderr, "%s\n", ErrorString);
return (rc);
}
return (0);
} else {
(void) fprintf(stderr,
gettext("Error: %s is not a valid IP address.\n"),
argv[0]);
return (-1);
}
break;
case Delete:
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
rc = DeletePrivateProfileLabel(Section, Label, configFile);
if (rc)
(void) fprintf(stderr, "Error: %s\n", ErrorString);
return (rc);
break;
case Change:
/* Now, check for the parameters. */
if (argc != 1) {
(void) fprintf(stderr,
gettext("Error: new value for %s was not specified."
" Please specify a value.\n"), Label);
return (-1);
}
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
if (ipValid(argv[0])) {
/* Change it! */
rc = WritePrivateProfileString(Section, Label,
argv[0], configFile);
if (rc) {
(void) fprintf(stderr, "%s\n", ErrorString);
return (rc);
}
return (0);
} else {
(void) fprintf(stderr,
gettext("Error: %s is not a valid IP address.\n"),
argv[0]);
return (-1);
}
break;
case Get:
if (!LabelExists) {
(void) fprintf(stderr,
gettext("Error: %s is not configured in [%s].\n"),
Label, Section);
return (-1);
}
(void) printf(gettext("[%s]\n\t%s = %s\n"),
Section, Label, buffer);
return (0);
break;
default:
(void) fprintf(stderr,
gettext("Error: Invalid command code!\n"));
return (-1);
} /* switch (command) */
} /* ipFunc */
/*
* Function: getFunctions
*
* Arguments: FunctionArray, string
*
* Description: This routine returns the func entry structure associated
* with the dest named, "string"
*
* Returns: FuncEntry
*
*/
FuncEntry *
getFunctions(FuncEntry Funcs[], char *string)
{
int i;
for (i = 0; Funcs[i].tag; i++)
if (!strcasecmp(string, Funcs[i].tag)) {
return (&Funcs[i]);
}
return (NULL);
} /* getFunctions */
/*
* Function: Str2Command
*
* Arguments: string
*
* Description: This routine returns the command associated
* with the command string, "string"
*
* Returns: Command
*
*/
Command
Str2Command(char *string)
{
extern CommandTable Commands[];
int i;
for (i = 0; Commands[i].string; i++)
if (!strcasecmp(string, Commands[i].string)) {
return (Commands[i].command);
}
return (-1);
} /* Str2Command */
/*
* Function: Command2Str
*
* Arguments: command
*
* Description: This function translates a command into a string.
*
* Returns: char *
*
*/
char *
Command2Str(Command cmd)
{
extern CommandTable Commands[];
CommandTable *item;
for (item = Commands; item->string; item++)
if (item->command == cmd)
return (item->string);
return ("Unknown");
} /* Command2Str */
/*
* Function: sectionDump
*
* Arguments: configFile, Section, funcs
*
* Description: This funciton will dump the value of particular
* labels (Funcs) in the given section.
*
* Returns: void
*
*/
void
sectionDump(char *configFile, char *Section, FuncEntry Funcs[])
{
int i;
int rc;
char buffer[MAX_VALUE_LEN] = {0};
(void) printf(gettext("[%s]\n"), Section);
for (i = 0; Funcs[i].tag; i++) {
rc = GetPrivateProfileString(Section, Funcs[i].Label, "",
buffer, MAX_VALUE_LEN-1, configFile);
/* If the item was there, and it was not null, then print it */
if (!rc && *buffer) {
(void) printf(gettext("\t%s = %s\n"),
Funcs[i].Label, buffer);
}
}
} /* sectionDump */
/*
* Function: checkValidStrings
*
* Arguments: validStrings, string
*
* Description: This function returns zero if the passed in string
* is in validStrings.
*
* Returns: int
*
*/
int
checkValidStrings(char *validStrings[], char *string)
{
char *probe;
int i = 0;
for (probe = validStrings[i]; probe; probe = validStrings[++i])
if (!strcasecmp(probe, string))
return (0);
return (-1);
} /* checkValidStrings */
/*
* Function: printValidStrings
*
* Arguments: validStrings
*
* Description: This routine prints out the valid strings for
* display messages.
*
* Returns: void
*
*/
void
printValidStrings(char *validStrings[])
{
char *probe;
int i = 0;
for (probe = validStrings[i]; probe; probe = validStrings[++i])
(void) fprintf(stderr, "%s ", probe);
} /* printValidStrings */
/*
* Function: ipValid
*
* Arguments: ipString
*
* Description: This function returns true if the string is valid.
* TODO: Use inet_pton to validate string.
*
* Returns: int
*
*/
int
ipValid(char *ipString)
{
#if 0
uint32_t in_addr;
in_addr = inet_pton(ipString);
(void) fprintf(stderr, "DEBUG: inet_pton(\"%s\") =0x%08x\n",
ipString, in_addr);
return (-1);
#else
int a, b, c, d;
int rc;
rc = sscanf(ipString, "%d.%d.%d.%d", &a, &b, &c, &d);
/* Check the parsing */
if (rc != 4)
return (0);
/* Check the bounds of each number */
if ((a < 0 || a > 255) ||
(b < 0 || b > 255) ||
(c < 0 || c > 255) ||
(d < 0 || d > 255))
return (0);
/* otherwise, it's valid */
return (1);
#endif
} /* ipValid */
/*
* Function: naiValid
*
* Arguments: string
*
* Description: This function returns true if the strings looks like
* a valid NAI.
* TODO: use RFC to validate NAI.
*
* Returns: int
*
*/
int
naiValid(char *ipString)
{
int atFound = FALSE;
/*
* Walk through the string, checking for at least one at,
* and no wierd characters.
*/
for (; *ipString; ipString++) {
if (*ipString == '@') {
if (atFound) {
/* Error: two @ symbols! */
return (0);
} else {
atFound = TRUE;
}
continue; /* to keep the if from nesting */
}
if (isspace(*ipString))
return (0);
}
if (atFound)
return (1); /* Success! */
else
return (0);
} /* naiValid */
/*
* Function: hexCheck
*
* Arguments: string
*
* Description: Check the string to make sure it is a valid Hex string
*
* Returns: int
*
*/
int
hexValid(char *string)
{
if (strlen(string) % 2) {
(void) fprintf(stderr,
gettext("Error: hex string must be of even length.\n"));
return (0);
}
for (; *string; string++) {
if (!isxdigit(*string))
return (0);
}
return (1);
} /* hexValid */
/*
* Function: addEmptySection
*
* Arguments: char *configFile, char *SectionName
*
* Description: This routine will add an empty section to a config file,
* by creating a section with a dummy label, then deleting
* the label. NOTE: If the section already exists, this
* function is a NOP. Also, if the label "DummyLabel"
* already exists in the section, it will be deleted as a side
* effect.
*
* Returns: int
*
*/
int
addEmptySection(char *configFile, char *Section)
{
int rc;
char *Label = "DummyLabel";
char *Value = "DummyValue";
rc = WritePrivateProfileString(Section, Label, Value, configFile);
if (rc) {
(void) fprintf(stderr, "Error: %s\n", ErrorString);
return (1);
}
rc = DeletePrivateProfileLabel(Section, Label, configFile);
if (rc) {
(void) fprintf(stderr, "Error: %s\n", ErrorString);
return (1);
}
return (0);
} /* addEmptySection */