12fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 22fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * profile.c -- A simple configuration file parsing "library in a file" 3efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 42fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * The profile library was originally written by Theodore Ts'o in 1995 52fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * for use in the MIT Kerberos v5 library. It has been 62fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * modified/enhanced/bug-fixed over time by other members of the MIT 72fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Kerberos team. This version was originally taken from the Kerberos 82fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * v5 distribution, version 1.4.2, and radically simplified for use in 92fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * e2fsprogs. (Support for locking for multi-threaded operations, 102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * being able to modify and update the configuration file 112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * programmatically, and Mac/Windows portability have been removed. 122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * It has been folded into a single C source file to make it easier to 132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * fold into an application program.) 142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * 15d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o * Copyright (C) 2005, 2006 by Theodore Ts'o. 162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * 172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * %Begin-Header% 182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * This file may be redistributed under the terms of the GNU Public 192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * License. 202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * %End-Header% 21efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Copyright (C) 1985-2005 by the Massachusetts Institute of Technology. 23efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * All rights reserved. 25efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Export of this software from the United States of America may require 272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * a specific license from the United States Government. It is the 282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * responsibility of any person or organization contemplating export to 292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * obtain such a license before exporting. 30efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * distribute this software and its documentation for any purpose and 332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * without fee is hereby granted, provided that the above copyright 342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * notice appear in all copies and that both that copyright notice and 352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * this permission notice appear in supporting documentation, and that 362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * the name of M.I.T. not be used in advertising or publicity pertaining 372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * to distribution of the software without specific, written prior 382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * permission. Furthermore if you modify this software you must label 392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * your software as modified software and not distribute it in such a 402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * fashion that it might be confused with the original MIT software. 412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * M.I.T. makes no representations about the suitability of this software 422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * for any purpose. It is provided "as is" without express or implied 432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * warranty. 44efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 48efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_UNISTD_H 522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <unistd.h> 532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <stdio.h> 552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_STDLIB_H 562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <stdlib.h> 572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <time.h> 592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <string.h> 602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <errno.h> 612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <ctype.h> 622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <limits.h> 632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <stddef.h> 642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <sys/types.h> 652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <sys/stat.h> 667d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o#include <dirent.h> 672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_PWD_H 682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include <pwd.h> 692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 71cec7103d922f89156acf25055a249fad82ed0e7aTheodore Ts'o#include <et/com_err.h> 722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include "profile.h" 73fd7ac1fc9889075885cd698ddd3287af6457c7beTheodore Ts'o#include "prof_err.h" 74fd7ac1fc9889075885cd698ddd3287af6457c7beTheodore Ts'o 755582275fe06d6f4d0679d0a1a28d069769da8b41Theodore Ts'o#undef STAT_ONCE_PER_SECOND 765582275fe06d6f4d0679d0a1a28d069769da8b41Theodore Ts'o#undef HAVE_STAT 772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * prof_int.h 802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'otypedef long prf_magic_t; 832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * This is the structure which stores the profile information for a 862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * particular configuration file. 872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 88d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'ostruct _prf_file_t { 892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_magic_t magic; 90d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o char *filespec; 912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef STAT_ONCE_PER_SECOND 922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o time_t last_stat; 932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o time_t timestamp; /* time tree was last updated from file */ 952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int flags; /* r/w, dirty */ 962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int upd_serial; /* incremented when data changes */ 97d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o struct profile_node *root; 982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct _prf_file_t *next; 992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o}; 1002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'otypedef struct _prf_file_t *prf_file_t; 1022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 1042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * The profile flags 1052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 1062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_FILE_RW 0x0001 1072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_FILE_DIRTY 0x0002 1086bde5c28ba25600f02f6d8cd2e8de39017bc421dTheodore Ts'o#define PROFILE_FILE_NO_RELOAD 0x0004 1092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 1112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * This structure defines the high-level, user visible profile_t 1122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * object, which is used as a handle by users who need to query some 1132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * configuration file(s) 1142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 1152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostruct _profile_t { 1162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_magic_t magic; 1172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_file_t first_file; 1182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o}; 1192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 1212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Used by the profile iterator in prof_get.c 1222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 1232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_ITER_LIST_SECTION 0x0001 1242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_ITER_SECTIONS_ONLY 0x0002 1252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_ITER_RELATIONS_ONLY 0x0004 1262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_ITER_FINAL_SEEN 0x0100 1282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 1302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Check if a filespec is last in a list (NULL on UNIX, invalid FSSpec on MacOS 1312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 1322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PROFILE_LAST_FILESPEC(x) (((x) == NULL) || ((x)[0] == '\0')) 1342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostruct profile_node { 1369a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o errcode_t magic; 1379a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o char *name; 1389a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o char *value; 1399a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o int group_level; 140642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o unsigned int final:1; /* Indicate don't search next file */ 141642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o unsigned int deleted:1; 1429a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o struct profile_node *first_child; 1439a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o struct profile_node *parent; 1449a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o struct profile_node *next, *prev; 1459a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o}; 1469a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o 1479a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#define CHECK_MAGIC(node) \ 1489a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o if ((node)->magic != PROF_MAGIC_NODE) \ 1499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o return PROF_MAGIC_NODE; 1509a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o 151204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o/* profile parser declarations */ 152204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'ostruct parse_state { 153204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o int state; 154204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o int group_level; 155204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o int line_num; 156204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o struct profile_node *root_section; 157204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o struct profile_node *current_section; 158204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o}; 159204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o 1606f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'ostatic const char *default_filename = "<default>"; 1616f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 162204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'ostatic profile_syntax_err_cb_t syntax_err_cb; 163204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o 164204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'ostatic errcode_t parse_line(char *line, struct parse_state *state); 1652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef DEBUG_PROGRAM 1672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_write_tree_file 1682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (struct profile_node *root, FILE *dstfile); 1692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_write_tree_to_buffer 1712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (struct profile_node *root, char **buf); 1722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 1732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void profile_free_node 1762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (struct profile_node *relation); 1772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_create_node 1792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (const char *name, const char *value, 1802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node **ret_node); 1812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef DEBUG_PROGRAM 1832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_verify_node 1842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (struct profile_node *node); 1852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 1862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_add_node 1882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (struct profile_node *section, 1892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *name, const char *value, 1902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node **ret_node); 1912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_find_node 1932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (struct profile_node *section, 1942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *name, const char *value, 1952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int section_flag, void **state, 1962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node **node); 1972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_node_iterator 1992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (void **iter_p, struct profile_node **ret_node, 2002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char **ret_name, char **ret_value); 2012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 2022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t profile_open_file 2032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (const char * file, prf_file_t *ret_prof); 2042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 205d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'ostatic errcode_t profile_update_file 206d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o (prf_file_t prf); 2072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 2082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void profile_free_file 2092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (prf_file_t profile); 2102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 2119a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ostatic errcode_t profile_get_value(profile_t profile, const char *name, 2129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char *subname, const char *subsubname, 2139a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char **ret_value); 2149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o 2152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 2162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 2172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * prof_init.c --- routines that manipulate the user-visible profile_t 2182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * object. 2192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 2202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 221efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ostatic int compstr(const void *m1, const void *m2) 2227d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o{ 223642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o const char *s1 = *((const char * const *) m1); 224642935c082ca22e1186fc9926fe06e4207d5ab56Theodore Ts'o const char *s2 = *((const char * const *) m2); 2257d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 226efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o return strcmp(s1, s2); 2277d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o} 2287d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 2297d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'ostatic void free_list(char **list) 2307d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o{ 2317d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o char **cp; 2327d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 2337d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (list == 0) 2347d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o return; 235efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 2367d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o for (cp = list; *cp; cp++) 2377d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o free(*cp); 2387d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o free(list); 2397d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o} 2407d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 2417d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'ostatic errcode_t get_dirlist(const char *dirname, char***ret_array) 2427d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o{ 2437d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o DIR *dir; 2447d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o struct dirent *de; 2457d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o struct stat st; 2467d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o errcode_t retval; 2477d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o char *fn, *cp; 2487d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o char **array = 0, **new_array; 2497d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o int max = 0, num = 0; 2507d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 2517d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o dir = opendir(dirname); 2527d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (!dir) 2537d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o return errno; 2547d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 2557d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o while ((de = readdir(dir)) != NULL) { 2567d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o for (cp = de->d_name; *cp; cp++) { 2577d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (!isalnum(*cp) && 2587d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o (*cp != '-') && 2597d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o (*cp != '_')) 2607d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o break; 2617d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 2627d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (*cp) 2637d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o continue; 2647d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o fn = malloc(strlen(dirname) + strlen(de->d_name) + 2); 2657d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (!fn) { 2667d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o retval = ENOMEM; 2677d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o goto errout; 2687d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 2697d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o sprintf(fn, "%s/%s", dirname, de->d_name); 2707d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if ((stat(fn, &st) < 0) || !S_ISREG(st.st_mode)) { 2717d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o free(fn); 2727d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o continue; 2737d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 2747d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (num >= max) { 2757d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o max += 10; 2767d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o new_array = realloc(array, sizeof(char *) * (max+1)); 2777d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (!new_array) { 2787d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o retval = ENOMEM; 279e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall free(fn); 2807d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o goto errout; 2817d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 2827d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o array = new_array; 2837d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 2847d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o array[num++] = fn; 2857d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 28612f91959993f0d2882592427c94f35f32436e03aBrian Behlendorf if (array) { 28712f91959993f0d2882592427c94f35f32436e03aBrian Behlendorf qsort(array, num, sizeof(char *), compstr); 28812f91959993f0d2882592427c94f35f32436e03aBrian Behlendorf array[num++] = 0; 28912f91959993f0d2882592427c94f35f32436e03aBrian Behlendorf } 2907d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o *ret_array = array; 2917d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o closedir(dir); 2927d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o return 0; 2937d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'oerrout: 294e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (array) 295e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall array[num] = 0; 2967d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o closedir(dir); 2977d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o free_list(array); 2987d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o return retval; 2997d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o} 3007d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 301efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 3022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_init(const char **files, profile_t *ret_profile) 3032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 3042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char **fs; 3052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_t profile; 3067d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o prf_file_t new_file, *last; 3072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval = 0; 3087d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o char **cpp, *cp, **array = 0; 3092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 3102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile = malloc(sizeof(struct _profile_t)); 3112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!profile) 3122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 3132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o memset(profile, 0, sizeof(struct _profile_t)); 3142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile->magic = PROF_MAGIC_PROFILE; 3157d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o last = &profile->first_file; 3162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 3172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* if the filenames list is not specified return an empty profile */ 3182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ( files ) { 3192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (fs = files; !PROFILE_LAST_FILESPEC(*fs); fs++) { 320e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (array) 321e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall free_list(array); 3227d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o retval = get_dirlist(*fs, &array); 3237d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (retval == 0) { 32412f91959993f0d2882592427c94f35f32436e03aBrian Behlendorf if (!array) 32512f91959993f0d2882592427c94f35f32436e03aBrian Behlendorf continue; 3267d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o for (cpp = array; (cp = *cpp); cpp++) { 3277d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o retval = profile_open_file(cp, &new_file); 3287d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (retval == EACCES) 3297d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o continue; 3307d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (retval) 3317d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o goto errout; 3327d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o *last = new_file; 3337d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o last = &new_file->next; 3347d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o } 335efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o } else if ((retval != ENOTDIR) && 3366f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o strcmp(*fs, default_filename)) 3377d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o goto errout; 3387d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o 3392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_open_file(*fs, &new_file); 3402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* if this file is missing, skip to the next */ 3412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == ENOENT || retval == EACCES) { 3422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 3432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 3447d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (retval) 3457d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o goto errout; 3467d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o *last = new_file; 3477d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o last = &new_file->next; 3482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 3492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 3507d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o * If all the files were not found, return the appropriate error. 3512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 3527d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o if (!profile->first_file) { 353e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = ENOENT; 354e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall goto errout; 3552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 3562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 3572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 3587d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o free_list(array); 3592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_profile = profile; 3602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 3617d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'oerrout: 3627d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o free_list(array); 3637d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o profile_release(profile); 3647d922f8bcba93f7d830825cb2e07b3eaee99b994Theodore Ts'o return retval; 3652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 3662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 367efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'ovoid 3682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_release(profile_t profile) 3692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 3702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_file_t p, next; 3712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 3722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!profile || profile->magic != PROF_MAGIC_PROFILE) 3732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 3742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 3752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (p = profile->first_file; p; p = next) { 3762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o next = p->next; 3772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_free_file(p); 3782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 3792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile->magic = 0; 3802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o free(profile); 3812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 3822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 3836f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o/* 3846f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o * This function sets the value of the pseudo file "<default>". If 3856f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o * the file "<default>" had previously been passed to profile_init(), 3866f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o * then def_string parameter will be parsed and used as the profile 3876f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o * information for the "<default>" file. 3886f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o */ 3896f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'oerrcode_t profile_set_default(profile_t profile, const char *def_string) 3906f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o{ 3916f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o struct parse_state state; 3926f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o prf_file_t prf; 3936f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o errcode_t retval; 3946f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o const char *in; 3956f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o char *line, *p, *end; 3966f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o int line_size, len; 3976f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 3986f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (!def_string || !profile || profile->magic != PROF_MAGIC_PROFILE) 3996f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o return PROF_MAGIC_PROFILE; 4006f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 4016f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o for (prf = profile->first_file; prf; prf = prf->next) { 4026f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (strcmp(prf->filespec, default_filename) == 0) 4036f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o break; 4046f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 4056f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (!prf) 4066f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o return 0; 4076f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 4086f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (prf->root) { 4096f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o profile_free_node(prf->root); 4106f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o prf->root = 0; 4116f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 4126f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 4136f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o memset(&state, 0, sizeof(struct parse_state)); 4146f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o retval = profile_create_node("(root)", 0, &state.root_section); 4156f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (retval) 4166f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o return retval; 4176f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 4186f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o line = 0; 4196f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o line_size = 0; 4206f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o in = def_string; 4216f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o while (*in) { 4226f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o end = strchr(in, '\n'); 4236f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o len = end ? (end - in) : (int) strlen(in); 4246f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (len >= line_size) { 4256f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o line_size = len+1; 4266f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o p = realloc(line, line_size); 4276f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (!p) { 4286f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o retval = ENOMEM; 4296f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o goto errout; 4306f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 4316f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o line = p; 4326f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 4336f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o memcpy(line, in, len); 4346f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o line[len] = 0; 4356f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o retval = parse_line(line, &state); 4366f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (retval) { 4376f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o errout: 4386f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (syntax_err_cb) 439efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o (syntax_err_cb)(prf->filespec, retval, 4406f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o state.line_num); 4416f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o free(line); 4426f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (prf->root) 4436f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o profile_free_node(prf->root); 4446f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o return retval; 4456f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 4466f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (!end) 4476f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o break; 4486f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o in = end+1; 4496f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 4506f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o prf->root = state.root_section; 4516f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o free(line); 4526f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 4536f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o return 0; 4546f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o} 4552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 4562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 4572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * prof_file.c ---- routines that manipulate an individual profile file. 4582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 4592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 4602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_open_file(const char * filespec, 4612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_file_t *ret_prof) 4622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 4632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_file_t prf; 4642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 4652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *home_env = 0; 4662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o unsigned int len; 4672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *expanded_filename; 4682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 4692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf = malloc(sizeof(struct _prf_file_t)); 4702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!prf) 4712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 4722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o memset(prf, 0, sizeof(struct _prf_file_t)); 4732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf->magic = PROF_MAGIC_FILE; 4742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 4752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o len = strlen(filespec)+1; 4762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (filespec[0] == '~' && filespec[1] == '/') { 4772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o home_env = getenv("HOME"); 4782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_PWD_H 4792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (home_env == NULL) { 48095a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o#ifdef HAVE_GETWUID_R 4812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct passwd *pw, pwx; 48295a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o uid_t uid; 4832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char pwbuf[BUFSIZ]; 4842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 4852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o uid = getuid(); 48695a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (!getpwuid_r(uid, &pwx, pwbuf, sizeof(pwbuf), &pw) 4872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o && pw != NULL && pw->pw_dir[0] != 0) 4882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o home_env = pw->pw_dir; 48995a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o#else 49095a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o struct passwd *pw; 49195a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o 49295a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o pw = getpwuid(getuid()); 49395a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o home_env = pw->pw_dir; 49495a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o#endif 4952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 4962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 4972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (home_env) 4982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o len += strlen(home_env); 4992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 5002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o expanded_filename = malloc(len); 50193503267c9765f80f8bbbdbb132d495a859361e1Brian Behlendorf if (expanded_filename == 0) { 502efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o profile_free_file(prf); 5032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return errno; 50493503267c9765f80f8bbbdbb132d495a859361e1Brian Behlendorf } 5052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (home_env) { 5062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o strcpy(expanded_filename, home_env); 5072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o strcat(expanded_filename, filespec+1); 5082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else 5092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o memcpy(expanded_filename, filespec, len); 5102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 511d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o prf->filespec = expanded_filename; 5122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 5136f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (strcmp(prf->filespec, default_filename) != 0) { 5146f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o retval = profile_update_file(prf); 5156f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (retval) { 5166f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o profile_free_file(prf); 5176f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o return retval; 5186f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 5192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 5202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 5212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_prof = prf; 5222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 5232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 5242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 525d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'oerrcode_t profile_update_file(prf_file_t prf) 5262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 5272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 5282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_STAT 5292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct stat st; 5302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef STAT_ONCE_PER_SECOND 5312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o time_t now; 5322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 5332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 5342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o FILE *f; 535204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o char buf[2048]; 536204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o struct parse_state state; 5372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 5386bde5c28ba25600f02f6d8cd2e8de39017bc421dTheodore Ts'o if (prf->flags & PROFILE_FILE_NO_RELOAD) 5396bde5c28ba25600f02f6d8cd2e8de39017bc421dTheodore Ts'o return 0; 5406bde5c28ba25600f02f6d8cd2e8de39017bc421dTheodore Ts'o 5412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_STAT 5422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef STAT_ONCE_PER_SECOND 5432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o now = time(0); 544d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o if (now == prf->last_stat && prf->root != NULL) { 5452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 5462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 5472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 548d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o if (stat(prf->filespec, &st)) { 5492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = errno; 5502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 5512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 5522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef STAT_ONCE_PER_SECOND 553d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o prf->last_stat = now; 5542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 555d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o if (st.st_mtime == prf->timestamp && prf->root != NULL) { 5562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 5572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 558d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o if (prf->root) { 559d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o profile_free_node(prf->root); 560d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o prf->root = 0; 5612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 5622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#else 5632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 5642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * If we don't have the stat() call, assume that our in-core 5652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * memory image is correct. That is, we won't reread the 5662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * profile file if it changes. 5672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 568d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o if (prf->root) { 5692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 5702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 5712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 572204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o memset(&state, 0, sizeof(struct parse_state)); 573204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o retval = profile_create_node("(root)", 0, &state.root_section); 574204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (retval) 575204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o return retval; 5762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errno = 0; 577d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o f = fopen(prf->filespec, "r"); 5782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (f == NULL) { 5792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = errno; 5802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == 0) 5812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = ENOENT; 5822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 5832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 584d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o prf->upd_serial++; 585204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o while (!feof(f)) { 586204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (fgets(buf, sizeof(buf), f) == NULL) 587204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o break; 588204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o retval = parse_line(buf, &state); 589204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (retval) { 590204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (syntax_err_cb) 591efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o (syntax_err_cb)(prf->filespec, retval, 592204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o state.line_num); 593204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o fclose(f); 594204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o return retval; 595204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o } 5962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 597204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o prf->root = state.root_section; 598204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o 599204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o fclose(f); 600204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o 6012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef HAVE_STAT 602d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o prf->timestamp = st.st_mtime; 6032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 6042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 6052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 6062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 6072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ovoid profile_free_file(prf_file_t prf) 6082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 609d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o if (prf->root) 610d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o profile_free_node(prf->root); 61145e338f5332a54295893dba2e32cc093d1316f60Jim Meyering free(prf->filespec); 6122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o free(prf); 6132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 6142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 615d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o/* Begin the profile parser */ 6162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 617f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'oprofile_syntax_err_cb_t profile_set_syntax_err_cb(profile_syntax_err_cb_t hook) 618f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o{ 619f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o profile_syntax_err_cb_t old; 620f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o 621f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o old = syntax_err_cb; 622f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o syntax_err_cb = hook; 623f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o return(old); 624f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o} 625f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o 626f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o#define STATE_INIT_COMMENT 0 627f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o#define STATE_STD_LINE 1 628f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o#define STATE_GET_OBRACE 2 6292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 6302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic char *skip_over_blanks(char *cp) 6312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 6322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o while (*cp && isspace((int) (*cp))) 6332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp++; 6342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return cp; 6352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 6362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 63795a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'ostatic int end_or_comment(char ch) 63895a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o{ 63995a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o return (ch == 0 || ch == '#' || ch == ';'); 64095a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o} 64195a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o 64295a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'ostatic char *skip_over_nonblanks(char *cp) 64395a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o{ 64495a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o while (!end_or_comment(*cp) && !isspace(*cp)) 64595a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o cp++; 64695a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o return cp; 64795a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o} 64895a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o 6492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void strip_line(char *line) 6502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 6512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *p = line + strlen(line); 6522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o while (p > line && (p[-1] == '\n' || p[-1] == '\r')) 6532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *p-- = 0; 6542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 6552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 6562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void parse_quoted_string(char *str) 6572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 6582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *to, *from; 6592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 6602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o to = from = str; 6612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 6622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (to = from = str; *from && *from != '"'; to++, from++) { 6632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (*from == '\\') { 6642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o from++; 6652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o switch (*from) { 6662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case 'n': 6672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *to = '\n'; 6682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 6692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case 't': 6702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *to = '\t'; 6712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 6722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case 'b': 6732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *to = '\b'; 6742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 6752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o default: 6762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *to = *from; 6772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 6782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 6792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 6802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *to = *from; 6812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 6822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *to = '\0'; 6832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 6842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 685204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'ostatic errcode_t parse_line(char *line, struct parse_state *state) 6862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 6872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *cp, ch, *tag, *value; 6882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *p; 6892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 6902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *node; 6912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int do_subsection = 0; 6922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o void *iter = 0; 693efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 694204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o state->line_num++; 695204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (state->state == STATE_GET_OBRACE) { 696204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o cp = skip_over_blanks(line); 697204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (*cp != '{') 698204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o return PROF_MISSING_OBRACE; 699204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o state->state = STATE_STD_LINE; 700204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o return 0; 701204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o } 702204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (state->state == STATE_INIT_COMMENT) { 703204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o if (line[0] != '[') 704204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o return 0; 705204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o state->state = STATE_STD_LINE; 706204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o } 707204ae371ad2e038b41c03aba13d3a57e4e6921ecTheodore Ts'o 7082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (*line == 0) 7092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 7102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o strip_line(line); 7112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp = skip_over_blanks(line); 7122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o ch = *cp; 71395a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (end_or_comment(ch)) 7142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 7152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ch == '[') { 7162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (state->group_level > 0) 7172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_SECTION_NOTOP; 7182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp++; 71922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o cp = skip_over_blanks(cp); 7202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p = strchr(cp, ']'); 7212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p == NULL) 7222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_SECTION_SYNTAX; 72322fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (*cp == '"') { 72422fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o cp++; 72522fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o parse_quoted_string(cp); 72622fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o } else { 72722fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o *p-- = '\0'; 72822fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o while (isspace(*p) && (p > cp)) 72922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o *p-- = '\0'; 73022fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (*cp == 0) 73122fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o return PROF_SECTION_SYNTAX; 73222fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o } 733efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = profile_find_node(state->root_section, cp, 0, 1, 7349a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o &iter, &state->current_section); 7352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == PROF_NO_SECTION) { 7362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_add_node(state->root_section, 7372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp, 0, 7382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o &state->current_section); 7392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 7402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 7412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else if (retval) 7422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 7432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 7442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 7452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Finish off the rest of the line. 7462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 7472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp = p+1; 7482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (*cp == '*') { 7499a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o state->current_section->final = 1; 7502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp++; 7512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 7522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 753efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * Spaces or comments after ']' should not be fatal 7542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 7552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp = skip_over_blanks(cp); 75695a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (!end_or_comment(*cp)) 7572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_SECTION_SYNTAX; 7582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 7592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 7602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ch == '}') { 7612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (state->group_level == 0) 7622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_EXTRA_CBRACE; 7632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (*(cp+1) == '*') 7649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o state->current_section->final = 1; 7659a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o state->current_section = state->current_section->parent; 7662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o state->group_level--; 7672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 7682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 7692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 7702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Parse the relations 7712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 7722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o tag = cp; 7732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp = strchr(cp, '='); 7742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!cp) 7752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_RELATION_SYNTAX; 7762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (cp == tag) 7772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_RELATION_SYNTAX; 7782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *cp = '\0'; 77922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (*tag == '"') { 78022fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o tag++; 78122fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o parse_quoted_string(tag); 78222fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o } else { 78322fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o /* Look for whitespace on left-hand side. */ 78422fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o p = skip_over_nonblanks(tag); 78522fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (*p) 78622fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o *p++ = 0; 78722fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o p = skip_over_blanks(p); 78822fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o /* If we have more non-whitespace, it's an error. */ 78922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (*p) 79022fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o return PROF_RELATION_SYNTAX; 79122fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o } 79295a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o 7932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cp = skip_over_blanks(cp+1); 7942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o value = cp; 79595a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o ch = value[0]; 79695a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (ch == '"') { 7972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o value++; 7982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o parse_quoted_string(value); 79995a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o } else if (end_or_comment(ch)) { 8002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o do_subsection++; 8012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o state->state = STATE_GET_OBRACE; 80295a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o } else if (value[0] == '{') { 80395a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o cp = skip_over_blanks(value+1); 80495a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o ch = *cp; 80595a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (end_or_comment(ch)) 80695a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o do_subsection++; 80795a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o else 80895a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o return PROF_RELATION_SYNTAX; 80995a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o } else { 81095a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o cp = skip_over_nonblanks(value); 81195a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o p = skip_over_blanks(cp); 81295a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o ch = *p; 81395a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o *cp = 0; 81495a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (!end_or_comment(ch)) 81595a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o return PROF_RELATION_SYNTAX; 8162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 8172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (do_subsection) { 8182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p = strchr(tag, '*'); 8192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p) 8202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *p = '\0'; 8212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_add_node(state->current_section, 8222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o tag, 0, &state->current_section); 8232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 8242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 8252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p) 8269a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o state->current_section->final = 1; 8272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o state->group_level++; 8282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 8292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 8302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p = strchr(tag, '*'); 8312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p) 8322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *p = '\0'; 8332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_add_node(state->current_section, tag, value, &node); 8342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p) 8359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o node->final = 1; 8362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 8372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 8382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 83944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o#ifdef DEBUG_PROGRAM 8402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 8412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Return TRUE if the string begins or ends with whitespace 8422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 8432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic int need_double_quotes(char *str) 8442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 8452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!str || !*str) 8462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 8472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (isspace((int) (*str)) ||isspace((int) (*(str + strlen(str) - 1)))) 8482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 1; 84995a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o if (strchr(str, '\n') || strchr(str, '\t') || strchr(str, '\b') || 85095a8d1de512f7ae55b78d99db21bb0d5973d115eTheodore Ts'o strchr(str, ' ') || strchr(str, '#') || strchr(str, ';')) 8512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 1; 8522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 8532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 8542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 8552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 8562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Output a string with double quotes, doing appropriate backquoting 8572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * of characters as necessary. 8582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 8592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void output_quoted_string(char *str, void (*cb)(const char *,void *), 8602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o void *data) 8612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 8622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char ch; 8632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char buf[2]; 8642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 8652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\"", data); 8662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!str) { 8672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\"", data); 8682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 8692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 8702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o buf[1] = 0; 8712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o while ((ch = *str++)) { 8722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o switch (ch) { 8732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case '\\': 8742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\\\\", data); 8752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 8762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case '\n': 8772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\\n", data); 8782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 8792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case '\t': 8802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\\t", data); 8812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 8822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o case '\b': 8832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\\b", data); 8842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 8852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o default: 8862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* This would be a lot faster if we scanned 8872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o forward for the next "interesting" 8882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o character. */ 8892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o buf[0] = ch; 8902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb(buf, data); 8912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 8922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 8932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 8942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\"", data); 8952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 8962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 8972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifndef EOL 8982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define EOL "\n" 8992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 9002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* Errors should be returned, not ignored! */ 9022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void dump_profile(struct profile_node *root, int level, 9032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o void (*cb)(const char *, void *), void *data) 9042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 9052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int i; 9062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *p; 9072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o void *iter; 9082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o long retval; 909efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 9102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter = 0; 9112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o do { 9129a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o retval = profile_find_node(root, 0, 0, 0, &iter, &p); 9132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 9142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 9152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (i=0; i < level; i++) 9162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\t", data); 91722fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (need_double_quotes(p->name)) 91822fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o output_quoted_string(p->name, cb, data); 91922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o else 9209a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o cb(p->name, data); 92122fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o cb(" = ", data); 92222fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (need_double_quotes(p->value)) 9239a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o output_quoted_string(p->value, cb, data); 92422fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o else 9259a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o cb(p->value, data); 92622fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o cb(EOL, data); 9272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } while (iter != 0); 9282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter = 0; 9302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o do { 9319a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o retval = profile_find_node(root, 0, 0, 1, &iter, &p); 9322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 9332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 9342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (level == 0) { /* [xxx] */ 9352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("[", data); 93622fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (need_double_quotes(p->name)) 93722fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o output_quoted_string(p->name, cb, data); 93822fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o else 93922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o cb(p->name, data); 9402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("]", data); 9419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o cb(p->final ? "*" : "", data); 9422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb(EOL, data); 9432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o dump_profile(p, level+1, cb, data); 9442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb(EOL, data); 9452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else { /* xxx = { ... } */ 9462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (i=0; i < level; i++) 9472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\t", data); 94822fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o if (need_double_quotes(p->name)) 94922fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o output_quoted_string(p->name, cb, data); 95022fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o else 95122fe674da4bdec2ff1c1abb7ad074df3a641377bTheodore Ts'o cb(p->name, data); 9522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb(" = {", data); 9532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb(EOL, data); 9542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o dump_profile(p, level+1, cb, data); 9552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (i=0; i < level; i++) 9562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("\t", data); 9572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb("}", data); 9589a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o cb(p->final ? "*" : "", data); 9592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cb(EOL, data); 9602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 9612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } while (iter != 0); 9622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 9632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void dump_profile_to_file_cb(const char *str, void *data) 9652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 9662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o fputs(str, data); 9672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 9682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_write_tree_file(struct profile_node *root, FILE *dstfile) 9702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 9712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o dump_profile(root, 0, dump_profile_to_file_cb, dstfile); 9722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 9732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 9742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostruct prof_buf { 9762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *base; 9772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o size_t cur, max; 9782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int err; 9792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o}; 9802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void add_data_to_buffer(struct prof_buf *b, const void *d, size_t len) 9822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 9832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (b->err) 9842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 9852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (b->max - b->cur < len) { 9862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o size_t newsize; 9872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *newptr; 9882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 9892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o newsize = b->max + (b->max >> 1) + len + 1024; 9902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o newptr = realloc(b->base, newsize); 9912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (newptr == NULL) { 9922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o b->err = 1; 9932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 9942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 9952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o b->base = newptr; 9962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o b->max = newsize; 9972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 9982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o memcpy(b->base + b->cur, d, len); 9992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o b->cur += len; /* ignore overflow */ 10002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 10012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic void dump_profile_to_buffer_cb(const char *str, void *data) 10032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 10042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o add_data_to_buffer((struct prof_buf *)data, str, strlen(str)); 10052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 10062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_write_tree_to_buffer(struct profile_node *root, 10082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char **buf) 10092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 10102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct prof_buf prof_buf = { 0, 0, 0, 0 }; 10112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o dump_profile(root, 0, dump_profile_to_buffer_cb, &prof_buf); 10132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (prof_buf.err) { 10142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *buf = NULL; 10152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 10162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 10172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o add_data_to_buffer(&prof_buf, "", 1); /* append nul */ 10182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (prof_buf.max - prof_buf.cur > (prof_buf.max >> 3)) { 10192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *newptr = realloc(prof_buf.base, prof_buf.cur); 10202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (newptr) 10212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prof_buf.base = newptr; 10222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 10232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *buf = prof_buf.base; 10242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 10252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 10262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 10272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 10292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * prof_tree.c --- these routines maintain the parse tree of the 10302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * config file. 1031efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 10322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * All of the details of how the tree is stored is abstracted away in 10332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * this file; all of the other profile routines build, access, and 10342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * modify the tree via the accessor functions found in this file. 10352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * 10362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Each node may represent either a relation or a section header. 1037efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 10382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * A section header must have its value field set to 0, and may a one 10392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * or more child nodes, pointed to by first_child. 1040efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 10412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * A relation has as its value a pointer to allocated memory 10422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * containing a string. Its first_child pointer must be null. 10432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * 10442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 10452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 10472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Free a node, and any children 10482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 10492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ovoid profile_free_node(struct profile_node *node) 10502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 10512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *child, *next; 10522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (node->magic != PROF_MAGIC_NODE) 10542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 1055efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 105645e338f5332a54295893dba2e32cc093d1316f60Jim Meyering free(node->name); 105745e338f5332a54295893dba2e32cc093d1316f60Jim Meyering free(node->value); 10582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (child=node->first_child; child; child = next) { 10602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o next = child->next; 10612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_free_node(child); 10622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 10632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o node->magic = 0; 1064efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 10652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o free(node); 10662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 10672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifndef HAVE_STRDUP 10692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#undef strdup 10702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define strdup MYstrdup 10712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic char *MYstrdup (const char *s) 10722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 10732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o size_t sz = strlen(s) + 1; 10742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *p = malloc(sz); 10752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p != 0) 10762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o memcpy(p, s, sz); 10772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return p; 10782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 10792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 10802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 10822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Create a node 10832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 10842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_create_node(const char *name, const char *value, 10852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node **ret_node) 10862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 10872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *new; 10882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 10892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new = malloc(sizeof(struct profile_node)); 10902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!new) 10912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 10922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o memset(new, 0, sizeof(struct profile_node)); 10932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->name = strdup(name); 10942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (new->name == 0) { 10952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_free_node(new); 10962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 10972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 10982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value) { 10992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->value = strdup(value); 11002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (new->value == 0) { 11012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_free_node(new); 11022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 11032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 11042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 11052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->magic = PROF_MAGIC_NODE; 11062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_node = new; 11082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 11092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 11102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 11122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * This function verifies that all of the representation invarients of 11132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * the profile are true. If not, we have a programming bug somewhere, 11142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * probably in this file. 11152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 11162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef DEBUG_PROGRAM 11172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_verify_node(struct profile_node *node) 11182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 11192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *p, *last; 11202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 11212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o CHECK_MAGIC(node); 11232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (node->value && node->first_child) 11252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_SECTION_WITH_VALUE; 11262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o last = 0; 11282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (p = node->first_child; p; last = p, p = p->next) { 11292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->prev != last) 11302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_LINK_LIST; 11312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (last && (last->next != p)) 11322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_LINK_LIST; 11332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (node->group_level+1 != p->group_level) 11342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_GROUP_LVL; 11352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->parent != node) 11362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_PARENT_PTR; 11372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_verify_node(p); 11382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 11392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 11402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 11412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 11422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 11432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 11442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 11462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Add a node to a particular section 11472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 11482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_add_node(struct profile_node *section, const char *name, 11492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *value, struct profile_node **ret_node) 11502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 11512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 11522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *p, *last, *new; 11532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o CHECK_MAGIC(section); 11552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (section->value) 11572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_ADD_NOT_SECTION; 11582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 11602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Find the place to insert the new node. We look for the 1161efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * place *after* the last match of the node name, since 11622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * order matters. 11632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 11642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (p=section->first_child, last = 0; p; last = p, p = p->next) { 11652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int cmp; 11662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cmp = strcmp(p->name, name); 11672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (cmp > 0) 11682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 11692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 11702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_create_node(name, value, &new); 11712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 11722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 11732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->group_level = section->group_level+1; 11742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->deleted = 0; 11752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->parent = section; 11762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->prev = last; 11772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o new->next = p; 11782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p) 11792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p->prev = new; 11802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (last) 11812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o last->next = new; 11822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o else 11832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o section->first_child = new; 11842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_node) 11852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_node = new; 11862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 11872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 11882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 11892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 11902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Iterate through the section, returning the nodes which match 11912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * the given name. If name is NULL, then interate through all the 11922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * nodes in the section. If section_flag is non-zero, only return the 11932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * section which matches the name; don't return relations. If value 11942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * is non-NULL, then only return relations which match the requested 11952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * value. (The value argument is ignored if section_flag is non-zero.) 1196efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * 11972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * The first time this routine is called, the state pointer must be 11982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * null. When this profile_find_node_relation() returns, if the state 11992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * pointer is non-NULL, then this routine should be called again. 12002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * (This won't happen if section_flag is non-zero, obviously.) 12012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * 12022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 12032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_find_node(struct profile_node *section, const char *name, 12042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *value, int section_flag, void **state, 12052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node **node) 12062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 12072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *p; 12082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 12092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o CHECK_MAGIC(section); 12102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p = *state; 12112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p) { 12122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o CHECK_MAGIC(p); 12132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else 12142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p = section->first_child; 1215efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 12162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (; p; p = p->next) { 12172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (name && (strcmp(p->name, name))) 12182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (section_flag) { 12202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->value) 12212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else { 12232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!p->value) 12242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value && (strcmp(p->value, value))) 12262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 12282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->deleted) 12292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* A match! */ 12312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (node) 12322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *node = p; 12332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 12342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 12352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p == 0) { 12362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *state = 0; 12372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return section_flag ? PROF_NO_SECTION : PROF_NO_RELATION; 12382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 12392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 12402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * OK, we've found one match; now let's try to find another 12412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * one. This way, if we return a non-zero state pointer, 12422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * there's guaranteed to be another match that's returned. 12432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 12442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (p = p->next; p; p = p->next) { 12452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (name && (strcmp(p->name, name))) 12462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (section_flag) { 12482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->value) 12492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else { 12512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!p->value) 12522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value && (strcmp(p->value, value))) 12542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 12552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 12562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* A match! */ 12572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 12582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 12592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *state = p; 12602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 12612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 12622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 12632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 12642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * This is a general-purpose iterator for returning all nodes that 1265efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o * match the specified name array. 12662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 12672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostruct profile_iterator { 12682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_magic_t magic; 12692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_t profile; 12702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int flags; 12712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *const *names; 12722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *name; 12732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o prf_file_t file; 12742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int file_serial; 12752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int done_idx; 12762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *node; 12772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int num; 12782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o}; 12792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1280efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 12819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oprofile_iterator_create(profile_t profile, const char *const *names, int flags, 12829a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o void **ret_iter) 12832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 12842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_iterator *iter; 12852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int done_idx = 0; 12862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 12872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (profile == 0) 12882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_NO_PROFILE; 12892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (profile->magic != PROF_MAGIC_PROFILE) 12902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_MAGIC_PROFILE; 12912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!names) 12922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_NAMESET; 12932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!(flags & PROFILE_ITER_LIST_SECTION)) { 12942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!names[0]) 12952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_NAMESET; 12962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o done_idx = 1; 12972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 12982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 12992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((iter = malloc(sizeof(struct profile_iterator))) == NULL) 13002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 13012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 13022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->magic = PROF_MAGIC_ITERATOR; 13032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->profile = profile; 13042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->names = names; 13052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->flags = flags; 13062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->file = profile->first_file; 13072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->done_idx = done_idx; 13082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->node = 0; 13092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->num = 0; 13102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_iter = iter; 13112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 13122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 13132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 13149a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'ovoid profile_iterator_free(void **iter_p) 13152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 13162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_iterator *iter; 13172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 13182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!iter_p) 13192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 13202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter = *iter_p; 13212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!iter || iter->magic != PROF_MAGIC_ITERATOR) 13222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return; 13232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o free(iter); 13242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *iter_p = 0; 13252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 13262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 13272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 13282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Note: the returned character strings in ret_name and ret_value 13292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * points to the stored character string in the parse string. Before 13302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * this string value is returned to a calling application 13312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * (profile_node_iterator is not an exported interface), it should be 13322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * strdup()'ed. 13332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 13342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oerrcode_t profile_node_iterator(void **iter_p, struct profile_node **ret_node, 13352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char **ret_name, char **ret_value) 13362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 13372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_iterator *iter = *iter_p; 13382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o struct profile_node *section, *p; 13392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *const *cpp; 13402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 13412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int skip_num = 0; 13422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 13432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!iter || iter->magic != PROF_MAGIC_ITERATOR) 13442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_MAGIC_ITERATOR; 13452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (iter->file && iter->file->magic != PROF_MAGIC_FILE) 13462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_MAGIC_FILE; 13472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 13482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * If the file has changed, then the node pointer is invalid, 13492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * so we'll have search the file again looking for it. 13502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 1351efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o if (iter->node && (iter->file && 13528f234d9650eb6f6a897148d5136cb27f373de4a7Brian Behlendorf iter->file->upd_serial != iter->file_serial)) { 13532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->flags &= ~PROFILE_ITER_FINAL_SEEN; 13542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o skip_num = iter->num; 13552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->node = 0; 13562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 13572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (iter->node && iter->node->magic != PROF_MAGIC_NODE) { 13582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_MAGIC_NODE; 13592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 13602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oget_new_file: 13612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (iter->node == 0) { 13622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (iter->file == 0 || 13632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o (iter->flags & PROFILE_ITER_FINAL_SEEN)) { 13649a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o profile_iterator_free(iter_p); 13652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_node) 13662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_node = 0; 13672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_name) 13682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_name = 0; 13692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_value) 13702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_value =0; 13712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 13722fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 13732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((retval = profile_update_file(iter->file))) { 13742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == ENOENT || retval == EACCES) { 13752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* XXX memory leak? */ 13762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->file = iter->file->next; 13772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o skip_num = 0; 13782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = 0; 13792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o goto get_new_file; 13802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else { 13819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o profile_iterator_free(iter_p); 13822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 13832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 13842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 1385d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o iter->file_serial = iter->file->upd_serial; 13862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 13872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * Find the section to list if we are a LIST_SECTION, 13882fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * or find the containing section if not. 13892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 1390d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o section = iter->file->root; 13912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (cpp = iter->names; cpp[iter->done_idx]; cpp++) { 13922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (p=section->first_child; p; p = p->next) { 13932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!strcmp(p->name, *cpp) && !p->value) 13942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 13952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 13962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!p) { 13972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o section = 0; 13982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 13992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o section = p; 14012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->final) 14022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->flags |= PROFILE_ITER_FINAL_SEEN; 14032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!section) { 14052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->file = iter->file->next; 14062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o skip_num = 0; 14072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o goto get_new_file; 14082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->name = *cpp; 14102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->node = section->first_child; 14112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* 14132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * OK, now we know iter->node is set up correctly. Let's do 14142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * the search. 14152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 14162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for (p = iter->node; p; p = p->next) { 14172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (iter->name && strcmp(p->name, iter->name)) 14182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 14192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((iter->flags & PROFILE_ITER_SECTIONS_ONLY) && 14202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o p->value) 14212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 14222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((iter->flags & PROFILE_ITER_RELATIONS_ONLY) && 14232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o !p->value) 14242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 14252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (skip_num > 0) { 14262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o skip_num--; 14272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 14282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (p->deleted) 14302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 14312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 14322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->num++; 14342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!p) { 14352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->file = iter->file->next; 14362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->node = 0; 14372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o skip_num = 0; 14382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o goto get_new_file; 14392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 14402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((iter->node = p->next) == NULL) 14412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o iter->file = iter->file->next; 14422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_node) 14432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_node = p; 14442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_name) 14452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_name = p->name; 14462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_value) 14472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_value = p->value; 14482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 14492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 14502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 14512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 14522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 14532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * prof_get.c --- routines that expose the public interfaces for 14542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * querying items from the profile. 14552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * 14562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 14572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 14582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 14592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * This function only gets the first value from the file; it is a 14602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * helper function for profile_get_string, profile_get_integer, etc. 14612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 14629a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'oerrcode_t profile_get_value(profile_t profile, const char *name, 14639a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char *subname, const char *subsubname, 14642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char **ret_value) 14652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 14662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 14672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o void *state; 14682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *value; 14699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char *names[4]; 14702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 14719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o names[0] = name; 14729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o names[1] = subname; 14739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o names[2] = subsubname; 14749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o names[3] = 0; 14759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o 14769a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o if ((retval = profile_iterator_create(profile, names, 14779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o PROFILE_ITER_RELATIONS_ONLY, 14789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o &state))) 14792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 14802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 14812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((retval = profile_node_iterator(&state, 0, 0, &value))) 14822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o goto cleanup; 14832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 14842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value) 14852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_value = value; 14862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o else 14872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = PROF_NO_RELATION; 1488efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 14892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ocleanup: 14909a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o profile_iterator_free(&state); 14912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 14922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 14932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1494efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 14952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_get_string(profile_t profile, const char *name, const char *subname, 14962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *subsubname, const char *def_val, 14972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char **ret_string) 14982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 14992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *value; 15002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 15012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 15022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (profile) { 1503efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = profile_get_value(profile, name, subname, 15049a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o subsubname, &value); 15052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) 15062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o value = def_val; 15072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o else if (retval) 15082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 15092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else 15102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o value = def_val; 1511efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 15122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value) { 15132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_string = malloc(strlen(value)+1); 15142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (*ret_string == 0) 15152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 15162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o strcpy(*ret_string, value); 15172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else 15182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_string = 0; 15192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 15202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 15212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1522efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 15232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_get_integer(profile_t profile, const char *name, const char *subname, 15242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *subsubname, int def_val, int *ret_int) 15252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 15262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *value; 15272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 15282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *end_value; 15292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o long ret_long; 15302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 15312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_int = def_val; 15322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (profile == 0) 15332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 15342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 15359a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o retval = profile_get_value(profile, name, subname, subsubname, &value); 15362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) { 15372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_int = def_val; 15382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 15392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else if (retval) 15402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 15412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 15422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value[0] == 0) 15432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* Empty string is no good. */ 15442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_INTEGER; 15452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errno = 0; 15462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o ret_long = strtol (value, &end_value, 10); 15472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 15482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* Overflow or underflow. */ 15492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((ret_long == LONG_MIN || ret_long == LONG_MAX) && errno != 0) 15502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_INTEGER; 15512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* Value outside "int" range. */ 15522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if ((long) (int) ret_long != ret_long) 15532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_INTEGER; 15542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o /* Garbage in string. */ 15552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (end_value != value + strlen (value)) 15562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_INTEGER; 1557efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 1558efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 15592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_int = ret_long; 15602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 15612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 15622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1563efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 156432460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'oprofile_get_uint(profile_t profile, const char *name, const char *subname, 1565efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o const char *subsubname, unsigned int def_val, 156632460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o unsigned int *ret_int) 156732460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o{ 156832460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o const char *value; 156932460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o errcode_t retval; 157032460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o char *end_value; 157132460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o unsigned long ret_long; 157232460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o 157332460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o *ret_int = def_val; 157432460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o if (profile == 0) 157532460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return 0; 157632460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o 157732460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o retval = profile_get_value(profile, name, subname, subsubname, &value); 157832460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) { 157932460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o *ret_int = def_val; 158032460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return 0; 158132460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o } else if (retval) 158232460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return retval; 158332460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o 158432460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o if (value[0] == 0) 158532460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o /* Empty string is no good. */ 158632460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return PROF_BAD_INTEGER; 158732460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o errno = 0; 158832460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o ret_long = strtoul (value, &end_value, 10); 158932460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o 159032460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o /* Overflow or underflow. */ 159132460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o if ((ret_long == ULONG_MAX) && errno != 0) 159232460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return PROF_BAD_INTEGER; 159332460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o /* Value outside "int" range. */ 159432460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o if ((unsigned long) (unsigned int) ret_long != ret_long) 159532460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return PROF_BAD_INTEGER; 159632460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o /* Garbage in string. */ 159732460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o if (end_value != value + strlen (value)) 159832460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return PROF_BAD_INTEGER; 1599efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 160032460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o *ret_int = ret_long; 160132460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o return 0; 160232460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o} 160332460c1e4c7259b532bdd1e74583c80f573b467aTheodore Ts'o 1604e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallerrcode_t 1605e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrallprofile_get_double(profile_t profile, const char *name, const char *subname, 1606e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *subsubname, double def_val, double *ret_double) 1607e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall{ 1608e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall const char *value; 1609e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errcode_t retval; 1610e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall char *end_value; 1611e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall double double_val; 1612e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 1613e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_double = def_val; 1614e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (profile == 0) 1615e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 1616e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 1617e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall retval = profile_get_value(profile, name, subname, subsubname, &value); 1618e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) { 1619e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_double = def_val; 1620e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 1621e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall } else if (retval) 1622e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return retval; 1623e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 1624e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (value[0] == 0) 1625e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* Empty string is no good. */ 1626e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return PROF_BAD_INTEGER; 1627e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall errno = 0; 1628e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall double_val = strtod(value, &end_value); 1629e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 1630e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* Overflow or underflow. */ 1631e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (errno != 0) 1632e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return PROF_BAD_INTEGER; 1633e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall /* Garbage in string. */ 1634e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall if (end_value != value + strlen(value)) 1635e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return PROF_BAD_INTEGER; 1636e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 1637e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall *ret_double = double_val; 1638e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall return 0; 1639e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall} 1640e0ed7404719a9ddd2ba427a80db5365c8bad18c0JP Abgrall 16412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic const char *const conf_yes[] = { 16422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o "y", "yes", "true", "t", "1", "on", 16432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 0, 16442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o}; 16452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 16462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic const char *const conf_no[] = { 16472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o "n", "no", "false", "nil", "0", "off", 16482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 0, 16492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o}; 16502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 16512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'ostatic errcode_t 16522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_parse_boolean(const char *s, int *ret_boolean) 16532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 16542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *const *p; 1655efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 16562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_boolean == NULL) 16572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_EINVAL; 16582fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 16592fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for(p=conf_yes; *p; p++) { 16602fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!strcasecmp(*p,s)) { 16612fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_boolean = 1; 16622fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 16632fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 16642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 16652fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 16662fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o for(p=conf_no; *p; p++) { 16672fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!strcasecmp(*p,s)) { 16682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_boolean = 0; 16692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 16702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 16712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 1672efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 16732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return PROF_BAD_BOOLEAN; 16742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 16752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1676efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 16772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_get_boolean(profile_t profile, const char *name, const char *subname, 16782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *subsubname, int def_val, int *ret_boolean) 16792fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 16802fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char *value; 16812fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 16822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 16832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (profile == 0) { 16842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_boolean = def_val; 16852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 16862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 16872fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 16889a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o retval = profile_get_value(profile, name, subname, subsubname, &value); 16892fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval == PROF_NO_SECTION || retval == PROF_NO_RELATION) { 16902fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_boolean = def_val; 16912fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 16922fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else if (retval) 16932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 1694efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 16952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return profile_parse_boolean (value, ret_boolean); 16962fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 16972fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1698efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'oerrcode_t 16992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oprofile_iterator(void **iter_p, char **ret_name, char **ret_value) 17002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 17012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *name, *value; 17022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 1703efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 17042fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_node_iterator(iter_p, 0, &name, &value); 17052fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) 17062fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return retval; 17072fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 17082fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_name) { 17092fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (name) { 17102fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_name = malloc(strlen(name)+1); 17112fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!*ret_name) 17122fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 17132fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o strcpy(*ret_name, name); 17142fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else 17152fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_name = 0; 17162fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 17172fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_value) { 17182fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (value) { 17192fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_value = malloc(strlen(value)+1); 17202fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!*ret_value) { 17212fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret_name) { 17222fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o free(*ret_name); 17232fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_name = 0; 17242fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 17252fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return ENOMEM; 17262fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 17272fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o strcpy(*ret_value, value); 17282fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } else 17292fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o *ret_value = 0; 17302fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 17312fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 17322fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 17332fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 17342fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#ifdef DEBUG_PROGRAM 17352fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 17362fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o/* 17372fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o * test_profile.c --- testing program for the profile routine 17382fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o */ 17392fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 17402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#include "argv_parse.h" 17419a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o#include "profile_helpers.h" 17422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 17432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'oconst char *program_name = "test_profile"; 17442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 17452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PRINT_VALUE 1 17462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#define PRINT_VALUES 2 17472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 174844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'ostatic void do_cmd(profile_t profile, char **argv) 17492fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 17502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o errcode_t retval; 17512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o const char **names, *value; 175244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o char **values, **cpp; 175344dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o char *cmd; 17542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o int print_status; 17552fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 175644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o cmd = *(argv); 175744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o names = (const char **) argv + 1; 175844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o print_status = 0; 175944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = 0; 176044dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o if (cmd == 0) 176144dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o return; 176244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o if (!strcmp(cmd, "query")) { 176344dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_get_values(profile, names, &values); 176444dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o print_status = PRINT_VALUES; 176544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "query1")) { 17669a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char *name = 0; 17679a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char *subname = 0; 17689a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o const char *subsubname = 0; 17699a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o 17709a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o name = names[0]; 17719a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o if (name) 17729a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o subname = names[1]; 17739a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o if (subname) 17749a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o subsubname = names[2]; 17759a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o if (subsubname && names[3]) { 1776efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o fprintf(stderr, 17779a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o "Only 3 levels are allowed with query1\n"); 17789a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o retval = EINVAL; 17799a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o } else 1780efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = profile_get_value(profile, name, subname, 17819a4c209cd26a7eae3d1de427d9b028f69e1c2554Theodore Ts'o subsubname, &value); 178244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o print_status = PRINT_VALUE; 178344dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "list_sections")) { 1784efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = profile_get_subsection_names(profile, names, 178544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o &values); 178644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o print_status = PRINT_VALUES; 178744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "list_relations")) { 1788efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o retval = profile_get_relation_names(profile, names, 178944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o &values); 179044dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o print_status = PRINT_VALUES; 179144dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "dump")) { 179244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_write_tree_file 1793d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o (profile->first_file->root, stdout); 179444dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o#if 0 179544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "clear")) { 179644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_clear_relation(profile, names); 179744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "update")) { 179844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_update_relation(profile, names+2, 179944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o *names, *(names+1)); 180044dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o#endif 180144dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "verify")) { 180244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_verify_node 1803d45544ca5419e218537f8b9689bbb028abbf8f28Theodore Ts'o (profile->first_file->root); 180444dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o#if 0 180544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "rename_section")) { 180644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_rename_section(profile, names+1, *names); 180744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "add")) { 180844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o value = *names; 180944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o if (strcmp(value, "NULL") == 0) 181044dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o value = NULL; 181144dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_add_relation(profile, names+1, value); 181244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else if (!strcmp(cmd, "flush")) { 181344dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o retval = profile_flush(profile); 181444dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o#endif 181544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } else { 181644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o printf("Invalid command.\n"); 181744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } 181844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o if (retval) { 181944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o com_err(cmd, retval, ""); 182044dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o print_status = 0; 182144dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } 182244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o switch (print_status) { 182344dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o case PRINT_VALUE: 182444dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o printf("%s\n", value); 182544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o break; 182644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o case PRINT_VALUES: 182744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o for (cpp = values; *cpp; cpp++) 182844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o printf("%s\n", *cpp); 182944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o profile_free_list(values); 183044dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o break; 183144dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o } 183244dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o} 183344dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o 183444dc5f8804b2480764f792315d84977ec9569163Theodore Ts'ostatic void do_batchmode(profile_t profile) 183544dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o{ 183644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o int argc, ret; 183744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o char **argv; 183844dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o char buf[256]; 183944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o 18402fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o while (!feof(stdin)) { 18412fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (fgets(buf, sizeof(buf), stdin) == NULL) 18422fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o break; 18432fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o printf(">%s", buf); 18442fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o ret = argv_parse(buf, &argc, &argv); 18452fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (ret != 0) { 18462fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o printf("Argv_parse returned %d!\n", ret); 18472fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o continue; 18482fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 184944dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o do_cmd(profile, argv); 18502fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o printf("\n"); 18512fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o argv_free(argv); 18522fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 18532fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_release(profile); 18542fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o exit(0); 1855efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 18562fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 18572fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 1858f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'ovoid syntax_err_report(const char *filename, long err, int line_num) 1859f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o{ 1860f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o fprintf(stderr, "Syntax error in %s, line number %d: %s\n", 1861f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o filename, line_num, error_message(err)); 1862f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o exit(1); 1863f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o} 18642fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 18656f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'oconst char *default_str = "[foo]\n\tbar=quux\n\tsub = {\n\t\twin = true\n}\n"; 18666f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 186744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'oint main(int argc, char **argv) 18682fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o{ 18692fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_t profile; 18702fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o long retval; 18712fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o char *cmd; 1872efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 18732fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (argc < 2) { 18742fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o fprintf(stderr, "Usage: %s filename [cmd argset]\n", program_name); 18752fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o exit(1); 18762fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 18772fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 18782fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o initialize_prof_error_table(); 1879f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o 1880f5f14fcfe9eba0282a3dfe5600364bbf797dcfc3Theodore Ts'o profile_set_syntax_err_cb(syntax_err_report); 1881efc6f628e15de95bcd13e4f0ee223cb42115d520Theodore Ts'o 18822fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o retval = profile_init_path(argv[1], &profile); 18832fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (retval) { 18842fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o com_err(program_name, retval, "while initializing profile"); 18852fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o exit(1); 18862fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o } 18876f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o retval = profile_set_default(profile, default_str); 18886f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o if (retval) { 18896f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o com_err(program_name, retval, "while setting default"); 18906f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o exit(1); 18916f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o } 18926f890e516d1eddb52a566d1f77888c9edf5772f2Theodore Ts'o 18932fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o cmd = *(argv+2); 18942fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o if (!cmd || !strcmp(cmd, "batch")) 18952fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o do_batchmode(profile); 189644dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o else 189744dc5f8804b2480764f792315d84977ec9569163Theodore Ts'o do_cmd(profile, argv+2); 18982fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o profile_release(profile); 18992fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 19002fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o return 0; 19012fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o} 19022fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o 19032fa9ba98337b07d6acfac52b5ee5dc8116dda866Theodore Ts'o#endif 1904