bool fldata_parse(struct fdict_s *fdict, struct record_s *record, char *data) { struct field_s *field; char *start, *end; int idx = 0; start = data; end = data; while (*end != '\0' && *end != '\n') { end = fldata_field_end_pos(end); *end = '\0'; field = record_get_field(fdict, record, idx); if (!field_set_value(fdict, field, idx, (const char*)start)) { if (fdict->error) printf("%s\n", fdict->error); else printf("Unknow Error!!"); return false; } start = ++end; idx++; } return true; }
int cmd_edit(int argc, char **argv) { unsigned char key[KDF_HASH_LEN]; struct session *session = NULL; struct blob *blob = NULL; static struct option long_options[] = { {"sync", required_argument, NULL, 'S'}, {"username", no_argument, NULL, 'U'}, {"password", no_argument, NULL, 'P'}, {"url", no_argument, NULL, 'L'}, {"field", required_argument, NULL, 'F'}, {"name", no_argument, NULL, 'N'}, {"notes", no_argument, NULL, 'O'}, {"non-interactive", no_argument, NULL, 'X'}, {0, 0, 0, 0} }; char option; int option_index; enum { NONE, USERNAME, PASSWORD, URL, FIELD, NAME, NOTES } choice = NONE; _cleanup_free_ char *field = NULL; _cleanup_free_ char *tmppath = NULL; _cleanup_free_ char *tmpdir = NULL; _cleanup_free_ char *editcmd = NULL; int tmpfd; FILE *tmpfile; char *name; char *value; bool non_interactive = false; enum blobsync sync = BLOB_SYNC_AUTO; struct account *editable; struct account *notes_expansion, *notes_collapsed = NULL; struct field *editable_field = NULL; size_t len, read; bool should_log_read = false; #define ensure_choice() if (choice != NONE) goto choice_die; while ((option = getopt_long(argc, argv, "", long_options, &option_index)) != -1) { switch (option) { case 'S': sync = parse_sync_string(optarg); break; case 'U': ensure_choice(); choice = USERNAME; break; case 'P': ensure_choice(); choice = PASSWORD; break; case 'L': ensure_choice(); choice = URL; break; case 'F': ensure_choice(); choice = FIELD; field = xstrdup(optarg); break; case 'N': ensure_choice(); choice = NAME; break; case 'O': ensure_choice(); choice = NOTES; break; case 'X': non_interactive = true; break; case '?': default: die_usage(cmd_edit_usage); } } #undef ensure_choice if (argc - optind != 1) die_usage(cmd_edit_usage); if (choice == NONE) choice_die: die_usage("edit ... {--name|--username|--password|--url|--notes|--field=FIELD}"); name = argv[optind]; init_all(sync, key, &session, &blob); editable = find_unique_account(blob, name); if (editable) { if (editable->share && editable->share->readonly) die("%s is a readonly shared entry from %s. It cannot be edited.", editable->fullname, editable->share->name); should_log_read = true; } else { editable = new0(struct account, 1); editable->id = xstrdup("0"); account_set_password(editable, xstrdup(""), key); account_set_fullname(editable, xstrdup(name), key); account_set_username(editable, xstrdup(""), key); account_set_note(editable, xstrdup(""), key); editable->url = xstrdup(""); editable->next = blob->account_head; blob->account_head = editable; } notes_expansion = notes_expand(editable); if (notes_expansion) { notes_collapsed = editable; editable = notes_expansion; } else if (choice == FIELD) die("Editing fields of entries that are not secure notes is currently not supported."); if (choice == USERNAME) value = editable->username; else if (choice == PASSWORD) value = editable->password; else if (choice == URL) value = editable->url; else if (choice == NAME) value = editable->fullname; else if (choice == FIELD) { for (editable_field = editable->field_head; editable_field; editable_field = editable_field->next) { if (!strcmp(editable_field->name, field)) break; } if (!editable_field) { editable_field = new0(struct field, 1); editable_field->type = xstrdup("text"); editable_field->name = xstrdup(field); field_set_value(editable, editable_field, xstrdup(""), key); editable_field->next = editable->field_head; editable->field_head = editable_field; } value = editable_field->value; } else if (choice == NOTES)