1 /* Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
2 
3    This program is free software; you can redistribute it and/or modify
4    it under the terms of the GNU General Public License, version 2.0,
5    as published by the Free Software Foundation.
6 
7    This program is also distributed with certain software (including
8    but not limited to OpenSSL) that is licensed under separate terms,
9    as designated in a particular file or component or in included license
10    documentation.  The authors of MySQL hereby grant you an additional
11    permission to link the program and your derivative works with the
12    separately licensed software that they have included with MySQL.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License, version 2.0, for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; if not, write to the Free Software
21    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
22 
23 #include <ndb_global.h>
24 #include <ndb_opts.h>
25 
26 #include <NdbOut.hpp>
27 #include <NdbApi.hpp>
28 #include <NDBT.hpp>
29 
30 static struct my_option
31 my_long_options[] =
32 {
33   { "help", '?',
34     "Display this help and exit.",
35     0, 0, 0,
36     GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
37   { 0, 0,
38     0,
39     0, 0, 0,
40     GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
41 };
42 
43 const char*
44 load_default_groups[]= { 0 };
45 
46 static void
short_usage_sub(void)47 short_usage_sub(void)
48 {
49   ndb_short_usage_sub("*.frm ...");
50 }
51 
52 static void
usage()53 usage()
54 {
55   printf("%s: pack and dump *.frm as C arrays\n", my_progname);
56   ndb_usage(short_usage_sub, load_default_groups, my_long_options);
57 }
58 
59 static void
dodump(const char * name,const uchar * frm_data,uint frm_len)60 dodump(const char* name, const uchar* frm_data, uint frm_len)
61 {
62   printf("const uint g_%s_frm_len = %u;\n\n", name, frm_len);
63   printf("const uint8 g_%s_frm_data[%u] =\n{\n", name, frm_len);
64   uint n = 0;
65   while (n < frm_len) {
66     if (n % 8 == 0) {
67       if (n != 0) {
68         printf("\n");
69       }
70       printf("  ");
71     }
72     printf("0x%02x", frm_data[n]);
73     if (n + 1 < frm_len) {
74             printf(",");
75     }
76     n++;
77   }
78   if (n % 8 != 0) {
79     printf("\n");
80   }
81   printf("};\n");
82 }
83 
84 static int
dofile(const char * file)85 dofile(const char* file)
86 {
87   struct stat st;
88   size_t size = 0;
89   uchar* data = 0;
90   int fd = -1;
91   uchar* pack_data = 0;
92   size_t pack_len = 0;
93   char* namebuf = 0;
94   int ret = -1;
95   do
96   {
97     if (stat(file, &st) == -1)
98     {
99       fprintf(stderr, "%s: stat: %s\n", file, strerror(errno));
100       break;
101     }
102     size = st.st_size;
103     if ((data = (uchar*)malloc(size)) == 0)
104     {
105       fprintf(stderr, "%s: malloc %u: %s\n", file, (uint)size, strerror(errno));
106       break;
107     }
108     if ((fd = open(file, O_RDONLY)) == -1)
109     {
110       fprintf(stderr, "%s: open: %s\n", file, strerror(errno));
111       break;
112     }
113     ssize_t size2;
114     if ((size2 = read(fd, data, size)) == -1)
115     {
116       fprintf(stderr, "%s: read: %s\n", file, strerror(errno));
117       break;
118     }
119     if ((size_t)size2 != size)
120     {
121       fprintf(stderr, "%s: short read: %u != %u\n", file, (uint)size2, (uint)size);
122       break;
123     }
124     int error;
125     if ((error = packfrm(data, size, &pack_data, &pack_len)) != 0)
126     {
127       fprintf(stderr, "%s: packfrm: error %d\n", file, error);
128       break;
129     }
130     namebuf = strdup(file);
131     if (namebuf == 0)
132     {
133       fprintf(stderr, "%s: strdup: %s\n", file, strerror(errno));
134       break;
135     }
136     char* name = namebuf;
137     if (strchr(name, '/') != 0)
138       name = strrchr(name, '/') + 1;
139     char* dot;
140     if ((dot = strchr(name, '.')) != 0)
141       *dot = 0;
142     printf("\n/*\n");
143     printf("  name: %s\n", name);
144     printf("  orig: %u\n", (uint)size);
145     printf("  pack: %u\n", (uint)pack_len);
146     printf("*/\n\n");
147     dodump(name, pack_data, pack_len);
148     ret = 0;
149   }
150   while (0);
151   if (namebuf != 0)
152     free(namebuf);
153   if (pack_data != 0)
154     my_free(pack_data); // Free data returned from packfrm with my_free
155   if (fd != -1)
156     (void)close(fd);
157   if (data != 0)
158     free(data);
159   return ret;
160 }
161 
162 int
main(int argc,char ** argv)163 main(int argc, char** argv)
164 {
165   my_progname = "ndb_pack_frm";
166   int ret;
167 
168   ndb_init();
169   ndb_opt_set_usage_funcs(short_usage_sub, usage);
170   ret = handle_options(&argc, &argv, my_long_options, ndb_std_get_one_option);
171  if (ret != 0)
172     return NDBT_WRONGARGS;
173 
174   for (int i = 0; i < argc; i++)
175   {
176     ret = dofile(argv[i]);
177     if (ret != 0)
178       return NDBT_FAILED;
179   }
180 
181   return NDBT_OK;
182 }
183