source: trunk/src/reglookup.c @ 40

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

Added type filtering to new reglookup.

Changed -f option to -p, since that letter makes more sense now.

  • Property svn:keywords set to Id
File size: 9.0 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 40 2005-07-31 16:52:57Z 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
31/* Globals, influenced by command line parameters */
32bool print_verbose = false;
33bool print_security = false;
34bool path_filter_enabled = false;
35bool type_filter_enabled = false;
36char* path_filter = NULL;
37int type_filter;
38char* registry_file = NULL;
39
40
41void bailOut(int code, char* message)
42{
43  fprintf(stderr, message);
44  exit(code);
45}
46
47
48void_stack* path2Stack(const char* s)
49{
50  void_stack* ret_val;
51  void_stack* rev_ret = void_stack_new(1024);
52  const char* cur = s;
53  char* next = NULL;
54  char* copy;
55
56  if (rev_ret == NULL)
57    return NULL;
58  if (s == NULL)
59    return rev_ret;
60 
61  while((next = strchr(cur, '/')) != NULL)
62  {
63    if ((next-cur) > 0)
64    {
65      copy = (char*)malloc((next-cur+1)*sizeof(char));
66      if(copy == NULL)
67        bailOut(2, "ERROR: Memory allocation problem.\n");
68         
69      memcpy(copy, cur, next-cur);
70      copy[next-cur] = '\0';
71      void_stack_push(rev_ret, copy);
72    }
73    cur = next+1;
74  }
75  if(strlen(cur) > 0)
76  {
77    copy = strdup(cur);
78    void_stack_push(rev_ret, copy);
79  }
80
81  ret_val = void_stack_copy_reverse(rev_ret);
82  void_stack_destroy(rev_ret);
83
84  return ret_val;
85}
86
87
88char* stack2Path(void_stack* nk_stack)
89{
90  const REGF_NK_REC* cur;
91  uint32 buf_left = 127;
92  uint32 buf_len = buf_left+1;
93  uint32 name_len = 0;
94  uint32 grow_amt;
95  char* buf; 
96  char* new_buf;
97  void_stack_iterator* iter;
98 
99  buf = (char*)malloc((buf_len)*sizeof(char));
100  if (buf == NULL)
101    return NULL;
102  buf[0] = '\0';
103
104  iter = void_stack_iterator_new(nk_stack);
105  if (iter == NULL)
106  {
107    free(buf);
108    return NULL;
109  }
110
111  /* skip root element */
112  cur = void_stack_iterator_next(iter);
113
114  while((cur = void_stack_iterator_next(iter)) != NULL)
115  {
116    buf[buf_len-buf_left-1] = '/';
117    buf_left -= 1;
118    name_len = strlen(cur->keyname);
119    if(name_len+1 > buf_left)
120    {
121      grow_amt = (uint32)(buf_len/2);
122      buf_len += name_len+1+grow_amt-buf_left;
123      if((new_buf = realloc(buf, buf_len)) == NULL)
124      {
125        free(buf);
126        free(iter);
127        return NULL;
128      }
129      buf = new_buf;
130      buf_left = grow_amt + name_len + 1;
131    }
132    strncpy(buf+(buf_len-buf_left-1), cur->keyname, name_len);
133    buf_left -= name_len;
134    buf[buf_len-buf_left-1] = '\0';
135  }
136
137  return buf;
138}
139
140
141void printValue(REGF_VK_REC* vk, char* prefix)
142{
143  if(!type_filter_enabled || (vk->type == type_filter))
144    printf("%s/%s:%s=\n", prefix, vk->valuename, type_val2str(vk->type));
145}
146
147
148void printValueList(REGF_NK_REC* nk, char* prefix)
149{
150  uint32 i;
151 
152  for(i=0; i < nk->num_values; i++)
153    printValue(&nk->values[i], prefix);
154}
155
156
157/* XXX: this function is god-awful.  Needs to be re-designed. */
158void printKeyTree(REGF_FILE* f, void_stack* nk_stack, char* prefix)
159{
160  REGF_NK_REC* cur;
161  REGF_NK_REC* sub;
162  char* path;
163  char* val_path;
164  int key_type = type_str2val("KEY");
165
166  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
167  {
168    cur->subkey_index = 0;
169    path = stack2Path(nk_stack);
170   
171    if(strlen(path) > 0)
172      if(!type_filter_enabled || (key_type == type_filter))
173        printf("%s%s:KEY\n", prefix, path);
174    if(!type_filter_enabled || (key_type != type_filter))
175      printValueList(cur, path);
176    while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
177    {
178      if((sub = regfio_fetch_subkey(f, cur)) != NULL)
179      {
180        sub->subkey_index = 0;
181        void_stack_push(nk_stack, sub);
182        path = stack2Path(nk_stack);
183        if(path != NULL)
184        {
185          val_path = (char*)malloc(strlen(prefix)+strlen(path)+1);
186          sprintf(val_path, "%s%s", prefix, path);
187          if(!type_filter_enabled || (key_type == type_filter))
188            printf("%s:KEY\n", val_path);
189          if(!type_filter_enabled || (key_type != type_filter))
190            printValueList(sub, val_path);
191          free(val_path);
192          free(path);
193        }
194      }
195      else
196      {
197        cur = void_stack_pop(nk_stack);
198        /* XXX: This is just a shallow free.  Need to write deep free
199         * routines to replace the Samba code for this.
200         */ 
201        if(cur != NULL)
202          free(cur);
203      }
204    }
205  }
206}
207
208
209/*
210 * Returns 0 if path was found.
211 * Returns 1 if path was not found.
212 * Returns less than 0 on other error.
213 */
214int retrievePath(REGF_FILE* f, void_stack* nk_stack,
215                 void_stack* path_stack)
216{
217  REGF_NK_REC* sub; 
218  REGF_NK_REC* cur;
219  void_stack* sub_nk_stack;
220  char* prefix;
221  char* cur_str = NULL;
222  bool found_cur = true;
223  uint32 i;
224  uint16 path_depth;
225  if(path_stack == NULL)
226    return -1;
227
228  path_depth = void_stack_size(path_stack);
229  if(path_depth < 1)
230    return -2;
231
232  if(void_stack_size(nk_stack) < 1)
233    return -3;
234  cur = (REGF_NK_REC*)void_stack_cur(nk_stack);
235
236  while(void_stack_size(path_stack) > 1)
237  {
238    /* Search key records only */
239    cur_str = (char*)void_stack_pop(path_stack);
240
241    found_cur = false;
242    while(!found_cur &&
243          (sub = regfio_fetch_subkey(f, cur)) != NULL)
244    {
245      if(strcasecmp(sub->keyname, cur_str) == 0)
246      {
247        cur = sub;
248        void_stack_push(nk_stack, sub);
249        found_cur = true;
250      }
251    }
252    free(cur_str);
253
254    if(!found_cur)
255      return 1;
256  }
257
258  /* Last round, search value and key records */
259  cur_str = (char*)void_stack_pop(path_stack);
260
261  for(i=0; (i < cur->num_values); i++)
262  {
263    if(strcasecmp(sub->values[i].valuename, cur_str) == 0)
264    {
265      printValue(&sub->values[i], stack2Path(nk_stack));
266      return 0;
267    }
268  }
269
270  while((sub = regfio_fetch_subkey(f, cur)) != NULL)
271  {
272    if(strcasecmp(sub->keyname, cur_str) == 0)
273    {
274      sub_nk_stack = void_stack_new(1024);
275      void_stack_push(sub_nk_stack, sub);
276      void_stack_push(nk_stack, sub);
277      prefix = stack2Path(nk_stack);
278      printKeyTree(f, sub_nk_stack, prefix);
279      return 0;
280    }
281  }
282
283  return 1;
284}
285
286
287static void usage(void)
288{
289  fprintf(stderr, "Usage: readreg [-v] [-s]"
290          " [-p <PATH_FILTER>] [-t <TYPE_FILTER>]"
291          " <REGISTRY_FILE>\n");
292  /* XXX: replace version string with Subversion property? */
293  fprintf(stderr, "Version: 0.2\n");
294  fprintf(stderr, "Options:\n");
295  fprintf(stderr, "\t-v\t sets verbose mode.\n");
296  fprintf(stderr, "\t-s\t prints security descriptors.\n");
297  fprintf(stderr, "\t-p\t restrict output to elements below this path.\n");
298  fprintf(stderr, "\t-t\t restrict results to this specific data type.\n");
299  fprintf(stderr, "\n");
300}
301
302
303int main(int argc, char** argv)
304{
305  void_stack* nk_stack;
306  void_stack* path_stack;
307  REGF_FILE* f;
308  REGF_NK_REC* root;
309  int retr_path_ret;
310  uint32 argi;
311
312  /* Process command line arguments */
313  if(argc < 2)
314  {
315    usage();
316    bailOut(1, "ERROR: Requires 1 argument.\n");
317  }
318 
319  for(argi = 1; argi < argc; argi++)
320  {
321    if (strcmp("-p", argv[argi]) == 0)
322    {
323      if(++argi > argc)
324      {
325        usage();
326        bailOut(1, "ERROR: '-p' option requires parameter.\n");
327      }
328      if((path_filter = strdup(argv[argi])) == NULL)
329        bailOut(2, "ERROR: Memory allocation problem.\n");
330
331      path_filter_enabled = true;
332    }
333    else if (strcmp("-t", argv[argi]) == 0)
334    {
335      if(++argi > argc)
336      {
337        usage();
338        bailOut(1, "ERROR: '-t' option requires parameter.\n");
339      }
340      if((type_filter = type_str2val(argv[argi])) == 0)
341      {
342        fprintf(stderr, "ERROR: Invalid type specified: %s.\n", argv[argi]);
343        bailOut(1, "");
344      }
345
346      type_filter_enabled = true;
347    }
348    else if (strcmp("-s", argv[argi]) == 0)
349      print_security = true;
350    else if (strcmp("-v", argv[argi]) == 0)
351      print_verbose = true;
352    else if (argv[argi][0] == '-')
353    {
354      usage();
355      fprintf(stderr, "ERROR: Unrecognized option: %s\n", argv[argi]);
356      bailOut(1, "");
357    }
358    else
359    {
360      if((registry_file = strdup(argv[argi])) == NULL)
361        bailOut(2, "ERROR: Memory allocation problem.\n");
362    }
363  }
364
365  f = regfio_open(registry_file);
366  if(f == NULL)
367  {
368    fprintf(stderr, "ERROR: Couldn't open registry file: %s\n", registry_file);
369    bailOut(3, "");
370  }
371
372  root = regfio_rootkey(f);
373  nk_stack = void_stack_new(1024);
374
375  if(void_stack_push(nk_stack, root))
376  {
377    path_stack = path2Stack(path_filter);
378    if(void_stack_size(path_stack) < 1)
379      printKeyTree(f, nk_stack, "");
380    else
381    {
382      retr_path_ret = retrievePath(f, nk_stack, path_stack);
383      if(retr_path_ret == 1)
384        fprintf(stderr, "WARNING: specified path not found.\n");
385      else if(retr_path_ret != 0)
386        bailOut(4, "ERROR:\n");
387    }
388  }
389  else
390    bailOut(2, "ERROR: Memory allocation problem.\n");
391
392  void_stack_destroy_deep(nk_stack);
393  regfio_close(f);
394
395  return 0;
396}
Note: See TracBrowser for help on using the repository browser.