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
RevLine 
[30]1/*
[31]2 * A utility to test functionality of Gerald Carter''s regfio interface.
[30]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>
[33]26#include <strings.h>
[30]27#include "../include/regfio.h"
[31]28#include "../include/void_stack.h"
[30]29
[38]30
[40]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
[38]41void bailOut(int code, char* message)
42{
43  fprintf(stderr, message);
44  exit(code);
45}
46
47
[33]48void_stack* path2Stack(const char* s)
[30]49{
[38]50  void_stack* ret_val;
51  void_stack* rev_ret = void_stack_new(1024);
52  const char* cur = s;
[33]53  char* next = NULL;
[38]54  char* copy;
55
56  if (rev_ret == NULL)
57    return NULL;
[37]58  if (s == NULL)
[38]59    return rev_ret;
60 
61  while((next = strchr(cur, '/')) != NULL)
[33]62  {
[38]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;
[33]74  }
75  if(strlen(cur) > 0)
[38]76  {
77    copy = strdup(cur);
78    void_stack_push(rev_ret, copy);
79  }
[33]80
[38]81  ret_val = void_stack_copy_reverse(rev_ret);
82  void_stack_destroy(rev_ret);
83
[33]84  return ret_val;
85}
86
87
88char* stack2Path(void_stack* nk_stack)
89{
90  const REGF_NK_REC* cur;
[37]91  uint32 buf_left = 127;
92  uint32 buf_len = buf_left+1;
93  uint32 name_len = 0;
94  uint32 grow_amt;
[31]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';
[30]103
[31]104  iter = void_stack_iterator_new(nk_stack);
105  if (iter == NULL)
[30]106  {
[31]107    free(buf);
108    return NULL;
[30]109  }
110
[33]111  /* skip root element */
112  cur = void_stack_iterator_next(iter);
113
[31]114  while((cur = void_stack_iterator_next(iter)) != NULL)
115  {
[33]116    buf[buf_len-buf_left-1] = '/';
117    buf_left -= 1;
[31]118    name_len = strlen(cur->keyname);
119    if(name_len+1 > buf_left)
120    {
[37]121      grow_amt = (uint32)(buf_len/2);
[31]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  }
[30]136
[31]137  return buf;
138}
[30]139
[31]140
[33]141void printValue(REGF_VK_REC* vk, char* prefix)
[31]142{
[40]143  if(!type_filter_enabled || (vk->type == type_filter))
144    printf("%s/%s:%s=\n", prefix, vk->valuename, type_val2str(vk->type));
[32]145}
146
147
[33]148void printValueList(REGF_NK_REC* nk, char* prefix)
[32]149{
[37]150  uint32 i;
[33]151 
152  for(i=0; i < nk->num_values; i++)
153    printValue(&nk->values[i], prefix);
154}
155
[37]156
[33]157/* XXX: this function is god-awful.  Needs to be re-designed. */
158void printKeyTree(REGF_FILE* f, void_stack* nk_stack, char* prefix)
159{
[31]160  REGF_NK_REC* cur;
161  REGF_NK_REC* sub;
162  char* path;
[33]163  char* val_path;
[40]164  int key_type = type_str2val("KEY");
[31]165
[32]166  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
[31]167  {
[33]168    cur->subkey_index = 0;
169    path = stack2Path(nk_stack);
170   
171    if(strlen(path) > 0)
[40]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);
[32]176    while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
[31]177    {
[32]178      if((sub = regfio_fetch_subkey(f, cur)) != NULL)
[31]179      {
[33]180        sub->subkey_index = 0;
[32]181        void_stack_push(nk_stack, sub);
[33]182        path = stack2Path(nk_stack);
[32]183        if(path != NULL)
184        {
[33]185          val_path = (char*)malloc(strlen(prefix)+strlen(path)+1);
186          sprintf(val_path, "%s%s", prefix, path);
[40]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);
[33]191          free(val_path);
[32]192          free(path);
193        }
[31]194      }
[32]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         */ 
[39]201        if(cur != NULL)
202          free(cur);
[32]203      }
[31]204    }
205  }
[30]206}
207
208
[33]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;
[37]223  uint32 i;
224  uint16 path_depth;
[33]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    }
[39]252    free(cur_str);
[33]253
254    if(!found_cur)
[37]255      return 1;
[33]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
[37]287static void usage(void)
288{
[39]289  fprintf(stderr, "Usage: readreg [-v] [-s]"
[40]290          " [-p <PATH_FILTER>] [-t <TYPE_FILTER>]"
[39]291          " <REGISTRY_FILE>\n");
[37]292  /* XXX: replace version string with Subversion property? */
293  fprintf(stderr, "Version: 0.2\n");
[39]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");
[40]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");
[37]299  fprintf(stderr, "\n");
300}
301
302
[30]303int main(int argc, char** argv)
304{
[31]305  void_stack* nk_stack;
[33]306  void_stack* path_stack;
[31]307  REGF_FILE* f;
308  REGF_NK_REC* root;
[33]309  int retr_path_ret;
[37]310  uint32 argi;
[31]311
[37]312  /* Process command line arguments */
[30]313  if(argc < 2)
314  {
[37]315    usage();
[38]316    bailOut(1, "ERROR: Requires 1 argument.\n");
[30]317  }
[37]318 
319  for(argi = 1; argi < argc; argi++)
320  {
[40]321    if (strcmp("-p", argv[argi]) == 0)
[37]322    {
323      if(++argi > argc)
324      {
325        usage();
[40]326        bailOut(1, "ERROR: '-p' option requires parameter.\n");
[37]327      }
[40]328      if((path_filter = strdup(argv[argi])) == NULL)
[38]329        bailOut(2, "ERROR: Memory allocation problem.\n");
330
[40]331      path_filter_enabled = true;
[37]332    }
333    else if (strcmp("-t", argv[argi]) == 0)
334    {
335      if(++argi > argc)
336      {
337        usage();
[38]338        bailOut(1, "ERROR: '-t' option requires parameter.\n");
[37]339      }
[40]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      }
[38]345
[37]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    {
[38]354      usage();
[37]355      fprintf(stderr, "ERROR: Unrecognized option: %s\n", argv[argi]);
[38]356      bailOut(1, "");
[37]357    }
358    else
359    {
360      if((registry_file = strdup(argv[argi])) == NULL)
[38]361        bailOut(2, "ERROR: Memory allocation problem.\n");
[37]362    }
363  }
[30]364
[37]365  f = regfio_open(registry_file);
366  if(f == NULL)
367  {
368    fprintf(stderr, "ERROR: Couldn't open registry file: %s\n", registry_file);
[38]369    bailOut(3, "");
[37]370  }
[38]371
[31]372  root = regfio_rootkey(f);
[37]373  nk_stack = void_stack_new(1024);
[30]374
[31]375  if(void_stack_push(nk_stack, root))
[33]376  {
[40]377    path_stack = path2Stack(path_filter);
[33]378    if(void_stack_size(path_stack) < 1)
379      printKeyTree(f, nk_stack, "");
380    else
381    {
[37]382      retr_path_ret = retrievePath(f, nk_stack, path_stack);
[33]383      if(retr_path_ret == 1)
[37]384        fprintf(stderr, "WARNING: specified path not found.\n");
[33]385      else if(retr_path_ret != 0)
[38]386        bailOut(4, "ERROR:\n");
[33]387    }
388  }
[37]389  else
[38]390    bailOut(2, "ERROR: Memory allocation problem.\n");
[31]391
[38]392  void_stack_destroy_deep(nk_stack);
[30]393  regfio_close(f);
394
395  return 0;
396}
Note: See TracBrowser for help on using the repository browser.