📄 mmreadcfg.c
字号:
/* $Id: mmreadcfg.c,v 1.2 2003/01/01 14:54:10 mmondor Exp $ *//* * Copyright (C) 1991-2003, Matthew Mondor * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software written by Matthew Mondor. * 4. The name of Matthew Mondor may not be used to endorse or promote * products derived from this software without specific prior written * permission. * * THIS SOFTWARE IS PROVIDED BY MATTHEW MONDOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL MATTHEW MONDOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */#include <sys/types.h>#include <sys/param.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <pwd.h>#include <grp.h>#include <mmtypes.h>#include <mmstring.h>#include <mmreadcfg.h>MMCOPYRIGHT("@(#) Copyright (c) 1991-2003\n\\tMatthew Mondor. All rights reserved.\n");MMRCSID("$Id: mmreadcfg.c,v 1.2 2003/01/01 14:54:10 mmondor Exp $");char *mmreadcfg_strings[] = { "Unknown error", "Config file not found", "Illegal keyword", "String too long", "String too short", "Value too high", "Value too low", "Not a boolean value (TRUE/FALSE)", "Required keyword not found", "Keyword defined more than once", "Keyword too long", "Unmatched quote", "No keyword data/value", "Unknown error", NULL};boolmmreadcfg(char *cfgn, CARG *arg, CRES *res){ FILE *cfg; char buf[1025], *buf2; size_t pos, pos2, tmp; long num, val, *ltmp; CARG *cargp; bool QUOTE, *btmp; res->CR_Number = -1; res->CR_Err = 0; *(res->CR_Data) = 0; /* First open the config file, if we can't report an error */ if (!(cfg = fopen(cfgn, "r"))) { res->CR_Err = CRE_NOT_FOUND; return (FALSE); } /* Config file ready to read, read it then parse the lines */ ReadCfg1: while (fgets(buf, 1024, cfg)) { pos = 0; ReadCfg2: /* Find valid KEYWORD, or report error. First skip all * unprintable characters */ while (buf[pos] && (buf[pos] < 33 || buf[pos] > 126)) pos++; if (!buf[pos]) continue; /* Copy to CR_Data until space or unprintable char or null, * Also check for ';' and '#' to skip comments */ pos2 = 0; while (buf[pos] && buf[pos] > 32 && buf[pos] < 127) { if (buf[pos] == ';' || buf[pos] == '#') goto ReadCfg1; if (pos2 > 30) { fclose(cfg); res->CR_Err = CRE_KEYWD_TOO_LONG; return (FALSE); } res->CR_Data[pos2] = buf[pos]; pos2++; pos++; } res->CR_Data[pos2] = 0; /* Compare with keywords */ cargp = arg; num = 0; while (cargp->CA_Type != CAT_END) { if (!mm_strnicmp(res->CR_Data, cargp->CA_KW, 31)) { /* Was it already defined? */ if (cargp->CA_Status == CAS_TOUCHED) { res->CR_Number = num; res->CR_Err = CRE_MULT_DEF_KEYWD; fclose(cfg); return (FALSE); } /* Go fetch info for definition * Skip non-printable characters */ while (buf[pos] && (buf[pos] < 33 || buf[pos] > 126)) pos++; if ((!buf[pos]) || buf[pos] == ';' || buf[pos] == '#') { res->CR_Number = num; res->CR_Err = CRE_NO_KEYWD_DATA; fclose(cfg); return (FALSE); } /* Copy to CR_Data until space or unprintable * char or null, we also check for quotes */ pos2 = 0; QUOTE = FALSE; while (buf[pos] && buf[pos] >= 32 && buf[pos] < 127) { if (buf[pos] == '"') { if (!QUOTE) { if (pos2) { res->CR_Number = num; res->CR_Err = CRE_UNMATCHED_QUOTE; fclose(cfg); return (FALSE); } /* pos2 stays same */ QUOTE = TRUE; pos++; continue; } else { QUOTE = FALSE; res->CR_Data[pos2] = 0; pos++; break; } } if (buf[pos] == ' ' && !QUOTE) { res->CR_Data[pos2] = 0; pos++; break; } res->CR_Data[pos2] = buf[pos]; pos2++; pos++; } res->CR_Data[pos2] = 0; /* num=actual keyword, res->CR_Data=actual keyword data, Arrange with keyword type */ if (cargp->CA_Type == CAT_STR) { if (cargp->CA_Max) { if (pos2 > cargp->CA_Max) { res->CR_Number = num; res->CR_Err = CRE_STR_TOO_LONG; fclose(cfg); return (FALSE); } else if (pos2 < cargp->CA_Min) { res->CR_Number = num; res->CR_Err = CRE_STR_TOO_SHORT; fclose(cfg); return (FALSE); } } /* Set keyword string */ buf2 = cargp->CA_Data; tmp = 0; while ((buf2[tmp] = res->CR_Data[tmp])) tmp++; } else if (cargp->CA_Type == CAT_VAL) { val = atol(res->CR_Data); if (val > cargp->CA_Max && cargp->CA_Max) { res->CR_Number = num; res->CR_Err = CRE_VAL_TOO_HIGH; fclose(cfg); return (FALSE); } else if (val < cargp->CA_Min) { res->CR_Number = num; res->CR_Err = CRE_VAL_TOO_LOW; fclose(cfg); res->CR_Data[pos2] = 0; return (FALSE); } /* Set keyword long value */ ltmp = cargp->CA_Data; *ltmp = val; } else if (cargp->CA_Type == CAT_BOOL) { if (!mm_strnicmp(res->CR_Data, "TRUE", 4)) { btmp = cargp->CA_Data; *btmp = TRUE; } else if (!mm_strnicmp(res->CR_Data, "FALSE", 4)) { btmp = cargp->CA_Data; *btmp = FALSE; } else { res->CR_Number = num; res->CR_Err = CRE_NOT_BOOLEAN; fclose(cfg); return (FALSE); } } cargp->CA_Status = CAS_TOUCHED; goto ReadCfg2; } num++; cargp++; } /* Unknown */ res->CR_Err = CRE_ILLEGAL_KEYWD; fclose(cfg); return (FALSE); } fclose(cfg); /* Check if any required keyword definition was ommited */ cargp = arg; num = 0; while (cargp->CA_Type != CAT_END) { if (cargp->CA_Status == 1) { res->CR_Number = num; res->CR_Err = CRE_REQUIRED_KEYWD; return (FALSE); } cargp++; num++; } /* Config file successfully read */ return (TRUE);}boolmmmapstring(CMAP *cmap, char *str, long *res){ while (cmap->CM_Str) { if (!mm_strcmp(cmap->CM_Str, str)) { *res = cmap->CM_Val; return (TRUE); } cmap++; } return (FALSE);}gid_t *mmgetgidarray(int *n, char *groups){ gid_t *array; struct group *grp; int i; char *args[NGROUPS_MAX], wgroups[256]; mm_strncpy(wgroups, groups, 255); if ((*n = mm_straspl(args, wgroups, NGROUPS_MAX)) > 0) { if ((array = malloc(sizeof(gid_t) * (*n)))) { for (i = 0; i < *n; i++) { if ((grp = getgrnam(args[i]))) array[i] = grp->gr_gid; else break; } if (i == *n) return (array); free(array); } } return (NULL);}gid_t *mmfreegidarray(gid_t *array){ free(array); return (NULL);}uid_tmmgetuid(char *user){ struct passwd *pwd; uid_t id; if ((pwd = getpwnam(user))) id = pwd->pw_uid; else id = -1; return (id);}gid_tmmgetgid(char *group){ struct group *grp; gid_t id; if ((grp = getgrnam(group))) id = grp->gr_gid; else id = -1; return (id);}/* Intended to be called by the superuser. There is no way to retreive * privileges back after calling this function. */boolmmdropprivs(uid_t uid, gid_t *gids, int ngids){#ifndef NODROPPRIVS if (ngids) { /* First set real and effective primary group id */ if (setgid(gids[0]) || setegid(gids[0])) return (FALSE); ngids--; /* Set secondary group ids if any */ if (ngids) if (setgroups(ngids, &gids[1])) return (FALSE); } /* Finally set the real and effective user id */ if (setuid(uid) || seteuid(uid)) return (FALSE);#endif /* !NODROPPRIVS */ return (TRUE);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -