source: trunk/src/reglookup.c @ 37

Last change on this file since 37 was 37, checked in by tim, 19 years ago

Added basic command line argument parsing. Only prefix_filter option works right now.

  • Property svn:keywords set to Id
File size: 8.5 KB
Line 
1/*
2 * A utility to test functionality of Gerald Carter''s regfio interface.
3 *
4 * Copyright (C) 2005 Timothy D. Morgan
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
18 *
19 * $Id: reglookup.c 37 2005-07-31 03:25:40Z tim $
20 */
21
22
23#include <stdlib.h>
24#include <stdio.h>
25#include <string.h>
26#include <strings.h>
27#include "../include/regfio.h"
28#include "../include/void_stack.h"
29
30/* XXX: this needs to be rewritten to malloc each resulting string, instead of
31 *      altering them in place
32 */
33void_stack* path2Stack(const char* s)
34{
35  void_stack* ret_val = void_stack_new(1024);
36  char* next = NULL;
37  char* cur;
38  if (s == NULL)
39    return ret_val;
40  else
41    cur = strdup(s);
42
43  while((next = strrchr(cur, '/')) != NULL)
44  {
45    next[0] = '\0';
46    if(strlen(next+1) > 0)
47      void_stack_push(ret_val, next+1);
48  }
49  if(strlen(cur) > 0)
50    void_stack_push(ret_val, cur);
51
52  return ret_val;
53}
54
55
56char* stack2Path(void_stack* nk_stack)
57{
58  const REGF_NK_REC* cur;
59  uint32 buf_left = 127;
60  uint32 buf_len = buf_left+1;
61  uint32 name_len = 0;
62  uint32 grow_amt;
63  char* buf; 
64  char* new_buf;
65  void_stack_iterator* iter;
66 
67  buf = (char*)malloc((buf_len)*sizeof(char));
68  if (buf == NULL)
69    return NULL;
70  buf[0] = '\0';
71
72  iter = void_stack_iterator_new(nk_stack);
73  if (iter == NULL)
74  {
75    free(buf);
76    return NULL;
77  }
78
79  /* skip root element */
80  cur = void_stack_iterator_next(iter);
81
82  while((cur = void_stack_iterator_next(iter)) != NULL)
83  {
84    buf[buf_len-buf_left-1] = '/';
85    buf_left -= 1;
86    name_len = strlen(cur->keyname);
87    if(name_len+1 > buf_left)
88    {
89      grow_amt = (uint32)(buf_len/2);
90      buf_len += name_len+1+grow_amt-buf_left;
91      if((new_buf = realloc(buf, buf_len)) == NULL)
92      {
93        free(buf);
94        free(iter);
95        return NULL;
96      }
97      buf = new_buf;
98      buf_left = grow_amt + name_len + 1;
99    }
100    strncpy(buf+(buf_len-buf_left-1), cur->keyname, name_len);
101    buf_left -= name_len;
102    buf[buf_len-buf_left-1] = '\0';
103  }
104
105  return buf;
106}
107
108
109void printValue(REGF_VK_REC* vk, char* prefix)
110{
111  const char* str_type;
112 
113  str_type = type_val2str(vk->type);
114  printf("%s/%s:%s=\n", prefix, vk->valuename, str_type);
115}
116
117
118void printValueList(REGF_NK_REC* nk, char* prefix)
119{
120  uint32 i;
121 
122  for(i=0; i < nk->num_values; i++)
123    printValue(&nk->values[i], prefix);
124}
125
126
127/* XXX: this function is god-awful.  Needs to be re-designed. */
128void printKeyTree(REGF_FILE* f, void_stack* nk_stack, char* prefix)
129{
130  REGF_NK_REC* cur;
131  REGF_NK_REC* sub;
132  char* path;
133  char* val_path;
134
135  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
136  {
137    cur->subkey_index = 0;
138    path = stack2Path(nk_stack);
139   
140    if(strlen(path) > 0)
141      printf("%s%s:KEY\n", prefix, path);
142    printValueList(cur, path);
143    while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
144    {
145      if((sub = regfio_fetch_subkey(f, cur)) != NULL)
146      {
147        sub->subkey_index = 0;
148        void_stack_push(nk_stack, sub);
149        path = stack2Path(nk_stack);
150        if(path != NULL)
151        {
152          val_path = (char*)malloc(strlen(prefix)+strlen(path)+1);
153          sprintf(val_path, "%s%s", prefix, path);
154          printf("%s:KEY\n", val_path);
155          printValueList(sub, val_path);
156          free(val_path);
157          free(path);
158        }
159      }
160      else
161      {
162        cur = void_stack_pop(nk_stack);
163        /* XXX: This is just a shallow free.  Need to write deep free
164         * routines to replace the Samba code for this.
165         */ 
166        /*      if(cur != NULL)
167          free(cur);*/
168      }
169    }
170  }
171}
172
173
174/*
175 * Returns 0 if path was found.
176 * Returns 1 if path was not found.
177 * Returns less than 0 on other error.
178 */
179int retrievePath(REGF_FILE* f, void_stack* nk_stack,
180                 void_stack* path_stack)
181{
182  REGF_NK_REC* sub; 
183  REGF_NK_REC* cur;
184  void_stack* sub_nk_stack;
185  char* prefix;
186  char* cur_str = NULL;
187  bool found_cur = true;
188  uint32 i;
189  uint16 path_depth;
190  if(path_stack == NULL)
191    return -1;
192
193  path_depth = void_stack_size(path_stack);
194  if(path_depth < 1)
195    return -2;
196
197  if(void_stack_size(nk_stack) < 1)
198    return -3;
199  cur = (REGF_NK_REC*)void_stack_cur(nk_stack);
200
201  while(void_stack_size(path_stack) > 1)
202  {
203    /* Search key records only */
204    cur_str = (char*)void_stack_pop(path_stack);
205
206    found_cur = false;
207    while(!found_cur &&
208          (sub = regfio_fetch_subkey(f, cur)) != NULL)
209    {
210      if(strcasecmp(sub->keyname, cur_str) == 0)
211      {
212        cur = sub;
213        void_stack_push(nk_stack, sub);
214        found_cur = true;
215      }
216    }
217
218    if(!found_cur)
219      return 1;
220  }
221
222  /* Last round, search value and key records */
223  cur_str = (char*)void_stack_pop(path_stack);
224
225  for(i=0; (i < cur->num_values); i++)
226  {
227    if(strcasecmp(sub->values[i].valuename, cur_str) == 0)
228    {
229      printValue(&sub->values[i], stack2Path(nk_stack));
230      return 0;
231    }
232  }
233
234  while((sub = regfio_fetch_subkey(f, cur)) != NULL)
235  {
236    if(strcasecmp(sub->keyname, cur_str) == 0)
237    {
238      sub_nk_stack = void_stack_new(1024);
239      void_stack_push(sub_nk_stack, sub);
240      void_stack_push(nk_stack, sub);
241      prefix = stack2Path(nk_stack);
242      printKeyTree(f, sub_nk_stack, prefix);
243      return 0;
244    }
245  }
246
247  return 1;
248}
249
250
251static void usage(void)
252{
253  fprintf(stderr, "Usage: readreg [-f <PREFIX_FILTER>] [-t <TYPE_FILTER>] "
254                  "[-v] [-s] <REGISTRY_FILE>\n");
255  /* XXX: replace version string with Subversion property? */
256  fprintf(stderr, "Version: 0.2\n");
257  fprintf(stderr, "\n\t-v\t sets verbose mode.");
258  fprintf(stderr, "\n\t-f\t a simple prefix filter.");
259  fprintf(stderr, "\n\t-t\t restrict results to a specific type.");
260  fprintf(stderr, "\n\t-s\t prints security descriptors.");
261  fprintf(stderr, "\n");
262}
263
264/* Globals, influenced by command line parameters */
265bool print_verbose = false;
266bool print_security = false;
267bool prefix_filter_enabled = false;
268bool type_filter_enabled = false;
269char* prefix_filter = NULL;
270char* type_filter = NULL;
271char* registry_file = NULL;
272
273
274int main(int argc, char** argv)
275{
276  void_stack* nk_stack;
277  void_stack* path_stack;
278  REGF_FILE* f;
279  REGF_NK_REC* root;
280  int retr_path_ret;
281  uint32 argi;
282
283  /* Process command line arguments */
284  if(argc < 2)
285  {
286    printf("ERROR: Requires 1 argument.\n");
287    usage();
288    exit(1);
289  }
290 
291  for(argi = 1; argi < argc; argi++)
292  {
293    if (strcmp("-f", argv[argi]) == 0)
294    {
295      if(++argi > argc)
296      {
297        fprintf(stderr, "ERROR: '-f' option requires parameter.\n");
298        usage();
299        exit(1);
300      }
301      if((prefix_filter = strdup(argv[argi])) == NULL)
302      {
303        fprintf(stderr, "ERROR: Memory allocation problem.\n");
304        exit(2);
305      }
306      prefix_filter_enabled = true;
307    }
308    else if (strcmp("-t", argv[argi]) == 0)
309    {
310      if(++argi > argc)
311      {
312        fprintf(stderr, "ERROR: '-t' option requires parameter.\n");
313        usage();
314        exit(1);
315      }
316      if((prefix_filter = strdup(argv[argi])) == NULL)
317      {
318        fprintf(stderr, "ERROR: Memory allocation problem.\n");
319        exit(2);
320      }
321      type_filter_enabled = true;
322    }
323    else if (strcmp("-s", argv[argi]) == 0)
324      print_security = true;
325    else if (strcmp("-v", argv[argi]) == 0)
326      print_verbose = true;
327    else if (argv[argi][0] == '-')
328    {
329      fprintf(stderr, "ERROR: Unrecognized option: %s\n", argv[argi]);
330      usage();
331      exit(1);
332    }
333    else
334    {
335      if((registry_file = strdup(argv[argi])) == NULL)
336      {
337        fprintf(stderr, "ERROR: Memory allocation problem.\n");
338        exit(2);
339      }     
340    }
341  }
342
343  f = regfio_open(registry_file);
344  if(f == NULL)
345  {
346    fprintf(stderr, "ERROR: Couldn't open registry file: %s\n", registry_file);
347    exit(1);
348  }
349  root = regfio_rootkey(f);
350  nk_stack = void_stack_new(1024);
351
352  if(void_stack_push(nk_stack, root))
353  {
354    path_stack = path2Stack(prefix_filter);
355    if(void_stack_size(path_stack) < 1)
356      printKeyTree(f, nk_stack, "");
357    else
358    {
359      retr_path_ret = retrievePath(f, nk_stack, path_stack);
360      if(retr_path_ret == 1)
361        fprintf(stderr, "WARNING: specified path not found.\n");
362      else if(retr_path_ret != 0)
363        fprintf(stderr, "ERROR:\n");
364    }
365  }
366  else
367  {
368    fprintf(stderr, "ERROR: Memory allocation problem.\n");
369    exit(2);
370  }
371  void_stack_destroy(nk_stack);
372
373  regfio_close(f);
374
375  return 0;
376}
Note: See TracBrowser for help on using the repository browser.