source: trunk/test/lib-regfio.c @ 33

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

Fixed some bugs.

rewrote testing code to allow for a path filter expression.

  • Property svn:keywords set to Id
File size: 6.2 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: lib-regfio.c 33 2005-07-17 19:03:02Z 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_stack* path2Stack(const char* s)
32{
33  void_stack* ret_val = void_stack_new(1024);
34  char* cur = strdup(s);
35  char* next = NULL;
36 
37  while((next = strrchr(cur, '/')) != NULL)
38  {
39    next[0] = '\0';
40    if(strlen(next+1) > 0)
41      void_stack_push(ret_val, next+1);
42  }
43  if(strlen(cur) > 0)
44    void_stack_push(ret_val, cur);
45
46  return ret_val;
47}
48
49
50char* stack2Path(void_stack* nk_stack)
51{
52  const REGF_NK_REC* cur;
53  unsigned int buf_left = 127;
54  unsigned int buf_len = buf_left+1;
55  unsigned int name_len = 0;
56  unsigned int grow_amt;
57  char* buf; 
58  char* new_buf;
59  void_stack_iterator* iter;
60 
61  buf = (char*)malloc((buf_len)*sizeof(char));
62  if (buf == NULL)
63    return NULL;
64  buf[0] = '\0';
65
66  iter = void_stack_iterator_new(nk_stack);
67  if (iter == NULL)
68  {
69    free(buf);
70    return NULL;
71  }
72
73  /* skip root element */
74  cur = void_stack_iterator_next(iter);
75
76  while((cur = void_stack_iterator_next(iter)) != NULL)
77  {
78    buf[buf_len-buf_left-1] = '/';
79    buf_left -= 1;
80    name_len = strlen(cur->keyname);
81    if(name_len+1 > buf_left)
82    {
83      grow_amt = (unsigned int)(buf_len/2);
84      buf_len += name_len+1+grow_amt-buf_left;
85      if((new_buf = realloc(buf, buf_len)) == NULL)
86      {
87        free(buf);
88        free(iter);
89        return NULL;
90      }
91      buf = new_buf;
92      buf_left = grow_amt + name_len + 1;
93    }
94    strncpy(buf+(buf_len-buf_left-1), cur->keyname, name_len);
95    buf_left -= name_len;
96    buf[buf_len-buf_left-1] = '\0';
97  }
98
99  return buf;
100}
101
102
103void printValue(REGF_VK_REC* vk, char* prefix)
104{
105  const char* str_type;
106 
107  str_type = type_val2str(vk->type);
108  printf("%s/%s:%s=\n", prefix, vk->valuename, str_type);
109}
110
111
112void printValueList(REGF_NK_REC* nk, char* prefix)
113{
114  unsigned int i;
115 
116  for(i=0; i < nk->num_values; i++)
117    printValue(&nk->values[i], prefix);
118}
119
120/* XXX: this function is god-awful.  Needs to be re-designed. */
121void printKeyTree(REGF_FILE* f, void_stack* nk_stack, char* prefix)
122{
123  REGF_NK_REC* cur;
124  REGF_NK_REC* sub;
125  char* path;
126  char* val_path;
127
128  if((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
129  {
130    cur->subkey_index = 0;
131    path = stack2Path(nk_stack);
132   
133    if(strlen(path) > 0)
134      printf("%s%s:KEY\n", prefix, path);
135    printValueList(cur, path);
136    while((cur = (REGF_NK_REC*)void_stack_cur(nk_stack)) != NULL)
137    {
138      if((sub = regfio_fetch_subkey(f, cur)) != NULL)
139      {
140        sub->subkey_index = 0;
141        void_stack_push(nk_stack, sub);
142        path = stack2Path(nk_stack);
143        if(path != NULL)
144        {
145          val_path = (char*)malloc(strlen(prefix)+strlen(path)+1);
146          sprintf(val_path, "%s%s", prefix, path);
147          printf("%s:KEY\n", val_path);
148          printValueList(sub, val_path);
149          free(val_path);
150          free(path);
151        }
152      }
153      else
154      {
155        cur = void_stack_pop(nk_stack);
156        /* XXX: This is just a shallow free.  Need to write deep free
157         * routines to replace the Samba code for this.
158         */ 
159        /*      if(cur != NULL)
160          free(cur);*/
161      }
162    }
163  }
164}
165
166
167/*
168 * Returns 0 if path was found.
169 * Returns 1 if path was not found.
170 * Returns less than 0 on other error.
171 */
172int retrievePath(REGF_FILE* f, void_stack* nk_stack,
173                 void_stack* path_stack)
174{
175  REGF_NK_REC* sub; 
176  REGF_NK_REC* cur;
177  void_stack* sub_nk_stack;
178  char* prefix;
179  char* cur_str = NULL;
180  bool found_cur = true;
181  unsigned int i;
182  unsigned short path_depth;
183  if(path_stack == NULL)
184    return -1;
185
186  path_depth = void_stack_size(path_stack);
187  if(path_depth < 1)
188    return -2;
189
190  if(void_stack_size(nk_stack) < 1)
191    return -3;
192  cur = (REGF_NK_REC*)void_stack_cur(nk_stack);
193
194  while(void_stack_size(path_stack) > 1)
195  {
196    /* Search key records only */
197    cur_str = (char*)void_stack_pop(path_stack);
198
199    found_cur = false;
200    while(!found_cur &&
201          (sub = regfio_fetch_subkey(f, cur)) != NULL)
202    {
203      if(strcasecmp(sub->keyname, cur_str) == 0)
204      {
205        cur = sub;
206        void_stack_push(nk_stack, sub);
207        found_cur = true;
208      }
209    }
210
211    if(!found_cur)
212      return 0;
213  }
214
215  /* Last round, search value and key records */
216  cur_str = (char*)void_stack_pop(path_stack);
217
218  for(i=0; (i < cur->num_values); i++)
219  {
220    if(strcasecmp(sub->values[i].valuename, cur_str) == 0)
221    {
222      printValue(&sub->values[i], stack2Path(nk_stack));
223      return 0;
224    }
225  }
226
227  while((sub = regfio_fetch_subkey(f, cur)) != NULL)
228  {
229    if(strcasecmp(sub->keyname, cur_str) == 0)
230    {
231      sub_nk_stack = void_stack_new(1024);
232      void_stack_push(sub_nk_stack, sub);
233      void_stack_push(nk_stack, sub);
234      prefix = stack2Path(nk_stack);
235      printKeyTree(f, sub_nk_stack, prefix);
236      return 0;
237    }
238  }
239
240  return 1;
241}
242
243
244int main(int argc, char** argv)
245{
246  void_stack* nk_stack;
247  void_stack* path_stack;
248  REGF_FILE* f;
249  REGF_NK_REC* root;
250  int retr_path_ret;
251  char* path = "/ControlSet002/Services/Eventlog/";
252
253  if(argc < 2)
254  {
255    printf("ERROR: Requires 1 argument.\n");
256    return 1;
257  }
258
259  f = regfio_open( argv[1] );
260  root = regfio_rootkey(f);
261
262  nk_stack = void_stack_new(1024);
263  if(void_stack_push(nk_stack, root))
264  {
265    path_stack = path2Stack(path);
266    if(void_stack_size(path_stack) < 1)
267      printKeyTree(f, nk_stack, "");
268    else
269    {
270      retr_path_ret = retrievePath(f, nk_stack, 
271                                   path_stack);
272      if(retr_path_ret == 1)
273        printf("WARNING: specified path not found.\n");
274      else if(retr_path_ret != 0)
275        printf("ERROR\n");
276    }
277  }
278  void_stack_destroy(nk_stack);
279
280  regfio_close(f);
281
282  return 0;
283}
Note: See TracBrowser for help on using the repository browser.