Changeset 61 for trunk/src


Ignore:
Timestamp:
07/17/06 21:56:59 (18 years ago)
Author:
tim
Message:

various minor speedups and memory leak fixes. Added support for NONE and LINK types.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/reglookup.c

    r59 r61  
    33 * Gerald Carter''s regfio interface.
    44 *
    5  * Copyright (C) 2005 Timothy D. Morgan
     5 * Copyright (C) 2005-2006 Timothy D. Morgan
    66 * Copyright (C) 2002 Richard Sharpe, rsharpe@richardsharpe.com
    77 *
     
    2828#include <strings.h>
    2929#include <time.h>
     30#include <iconv.h>
    3031#include "../include/regfio.h"
    3132#include "../include/void_stack.h"
     
    4344/* Other globals */
    4445const char* special_chars = ",\"\\";
     46iconv_t conv_desc;
     47
    4548
    4649void bailOut(int code, char* message)
     
    5457 * except for non-printable or special characters are quoted in hex
    5558 * with the syntax '\xQQ' where QQ is the hex ascii value of the quoted
    56  * character.  A null terminator is added, as only ascii, not binary,
     59 * character.  A null terminator is added, since only ascii, not binary,
    5760 * is returned.
    5861 */
     
    6063                          unsigned int len, const char* special)
    6164{
    62   unsigned int i;
    63   unsigned int num_written=0;
    64   unsigned int out_len = sizeof(char)*len+1;
    65   char* ret_val = malloc(out_len);
     65  unsigned int i, added_len;
     66  unsigned int num_written = 0;
     67
     68  unsigned int buf_len = sizeof(char)*(len+1);
     69  char* ret_val = malloc(buf_len);
     70  char* tmp_buf;
    6671
    6772  if(ret_val == NULL)
     
    7075  for(i=0; i<len; i++)
    7176  {
     77    if(buf_len <= (num_written+5))
     78    {
     79      /* Expand the buffer by the memory consumption rate seen so far
     80       * times the amount of input left to process.  The expansion is bounded
     81       * below by a minimum safety increase, and above by the maximum possible
     82       * output string length.
     83       */
     84      added_len = (len-i)*num_written/(i+1);
     85      if((buf_len+added_len) > (len*4+1))
     86        buf_len = len*4+1;
     87      else
     88      {
     89        if (added_len < 5)
     90          buf_len += 5;
     91        else
     92          buf_len += added_len;
     93      }
     94
     95      tmp_buf = realloc(ret_val, buf_len);
     96      if(tmp_buf == NULL)
     97      {
     98        free(ret_val);
     99        return NULL;
     100      }
     101      ret_val = tmp_buf;
     102    }
     103   
    72104    if(str[i] < 32 || str[i] > 126 || strchr(special, str[i]) != NULL)
    73105    {
    74       out_len += 3;
    75       /* XXX: may not be the most efficient way of getting enough memory. */
    76       ret_val = realloc(ret_val, out_len);
    77       if(ret_val == NULL)
    78         break;
    79       num_written += snprintf(ret_val+num_written, (out_len)-num_written,
     106      num_written += snprintf(ret_val + num_written, buf_len - num_written,
    80107                              "\\x%.2X", str[i]);
    81108    }
     
    107134
    108135/*
    109  * Convert from UniCode to Ascii ... Does not take into account other lang
    110  * Restrict by ascii_max if > 0
     136 * Convert from Unicode to ASCII.
    111137 */
    112 static int uni_to_ascii(unsigned char *uni, unsigned char *ascii,
    113                         int ascii_max, int uni_max)
    114 {
    115   int i = 0;
    116 
    117   while (i < ascii_max && (uni[i*2] || uni[i*2+1]))
    118   {
    119     if (uni_max > 0 && (i*2) >= uni_max) break;
    120     ascii[i] = uni[i*2];
    121     i++;
    122   }
    123   ascii[i] = '\0';
    124 
    125   return i;
     138static int uni_to_ascii(unsigned char* uni, char* ascii,
     139                        unsigned int uni_max, unsigned int ascii_max)
     140{
     141  char* inbuf = (char*)uni;
     142  char* outbuf = ascii;
     143  int ret;
     144
     145  /* Set up conversion descriptor. */
     146  conv_desc = iconv_open("US-ASCII", "UTF-16LE");
     147
     148  ret = iconv(conv_desc, &inbuf, &uni_max, &outbuf, &ascii_max);
     149  if(ret == -1)
     150  {
     151    iconv_close(conv_desc);
     152    return -1;
     153  }
     154
     155  iconv_close(conv_desc); 
     156  return strlen(ascii);
    126157}
    127158
     
    130161 * Convert a data value to a string for display
    131162 */
    132 static unsigned char* data_to_ascii(unsigned char *datap, int len, int type)
    133 {
    134   unsigned char *asciip;
     163static char* data_to_ascii(unsigned char *datap, int len, int type)
     164{
     165  char* asciip;
    135166  unsigned int i;
    136167  unsigned short num_nulls;
    137   unsigned char* ascii;
     168  char* ascii;
    138169  unsigned char* cur_str;
    139   unsigned char* cur_ascii;
     170  char* cur_ascii;
    140171  char* cur_quoted;
    141172  unsigned int cur_str_len;
     
    145176  switch (type)
    146177  {
     178    /* REG_LINK is a symbolic link, stored as a unicode string. */
     179  case REG_LINK:
    147180  case REG_SZ:
    148181    ascii_max = sizeof(char)*len;
     
    151184      return NULL;
    152185   
    153     /* XXX: This has to be fixed. It has to be UNICODE */
    154     uni_to_ascii(datap, ascii, len, ascii_max);
    155     cur_quoted = quote_string((char*)ascii, special_chars);
     186    if(uni_to_ascii(datap, ascii, len, ascii_max) < 0)
     187    {
     188      free(ascii);
     189      return NULL;
     190    }
     191    cur_quoted = quote_string(ascii, special_chars);
    156192    free(ascii);
    157     return (unsigned char*)cur_quoted;
     193    return cur_quoted;
    158194    break;
    159195
     196    /* XXX: This could be Unicode or ASCII.  Are we processing it
     197     *      correctly in both cases?
     198     */
    160199  case REG_EXPAND_SZ:
    161200    ascii_max = sizeof(char)*len;
     
    164203      return NULL;
    165204
    166     uni_to_ascii(datap, ascii, len, ascii_max);
    167     cur_quoted = quote_string((char*)ascii, special_chars);
     205    if(uni_to_ascii(datap, ascii, len, ascii_max) < 0)
     206    {
     207      free(ascii);
     208      return NULL;
     209    }
     210    cur_quoted = quote_string(ascii, special_chars);
    168211    free(ascii);
    169     return (unsigned char*)cur_quoted;
     212    return cur_quoted;
    170213    break;
    171214
     
    176219      return NULL;
    177220
    178     snprintf((char*)ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
     221    snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
    179222             datap[0], datap[1], datap[2], datap[3]);
    180223    return ascii;
     
    187230      return NULL;
    188231
    189     snprintf((char*)ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
     232    snprintf(ascii, ascii_max, "0x%.2X%.2X%.2X%.2X",
    190233             datap[3], datap[2], datap[1], datap[0]);
    191234    return ascii;
     
    226269      if(num_nulls == 2)
    227270      {
    228         uni_to_ascii(cur_str, cur_ascii, cur_str_max, 0);
    229         cur_quoted = quote_string((char*)cur_ascii, ",|\"\\");
    230         alen = snprintf((char*)asciip, str_rem, "%s", cur_quoted);
     271        if(uni_to_ascii(cur_str, cur_ascii, cur_str_max, cur_str_max) < 0)
     272        {
     273          free(ascii);
     274          free(cur_ascii);
     275          free(cur_str);
     276          return NULL;
     277        }
     278
     279        cur_quoted = quote_string(cur_ascii, ",|\"\\");
     280        alen = snprintf(asciip, str_rem, "%s", cur_quoted);
    231281        asciip += alen;
    232282        str_rem -= alen;
     
    237287        else
    238288        {
    239           alen = snprintf((char*)asciip, str_rem, "%c", '|');
    240           asciip += alen;
    241           str_rem -= alen;
     289          if(str_rem > 0)
     290          {
     291            asciip[0] = '|';
     292            asciip[1] = '\0';
     293            asciip++;
     294            str_rem--;
     295          }
    242296          memset(cur_str, 0, cur_str_max);
    243297          cur_str_len = 0;
     
    255309
    256310  /* XXX: Dont know what to do with these yet, just print as binary... */
     311  case REG_NONE:
    257312  case REG_RESOURCE_LIST:
    258313  case REG_FULL_RESOURCE_DESCRIPTOR:
     
    260315
    261316  case REG_BINARY:
    262     return (unsigned char*)quote_buffer(datap, len, special_chars);
     317    return quote_buffer(datap, len, special_chars);
    263318    break;
    264319
     
    369424  uint32 size;
    370425  uint8 tmp_buf[4];
    371   unsigned char* quoted_value;
     426  char* quoted_value;
    372427  char* quoted_prefix;
    373428  char* quoted_name;
     
    397452      size = 16384;
    398453    }
     454
    399455    quoted_value = data_to_ascii(vk->data, vk->data_size, vk->type);
    400456  }
     
    443499  time_t tmp_time[1];
    444500  struct tm* tmp_time_s = NULL;
    445 
     501  char* quoted_path = NULL;
     502
     503  /* XXX: it would be faster to always pass a quoted string to this
     504   *      function, instead of re-quoting it every call. */
     505  /* XXX: check return of quote_string */
     506  quoted_path = quote_string(full_path, special_chars);
    446507  *tmp_time = nt_time_to_unix(&k->mtime);
    447508  tmp_time_s = gmtime(tmp_time);
     
    463524      dacl = empty_str;
    464525
    465     printf("%s,KEY,,%s,%s,%s,%s,%s\n", full_path, mtime,
     526    printf("%s,KEY,,%s,%s,%s,%s,%s\n", quoted_path, mtime,
    466527           owner, group, sacl, dacl);
    467528
     
    476537  }
    477538  else
    478     printf("%s,KEY,,%s\n", full_path, mtime);
     539    printf("%s,KEY,,%s\n", quoted_path, mtime);
     540
     541  free(quoted_path);
    479542}
    480543
     
    673736static void usage(void)
    674737{
    675   fprintf(stderr, "Usage: readreg [-v] [-s]"
     738  fprintf(stderr, "Usage: reglookup [-v] [-s]"
    676739          " [-p <PATH_FILTER>] [-t <TYPE_FILTER>]"
    677740          " <REGISTRY_FILE>\n");
    678741  /* XXX: replace version string with Subversion property? */
    679   fprintf(stderr, "Version: 0.2.2\n");
     742  fprintf(stderr, "Version: 0.3.0\n");
    680743  fprintf(stderr, "Options:\n");
    681744  fprintf(stderr, "\t-v\t sets verbose mode.\n");
     
    728791        bailOut(1, "ERROR: '-t' option requires parameter.\n");
    729792      }
    730       if((type_filter = regfio_type_str2val(argv[argi])) == 0)
     793      if((type_filter = regfio_type_str2val(argv[argi])) < 0)
    731794      {
    732795        fprintf(stderr, "ERROR: Invalid type specified: %s.\n", argv[argi]);
    733796        bailOut(1, "");
    734797      }
    735 
    736798      type_filter_enabled = true;
    737799    }
Note: See TracChangeset for help on using the changeset viewer.