source: trunk/src/reglookup.c @ 39

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

small cleanups, added some free() calls.

fixed top-level Makefile to clean properly.

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