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
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 39 2005-07-31 15:15:03Z 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
31void bailOut(int code, char* message)
32{
33  fprintf(stderr, message);
34  exit(code);
35}
36
37
[33]38void_stack* path2Stack(const char* s)
[30]39{
[38]40  void_stack* ret_val;
41  void_stack* rev_ret = void_stack_new(1024);
42  const char* cur = s;
[33]43  char* next = NULL;
[38]44  char* copy;
45
46  if (rev_ret == NULL)
47    return NULL;
[37]48  if (s == NULL)
[38]49    return rev_ret;
50 
51  while((next = strchr(cur, '/')) != NULL)
[33]52  {
[38]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;
[33]64  }
65  if(strlen(cur) > 0)
[38]66  {
67    copy = strdup(cur);
68    void_stack_push(rev_ret, copy);
69  }
[33]70
[38]71  ret_val = void_stack_copy_reverse(rev_ret);
72  void_stack_destroy(rev_ret);
73
[33]74  return ret_val;
75}
76
77
78char* stack2Path(void_stack* nk_stack)
79{
80  const REGF_NK_REC* cur;
[37]81  uint32 buf_left = 127;
82  uint32 buf_len = buf_left+1;
83  uint32 name_len = 0;
84  uint32 grow_amt;
[31]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';
[30]93
[31]94  iter = void_stack_iterator_new(nk_stack);
95  if (iter == NULL)
[30]96  {
[31]97    free(buf);
98    return NULL;
[30]99  }
100
[33]101  /* skip root element */
102  cur = void_stack_iterator_next(iter);
103
[31]104  while((cur = void_stack_iterator_next(iter)) != NULL)
105  {
[33]106    buf[buf_len-buf_left-1] = '/';
107    buf_left -= 1;
[31]108    name_len = strlen(cur->keyname);
109    if(name_len+1 > buf_left)
110    {
[37]111      grow_amt = (uint32)(buf_len/2);
[31]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  }
[30]126
[31]127  return buf;
128}
[30]129
[31]130
[33]131void printValue(REGF_VK_REC* vk, char* prefix)
[31]132{
[32]133  const char* str_type;
134 
[33]135  str_type = type_val2str(vk->type);
136  printf("%s/%s:%s=\n", prefix, vk->valuename, str_type);
[32]137}
138
139
[33]140void printValueList(REGF_NK_REC* nk, char* prefix)
[32]141{
[37]142  uint32 i;
[33]143 
144  for(i=0; i < nk->num_values; i++)
145    printValue(&nk->values[i], prefix);
146}
147
[37]148
[33]149/* XXX: this function is god-awful.  Needs to be re-designed. */
150void printKeyTree(REGF_FILE* f, void_stack* nk_stack, char* prefix)
151{
[31]152  REGF_NK_REC* cur;
153  REGF_NK_REC* sub;
154  char* path;
[33]155  char* val_path;
[31]156
[32]157  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
[31]158  {
[33]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);
[32]165    while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
[31]166    {
[32]167      if((sub = regfio_fetch_subkey(f, cur)) != NULL)
[31]168      {
[33]169        sub->subkey_index = 0;
[32]170        void_stack_push(nk_stack, sub);
[33]171        path = stack2Path(nk_stack);
[32]172        if(path != NULL)
173        {
[33]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);
[32]179          free(path);
180        }
[31]181      }
[32]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         */ 
[39]188        if(cur != NULL)
189          free(cur);
[32]190      }
[31]191    }
192  }
[30]193}
194
195
[33]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;
[37]210  uint32 i;
211  uint16 path_depth;
[33]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    }
[39]239    free(cur_str);
[33]240
241    if(!found_cur)
[37]242      return 1;
[33]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
[37]274static void usage(void)
275{
[39]276  fprintf(stderr, "Usage: readreg [-v] [-s]"
277          " [-f <PREFIX_FILTER>] [-t <TYPE_FILTER>]"
278          " <REGISTRY_FILE>\n");
[37]279  /* XXX: replace version string with Subversion property? */
280  fprintf(stderr, "Version: 0.2\n");
[39]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");
[37]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
[30]299int main(int argc, char** argv)
300{
[31]301  void_stack* nk_stack;
[33]302  void_stack* path_stack;
[31]303  REGF_FILE* f;
304  REGF_NK_REC* root;
[33]305  int retr_path_ret;
[37]306  uint32 argi;
[31]307
[37]308  /* Process command line arguments */
[30]309  if(argc < 2)
310  {
[37]311    usage();
[38]312    bailOut(1, "ERROR: Requires 1 argument.\n");
[30]313  }
[37]314 
315  for(argi = 1; argi < argc; argi++)
316  {
317    if (strcmp("-f", argv[argi]) == 0)
318    {
319      if(++argi > argc)
320      {
321        usage();
[38]322        bailOut(1, "ERROR: '-f' option requires parameter.\n");
[37]323      }
324      if((prefix_filter = strdup(argv[argi])) == NULL)
[38]325        bailOut(2, "ERROR: Memory allocation problem.\n");
326
[37]327      prefix_filter_enabled = true;
328    }
329    else if (strcmp("-t", argv[argi]) == 0)
330    {
331      if(++argi > argc)
332      {
333        usage();
[38]334        bailOut(1, "ERROR: '-t' option requires parameter.\n");
[37]335      }
336      if((prefix_filter = strdup(argv[argi])) == NULL)
[38]337        bailOut(2, "ERROR: Memory allocation problem.\n");
338
[37]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    {
[38]347      usage();
[37]348      fprintf(stderr, "ERROR: Unrecognized option: %s\n", argv[argi]);
[38]349      bailOut(1, "");
[37]350    }
351    else
352    {
353      if((registry_file = strdup(argv[argi])) == NULL)
[38]354        bailOut(2, "ERROR: Memory allocation problem.\n");
[37]355    }
356  }
[30]357
[37]358  f = regfio_open(registry_file);
359  if(f == NULL)
360  {
361    fprintf(stderr, "ERROR: Couldn't open registry file: %s\n", registry_file);
[38]362    bailOut(3, "");
[37]363  }
[38]364
[31]365  root = regfio_rootkey(f);
[37]366  nk_stack = void_stack_new(1024);
[30]367
[31]368  if(void_stack_push(nk_stack, root))
[33]369  {
[37]370    path_stack = path2Stack(prefix_filter);
[33]371    if(void_stack_size(path_stack) < 1)
372      printKeyTree(f, nk_stack, "");
373    else
374    {
[37]375      retr_path_ret = retrievePath(f, nk_stack, path_stack);
[33]376      if(retr_path_ret == 1)
[37]377        fprintf(stderr, "WARNING: specified path not found.\n");
[33]378      else if(retr_path_ret != 0)
[38]379        bailOut(4, "ERROR:\n");
[33]380    }
381  }
[37]382  else
[38]383    bailOut(2, "ERROR: Memory allocation problem.\n");
[31]384
[38]385  void_stack_destroy_deep(nk_stack);
[30]386  regfio_close(f);
387
388  return 0;
389}
Note: See TracBrowser for help on using the repository browser.