00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifndef lint
00039 static char copyright[] =
00040 "@(#) Copyright (c) 2002\n\
00041 Netherlands Forensic Institute. All rights reserved.\n";
00042 #endif
00043
00044 #ifdef HAVE_CONFIG_H
00045 #include <config.h>
00046 #endif
00047
00048 #include <ctype.h>
00049 #include <errno.h>
00050 #include <limits.h>
00051 #include <stdlib.h>
00052 #include <stdio.h>
00053 #include <string.h>
00054 #include <sys/types.h>
00055 #include <sys/stat.h>
00056 #include <fcntl.h>
00057 #include <unistd.h>
00058
00059 #include "rdd.h"
00060 #include "rdd_internals.h"
00061 #include "error.h"
00062 #include "commandline.h"
00063
00064 static const char *usage_message;
00065
00066 void
00067 rdd_opt_init(const char *usage_msg)
00068 {
00069 usage_message = usage_msg;
00070 }
00071
00072 static int
00073 match_name(char *input, char *short_name, char *long_name)
00074 {
00075
00076 if (input == 0) {
00077 return 0;
00078 }
00079
00080 if (short_name != 0) {
00081 if (!strcmp(input, short_name)) {
00082 return 1;
00083 }
00084 }
00085
00086
00087 if (long_name != 0) {
00088 if (!strcmp(input, long_name)) {
00089 return 1;
00090 }
00091 }
00092
00093 return 0;
00094 }
00095
00096
00097
00098
00099 RDD_OPTION *
00100 rdd_get_opt_with_arg(RDD_OPTION * tab, char **argv, int argc, unsigned *i, char **opt, char **arg)
00101 {
00102 RDD_OPTION *od;
00103 char *optname;
00104
00105 if (tab == 0) {
00106 return 0;
00107 }
00108 if (argv == 0) {
00109 return 0;
00110 }
00111 if (argc <= 0) {
00112 return 0;
00113 }
00114 if (i == 0) {
00115 return 0;
00116 }
00117 if (*i >= argc) {
00118 return 0;
00119 }
00120 if (*i < 0) {
00121 return 0;
00122 }
00123 if (opt == 0) {
00124 return 0;
00125 }
00126 if (arg == 0) {
00127 return 0;
00128 }
00129
00130
00131 *opt = 0;
00132 *arg = 0;
00133 optname = argv[*i];
00134 for (od = &tab[0]; od->long_name != 0; od++) {
00135
00136 if (!match_name(optname, od->short_name, od->long_name)) {
00137 continue;
00138 }
00139 ++od->count;
00140 *opt = optname;
00141
00142 if (!strcmp(od->long_name, "--out")) {
00143 *arg = 0;
00144 } else {
00145 if (od->count > 1) {
00146 error("option %s specified multiple times", optname);
00147 }
00148
00149 *opt = optname;
00150 if (od->arg_descr == 0) {
00151 *arg = 0;
00152 } else {
00153 (*i)++;
00154 if ((*i) >= (unsigned) argc) {
00155 error("option %s requires an argument", optname);
00156 }
00157 od->arg_value = *arg = argv[*i];
00158 }
00159 }
00160 return od;
00161 }
00162 return 0;
00163 }
00164
00165 int
00166 rdd_opt_set_arg(RDD_OPTION * tab, char * longname, char ** argp)
00167 {
00168 RDD_OPTION *od;
00169
00170 if (tab == 0) {
00171 return 0;
00172 }
00173 if (longname == 0) {
00174 return 0;
00175 }
00176
00177 for (od = &tab[0]; od->long_name != 0; od++) {
00178 if (streq(od->long_name+2, longname)) {
00179 if (od->count == 0) {
00180 return 0;
00181 }
00182 if (argp != 0) {
00183 *argp = od->arg_value;
00184 }
00185 return 1;
00186 }
00187 }
00188 bug("opt_set_arg: %s is not a known option", longname);
00189 return 0;
00190 }
00191
00192 int
00193 rdd_opt_set(RDD_OPTION * tab, char *longname)
00194 {
00195 return rdd_opt_set_arg(tab, longname, 0);
00196 }
00197
00198 static void
00199 rdd_option_table_usage(RDD_OPTION * tab, const char * name)
00200 {
00201 RDD_OPTION *od;
00202 char optnames[80];
00203
00204 if (name == 0 || tab == 0) {
00205 exit(EXIT_FAILURE);
00206 }
00207
00208 for (od = &tab[0]; od->long_name != 0; od++) {
00209 if (od->short_name != 0) {
00210 snprintf(optnames, sizeof optnames, "%s, %s %s",
00211 od->short_name, od->long_name,
00212 od->arg_descr == 0 ? "" : od->arg_descr);
00213 } else {
00214 snprintf(optnames, sizeof optnames, "%s %s", od->long_name,
00215 od->arg_descr == 0 ? "" : od->arg_descr);
00216 }
00217 optnames[(sizeof optnames)-1] = '\000';
00218
00219 if (strlen(optnames) <= 32) {
00220 fprintf(stderr, "%-32.32s %s\n",
00221 optnames, od->description);
00222 } else {
00223 fprintf(stderr, "%s\n", optnames);
00224 fprintf(stderr, "%-32.32s %s\n", "", od->description);
00225 }
00226 }
00227 }
00228
00229 void
00230 rdd_opt_usage(RDD_OPTION * opttab, RDD_OPTION * output_opttab, int exitCode)
00231 {
00232 if (usage_message != 0) {
00233 fprintf(stderr, "Usage: %s", usage_message);
00234 }
00235
00236 if (opttab != 0) {
00237 rdd_option_table_usage(opttab, "Options");
00238 }
00239
00240 if (output_opttab != 0) {
00241 rdd_option_table_usage(output_opttab, "Output options");
00242 }
00243 exit(exitCode);
00244 }
00245
00246 int
00247 compare_paths(char *first_path, char *second_path)
00248 {
00249 struct stat buffer;
00250 int status, fildes;
00251 long long first, second;
00252 fildes = open(first_path, O_RDONLY);
00253 if (fildes != -1) {
00254 status = fstat(fildes, &buffer);
00255 first = buffer.st_ino;
00256 close(fildes);
00257 fildes = open(second_path, O_RDONLY);
00258 if (fildes != -1) {
00259 status = fstat(fildes, &buffer);
00260 second = buffer.st_ino;
00261 close(fildes);
00262 return !(second == first);
00263 }
00264 }
00265 return 1;
00266 }
00267
00268
00269