4 * Date: Mon Dec 28 08:54:38 2009
6 * GNU recutils - recins
10 /* Copyright (C) 2009-2019 Jose E. Marchesi */
12 /* This program is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 3 of the License, or
15 * (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program. If not, see <http://www.gnu.org/licenses/>.
36 #define _(str) gettext (str)
42 /* Forward declarations. */
43 bool recins_insert_record (rec_db_t db
, char *type
, rec_record_t record
);
44 void recins_parse_args (int argc
, char **argv
);
50 char *recutl_type
= NULL
;
51 rec_sex_t recutl_sex
= NULL
;
52 char *recutl_sex_str
= NULL
;
53 char *recutl_quick_str
= NULL
;
54 bool recutl_insensitive
= false;
55 rec_record_t recins_record
= NULL
;
56 char *recins_file
= NULL
;
57 bool recins_force
= false;
58 bool recins_verbose
= false;
59 bool recins_external
= true;
60 bool recins_auto
= true;
61 char *recins_password
= NULL
;
62 size_t recutl_random
= 0;
65 * Command line options management
71 RECORD_SELECTION_ARGS
,
78 #if defined REC_CRYPT_SUPPORT
84 static const struct option GNU_longOptions
[] =
87 RECORD_SELECTION_LONG_ARGS
,
88 {"type", required_argument
, NULL
, TYPE_ARG
},
89 {"name", required_argument
, NULL
, NAME_ARG
},
90 {"value", required_argument
, NULL
, VALUE_ARG
},
91 {"force", no_argument
, NULL
, FORCE_ARG
},
92 {"verbose", no_argument
, NULL
, VERBOSE_ARG
},
93 {"no-external", no_argument
, NULL
, NO_EXTERNAL_ARG
},
94 {"record", required_argument
, NULL
, RECORD_ARG
},
95 {"no-auto", no_argument
, NULL
, NO_AUTO_ARG
},
96 #if defined REC_CRYPT_SUPPORT
97 {"password", required_argument
, NULL
, PASSWORD_ARG
},
107 recutl_print_help (void)
109 /* TRANSLATORS: --help output, recins synopsis.
112 Usage: recins [OPTION]... [-t TYPE] [-n NUM | -e RECORD_EXPR | -q STR | -m NUM] [(-f NAME -v STR) | -r RECDATA]... [FILE]\n"));
114 /* TRANSLATORS: --help output, recins short description.
117 Insert new records in a rec database.\n"), stdout
);
120 /* TRANSLATORS: --help output, recins arguments.
123 -f, --field=STR field name; should be followed by a -v.\n\
124 -v, --value=STR field value; should be preceded by an -f.\n\
125 -r, --record=STR record that will be inserted in the file.\n\
126 --force insert the record even if it is violating\n\
127 record restrictions.\n\
128 --no-external don't use external descriptors.\n\
129 --no-auto don't insert auto generated fields.\n\
130 --verbose give a detailed report if the integrity check\n\
133 #if defined REC_CRYPT_SUPPORT
134 /* TRANSLATORS: --help output, encryption related options.
137 -s, --password=STR encrypt confidential fields with the given password.\n"),
141 recutl_print_help_common ();
144 recutl_print_help_record_selection ();
147 /* TRANSLATORS: --help output, notes on recins.
150 If no FILE is specified then the command acts like a filter, getting\n\
151 the data from standard input and writing the result to standard output.\n"), stdout
);
154 recutl_print_help_footer ();
158 void recins_parse_args (int argc
,
163 rec_field_t field
= NULL
;
164 char *field_name
= NULL
;
165 rec_record_t provided_record
;
167 while ((ret
= getopt_long (argc
,
169 RECORD_SELECTION_SHORT_ARGS
170 ENCRYPTION_SHORT_ARGS
179 RECORD_SELECTION_ARGS_CASES
187 recins_verbose
= true;
195 recutl_fatal (_("a -f should be followed by a -v\n"));
199 if (recins_record
== NULL
)
201 recins_record
= rec_record_new ();
202 rec_record_set_source (recins_record
, "cmdli");
203 rec_record_set_location (recins_record
, 0);
206 if (!rec_field_name_p (optarg
))
208 recutl_fatal (_("invalid field name %s.\n"), optarg
);
211 field
= rec_field_new (optarg
, "foo");
219 recutl_fatal (_("a -v should be preceded by a -f\n"));
222 rec_field_set_value (field
, optarg
);
223 rec_mset_append (rec_record_mset (recins_record
), MSET_FIELD
, (void *) field
, MSET_ANY
);
228 case NO_EXTERNAL_ARG
:
230 recins_external
= false;
238 #if defined REC_CRYPT_SUPPORT
242 if (recins_password
!= NULL
)
244 recutl_fatal (_("more than one password was specified\n"));
247 recins_password
= xstrdup (optarg
);
254 /* Parse the provided record and put it in recins_record. */
255 provided_record
= rec_parse_record_str (optarg
);
256 if (!provided_record
)
258 recutl_fatal (_("error while parsing the record provided by -r\n"));
263 /* Append the fields in provided_record into
266 rec_mset_iterator_t iter
= rec_mset_iterator (rec_record_mset (provided_record
));
267 while (rec_mset_iterator_next (&iter
, MSET_FIELD
, (const void **) &field
, NULL
))
269 rec_mset_append (rec_record_mset (recins_record
), MSET_FIELD
, (void *) rec_field_dup (field
), MSET_ANY
);
272 rec_mset_iterator_free (&iter
);
274 rec_record_destroy (provided_record
);
275 provided_record
= NULL
;
279 recins_record
= provided_record
;
293 recutl_fatal (_("please provide a value for the field %s\n"), field_name
);
296 /* Read the name of the file where to make the insertions. */
300 if ((argc
- optind
) != 1)
302 recutl_print_help ();
306 recins_file
= argv
[optind
++];
311 recins_add_new_record (rec_db_t db
)
315 #if defined REC_CRYPT_SUPPORT
317 /* Get the password interactively from the user if some field is
318 declared as confidential in the requested record set. */
322 rec_fex_t confidential_fields
;
326 rset
= rec_db_get_rset_by_type (db
, recutl_type
);
330 confidential_fields
= rec_rset_confidential (rset
);
331 if (!confidential_fields
)
332 recutl_out_of_memory ();
334 if (rec_fex_size (confidential_fields
) > 0)
336 if (!recins_password
&& recutl_interactive ())
338 recins_password
= recutl_getpass (true);
339 if (!recins_password
)
341 recutl_fatal ("not in an interactive terminal.\n");
345 /* Passwords can't be empty. */
347 if (recins_password
&& (strlen (recins_password
) == 0))
349 free (recins_password
);
350 recins_password
= NULL
;
357 #endif /* REC_CRYPT_SUPPORT */
359 /* Set flags flags and call the library to perform the
360 requested insertion/replacement operation. */
362 if (recutl_insensitive
)
364 flags
= flags
| REC_F_ICASE
;
369 flags
= flags
| REC_F_NOAUTO
;
372 if (!rec_db_insert (db
,
381 recutl_out_of_memory ();
383 /* Check for the integrity of the resulting database. */
385 if (!recins_force
&& db
)
387 recutl_check_integrity (db
, recins_verbose
, recins_external
);
392 main (int argc
, char *argv
[])
396 recutl_init ("recins");
398 recins_parse_args (argc
, argv
);
400 db
= recutl_read_db_from_file (recins_file
);
403 /* Create an empty database. */
406 recins_add_new_record (db
);
408 if (!recutl_file_is_writable (recins_file
))
410 recutl_error (_("file %s is not writable.\n"), recins_file
);
413 recutl_write_db_to_file (db
, recins_file
);
418 /* End of recins.c */