annotate pwfile.c @ 22:ec01c579024a

Add fully interactive mode
author Guido Berhoerster <guido+pwm@berhoerster.name>
date Thu, 07 Sep 2017 12:40:50 +0200
parents efef93e54c5f
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1 /*
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
2 * Copyright (C) 2017 Guido Berhoerster <guido+pwm@berhoerster.name>
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
3 *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
4 * Permission is hereby granted, free of charge, to any person obtaining
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
5 * a copy of this software and associated documentation files (the
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
6 * "Software"), to deal in the Software without restriction, including
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
7 * without limitation the rights to use, copy, modify, merge, publish,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
8 * distribute, sublicense, and/or sell copies of the Software, and to
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
9 * permit persons to whom the Software is furnished to do so, subject to
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
10 * the following conditions:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
11 *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
12 * The above copyright notice and this permission notice shall be included
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
13 * in all copies or substantial portions of the Software.
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
14 *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
22 */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
23
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
24 #include "compat.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
25
10
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
26 #include <ctype.h>
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
27 #ifdef HAVE_ERR_H
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
28 #include <err.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
29 #endif /* HAVE_ERR_H */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
30 #include <errno.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
31 #include <stdio.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
32 #include <string.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
33 #include <sys/stat.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
34 #ifdef HAVE_SYS_TREE_H
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
35 #include <sys/tree.h>
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
36 #endif
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
37 #include <sys/utsname.h>
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
38 #include <unistd.h>
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
39 #include <time.h>
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
40
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
41 #include "pwfile.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
42 #include "util.h"
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
43
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
44 struct record_id_entry {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
45 RB_ENTRY(record_id_entry) record_id_entry;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
46 unsigned int id;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
47 unsigned char uuid[PWS3_UUID_SIZE];
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
48 };
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
49
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
50 RB_HEAD(record_id_tree, record_id_entry);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
51
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
52 static int record_id_entry_cmp(struct record_id_entry *,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
53 struct record_id_entry *);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
54 RB_PROTOTYPE_STATIC(record_id_tree, record_id_entry, record_id_entry,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
55 record_id_entry_cmp)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
56 RB_GENERATE_STATIC(record_id_tree, record_id_entry, record_id_entry,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
57 record_id_entry_cmp)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
58
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
59 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
60 record_id_entry_cmp(struct record_id_entry *entry1,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
61 struct record_id_entry *entry2)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
62 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
63 if (entry1->id > entry2->id) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
64 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
65 } else if (entry1->id < entry2->id) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
66 return (1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
67 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
68 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
69 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
70
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
71 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
72 pws_record_cmp(const void *p1, const void *p2)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
73 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
74 int retval;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
75 struct pws3_record *record1 = *(struct pws3_record **)p1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
76 struct pws3_record *record2 = *(struct pws3_record **)p2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
77 struct pws3_field *group_field1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
78 const char *group1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
79 struct pws3_field *group_field2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
80 const char *group2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
81 struct pws3_field *title_field1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
82 const char *title1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
83 struct pws3_field *title_field2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
84 const char *title2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
85
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
86 group_field1 = pws3_record_get_field(record1, PWS3_RECORD_FIELD_GROUP);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
87 group1 = (group_field1 != NULL) ? pws3_field_get_text(group_field1) :
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
88 "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
89 group_field2 = pws3_record_get_field(record2, PWS3_RECORD_FIELD_GROUP);
2
5cd0debdb7d8 Fix a typo potentially causing a NULL pointer dereference
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 0
diff changeset
90 group2 = (group_field2 != NULL) ? pws3_field_get_text(group_field2) :
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
91 "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
92 retval = strcmp(group1, group2);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
93 if (retval != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
94 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
95 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
96
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
97 title_field1 = pws3_record_get_field(record1, PWS3_RECORD_FIELD_TITLE);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
98 title1 = (title_field1 != NULL) ? pws3_field_get_text(title_field1) :
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
99 "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
100 title_field2 = pws3_record_get_field(record2, PWS3_RECORD_FIELD_TITLE);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
101 title2 = (title_field2 != NULL) ? pws3_field_get_text(title_field2) :
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
102 "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
103 return (strcmp(title1, title2));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
104 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
105
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
106 static void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
107 record_id_tree_clear(struct record_id_tree *tree)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
108 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
109 struct record_id_entry *entry;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
110 struct record_id_entry *entry_tmp;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
111
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
112 RB_FOREACH_SAFE(entry, record_id_tree, tree, entry_tmp) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
113 RB_REMOVE(record_id_tree, tree, entry);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
114 free(entry);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
115 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
116 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
117
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
118 static void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
119 record_id_tree_destroy(struct record_id_tree *tree)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
120 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
121 if (tree == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
122 return;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
123 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
124
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
125 record_id_tree_clear(tree);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
126 free(tree);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
127 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
128
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
129 static const unsigned char *
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
130 record_id_tree_get_uuid(struct record_id_tree *tree, unsigned int id)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
131 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
132 struct record_id_entry *entry;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
133
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
134 entry = RB_FIND(record_id_tree, tree,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
135 &(struct record_id_entry){ .id = id });
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
136 if (entry == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
137 return (NULL);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
138 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
139
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
140 return (entry->uuid);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
141 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
142
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
143 void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
144 pwfile_init(struct pwm_ctx *ctx)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
145 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
146 ctx->file = pws3_file_create();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
147 if (ctx->file == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
148 err(1, "pws3_file_create");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
149 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
150
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
151 ctx->next_id = 1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
152
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
153 ctx->record_id_tree = xmalloc(sizeof (struct record_id_tree));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
154 RB_INIT(ctx->record_id_tree);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
155 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
156
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
157 void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
158 pwfile_destroy(struct pwm_ctx *ctx)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
159 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
160 record_id_tree_destroy(ctx->record_id_tree);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
161 ctx->record_id_tree = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
162 pws3_file_destroy(ctx->file);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
163 ctx->file = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
164 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
165
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
166 int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
167 pwfile_read_file(struct pwm_ctx *ctx, FILE *fp)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
168 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
169 struct pws3_record *pws3_record;
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
170 size_t record_list_len = 0;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
171 struct pws3_record **pws3_record_list;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
172 size_t i;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
173 struct pws3_field *uuid_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
174 const unsigned char *uuid;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
175 struct record_id_entry *entry;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
176
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
177 if (pws3_file_read_stream(ctx->file, ctx->password, fp) != 0) {
5
0b1bce8db371 Prevent misleading double error message
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 4
diff changeset
178 fprintf(stderr, "failed to read password database: %s\n",
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
179 pws3_file_get_error_message(ctx->file));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
180 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
181 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
182
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
183 record_id_tree_clear(ctx->record_id_tree);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
184
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
185 /* sort records by group and title */
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
186 for (pws3_record = pws3_file_first_record(ctx->file);
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
187 pws3_record != NULL;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
188 pws3_record = pws3_file_next_record(ctx->file, pws3_record)) {
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
189 record_list_len++;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
190 }
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
191 pws3_record_list = xmalloc(sizeof (struct pws3_record *) *
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
192 record_list_len);
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
193 for (pws3_record = pws3_file_first_record(ctx->file), i = 0;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
194 pws3_record != NULL;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
195 pws3_record = pws3_file_next_record(ctx->file, pws3_record)) {
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
196 pws3_record_list[i++] = pws3_record;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
197 }
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
198 qsort(pws3_record_list, record_list_len,
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
199 sizeof (struct pws3_record *), pws_record_cmp);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
200
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
201 /* build the tree of record IDs */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
202 for (i = 0; i < record_list_len; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
203 uuid_field = pws3_record_get_field(pws3_record_list[i],
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
204 PWS3_RECORD_FIELD_UUID);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
205 uuid = pws3_field_get_uuid(uuid_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
206
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
207 entry = xmalloc(sizeof (struct record_id_entry));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
208 entry->id = ctx->next_id++;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
209 memcpy(entry->uuid, uuid, sizeof (entry->uuid));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
210
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
211 RB_INSERT(record_id_tree, ctx->record_id_tree, entry);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
212 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
213
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
214 free(pws3_record_list);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
215
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
216 ctx->unsaved_changes = 0;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
217
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
218 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
219 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
220
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
221 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
222 make_backup_copy(const char *filename)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
223 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
224 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
225 FILE *fp_orig = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
226 char *backup_filename = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
227 char *tmpfilename = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
228 mode_t old_mode;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
229 int fd_backup = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
230 unsigned char buf[BUFSIZ];
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
231 size_t read_len;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
232 FILE *fp_backup = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
233
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
234 fp_orig = fopen(filename, "r");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
235 if (fp_orig == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
236 if (errno != ENOENT) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
237 warn("fopen");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
238 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
239 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
240 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
241 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
242
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
243 xasprintf(&backup_filename, "%s~", filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
244 xasprintf(&tmpfilename, "%s.XXXXXX", filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
245
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
246 /* create temporary file */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
247 old_mode = umask(S_IRWXG | S_IRWXO);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
248 fd_backup = mkstemp(tmpfilename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
249 umask(old_mode);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
250 if (fd_backup == -1) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
251 warn("mkstemp");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
252 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
253 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
254 fp_backup = fdopen(fd_backup, "w");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
255 if (fp_backup == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
256 warn("fdopen");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
257 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
258 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
259
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
260 /* copy file contents */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
261 while (!feof(fp_orig)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
262 read_len = fread(buf, 1, sizeof (buf), fp_orig);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
263 if ((read_len < sizeof (buf)) && ferror(fp_orig)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
264 warn("fread");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
265 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
266 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
267 if (fwrite(buf, 1, read_len, fp_backup) != read_len) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
268 warn("fwrite");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
269 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
270 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
271 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
272 if (fflush(fp_backup) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
273 warn("fflush");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
274 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
275 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
276 if (fsync(fileno(fp_backup)) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
277 warn("fsync");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
278 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
279 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
280
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
281 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
282
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
283 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
284 if ((fd_backup != -1) && (fp_backup == NULL)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
285 close(fd_backup);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
286 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
287 if (fp_backup != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
288 fclose(fp_backup);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
289 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
290 if (fp_orig != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
291 fclose(fp_orig);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
292 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
293 if (retval == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
294 /* rename temporary file and overwrite existing file */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
295 if (rename(tmpfilename, backup_filename) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
296 warn("rename");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
297 retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
298 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
299 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
300 if ((retval != 0) && ((fd_backup != -1) || (fp_backup != NULL))) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
301 unlink(tmpfilename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
302 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
303 free(tmpfilename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
304 free(backup_filename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
305
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
306 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
307 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
308
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
309 static void
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
310 update_file_metadata(struct pws3_file *file)
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
311 {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
312 struct pws3_field *save_app_field;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
313 struct pws3_field *save_timestamp_field;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
314 char *logname;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
315 const char default_username[] = "unknown user";
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
316 const char *username;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
317 size_t username_len;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
318 struct utsname utsn;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
319 const char default_hostname[] = "unknown host";
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
320 const char *hostname;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
321 char user_host[1024];
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
322 struct pws3_field *save_user_host_field;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
323 struct pws3_field *save_user_field;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
324 struct pws3_field *save_host_field;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
325
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
326 save_app_field =
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
327 pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_APPLICATION);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
328 if (save_app_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
329 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
330 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
331 if (pws3_field_set_text(save_app_field, PACKAGE " V" VERSION) !=
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
332 0) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
333 err(1, "pws3_field_set_text");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
334 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
335 pws3_file_set_header_field(file, save_app_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
336
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
337 save_timestamp_field =
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
338 pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_TIMESTAMP);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
339 if (save_timestamp_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
340 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
341 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
342 pws3_field_set_time(save_timestamp_field, time(NULL));
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
343 pws3_file_set_header_field(file, save_timestamp_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
344
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
345 logname = getenv("LOGNAME");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
346 if (logname == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
347 logname = getlogin();
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
348 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
349 username = (logname != NULL) ? logname : default_username;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
350 username_len = MIN(strlen(username), sizeof (user_host) - 4 - 1);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
351 hostname = (uname(&utsn) == 0) ? utsn.nodename : default_hostname;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
352 snprintf(user_host, sizeof (user_host), "%04zx%s%s", username_len,
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
353 username, hostname);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
354
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
355 save_user_host_field =
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
356 pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER_HOST);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
357 if (save_user_host_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
358 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
359 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
360 if (pws3_field_set_text(save_user_host_field, user_host) != 0) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
361 err(1, "pws3_field_set_text");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
362 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
363 pws3_file_set_header_field(file, save_user_host_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
364
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
365 save_user_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_USER);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
366 if (save_user_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
367 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
368 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
369 if (pws3_field_set_text(save_user_field, logname) != 0) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
370 err(1, "pws3_field_set_text");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
371 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
372 pws3_file_set_header_field(file, save_user_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
373
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
374 save_host_field = pws3_field_create(1, PWS3_HEADER_FIELD_SAVE_HOST);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
375 if (save_host_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
376 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
377 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
378 if (pws3_field_set_text(save_host_field, hostname) != 0) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
379 err(1, "pws3_field_set_text");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
380 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
381 pws3_file_set_header_field(file, save_host_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
382 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
383
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
384 static int
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
385 write_file(struct pwm_ctx *ctx, const char *filename)
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
386 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
387 int retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
388 char *tmpfilename = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
389 mode_t old_mode;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
390 int fd = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
391 FILE *fp = NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
392
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
393 xasprintf(&tmpfilename, "%s.XXXXXX", filename);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
394
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
395 /* create temporary file */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
396 old_mode = umask(S_IRWXG | S_IRWXO);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
397 fd = mkstemp(tmpfilename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
398 if (fd == -1) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
399 warn("mkstemp");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
400 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
401 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
402 umask(old_mode);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
403 fp = fdopen(fd, "w");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
404 if (fp == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
405 warn("fdopen");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
406 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
407 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
408
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
409 /* write contents */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
410 if (pws3_file_write_stream(ctx->file, ctx->password, 10000, fp) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
411 warnx("pws3_file_write_stream: %s",
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
412 pws3_file_get_error_message(ctx->file));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
413 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
414 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
415 if (fflush(fp) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
416 warn("fflush");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
417 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
418 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
419 if (fsync(fileno(fp)) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
420 warn("fsync");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
421 goto out;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
422 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
423
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
424 retval = 0;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
425
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
426 out:
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
427 if ((fd != -1) && (fp == NULL)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
428 close(fd);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
429 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
430 if (fp != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
431 fclose(fp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
432 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
433 if (retval == 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
434 /* rename temporary file and overwrite existing file */
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
435 if (rename(tmpfilename, filename) != 0) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
436 warn("rename");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
437 retval = -1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
438 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
439 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
440 if ((retval != 0) && ((fd != -1) || (fp != NULL))) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
441 unlink(tmpfilename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
442 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
443 free(tmpfilename);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
444
20
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
445 return (retval);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
446 }
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
447
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
448 int
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
449 pwfile_write_autosave_file(struct pwm_ctx *ctx)
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
450 {
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
451 int retval;
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
452 char *autosave_filename;
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
453
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
454 xasprintf(&autosave_filename, "%s/autosave.psafe3", ctx->dirname);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
455
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
456 retval = write_file(ctx, autosave_filename);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
457
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
458 free(autosave_filename);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
459
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
460 return (retval);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
461 }
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
462
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
463 int
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
464 pwfile_write_file(struct pwm_ctx *ctx)
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
465 {
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
466 int retval;
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
467
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
468 /* update password file metadata */
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
469 update_file_metadata(ctx->file);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
470
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
471 /* make a backup copy of the existing password file */
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
472 if (make_backup_copy(ctx->filename) != 0) {
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
473 return (-1);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
474 }
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
475
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
476 retval = write_file(ctx, ctx->filename);
efef93e54c5f Automatically save the database when receiving a fatal signal
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 13
diff changeset
477
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
478 ctx->unsaved_changes = !!retval;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
479
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
480 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
481 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
482
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
483 static int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
484 list_item_cmp(const void *p1, const void *p2)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
485 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
486 int retval;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
487 const union list_item *item1 = *(const union list_item **)p1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
488 const union list_item *item2 = *(const union list_item **)p2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
489 const char *group1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
490 const char *group2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
491 const char *title1;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
492 const char *title2;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
493
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
494 /* sort both groups and records first by group name */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
495 group1 = (item1->any.group != NULL) ? item1->any.group : "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
496 group2 = (item2->any.group != NULL) ? item2->any.group : "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
497 retval = strcmp(group1, group2);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
498 if ((retval != 0) || ((item1->any.type == ITEM_TYPE_GROUP) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
499 (item2->any.type == ITEM_TYPE_GROUP))) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
500 return (retval);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
501 } else if ((item1->any.type == ITEM_TYPE_GROUP) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
502 (item2->any.type == ITEM_TYPE_RECORD)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
503 /* groups come before records belonging to it */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
504 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
505 } else if ((item1->any.type == ITEM_TYPE_RECORD) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
506 (item2->any.type == ITEM_TYPE_GROUP)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
507 return (1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
508 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
509
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
510 /* sort records also by title */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
511 title1 = (item1->record.title != NULL) ? item1->record.title : "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
512 title2 = (item2->record.title != NULL) ? item2->record.title : "";
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
513 return (strcmp(title1, title2));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
514 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
515
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
516 union list_item **
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
517 pwfile_create_list(struct pwm_ctx *ctx)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
518 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
519 union list_item **list;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
520 struct record_id_entry *entry;
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
521 size_t list_capacity = 0;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
522 struct pws3_field *empty_group_field;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
523 struct pws3_record *pws3_record;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
524 struct pws3_field *group_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
525 const char *group;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
526 struct pws3_field *title_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
527 const char *title;
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
528 union list_item *item;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
529 size_t list_len = 0;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
530 size_t i;
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
531 size_t j;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
532 const char *prev_group = NULL;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
533
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
534 RB_FOREACH(entry, record_id_tree, ctx->record_id_tree) {
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
535 list_capacity++;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
536 }
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
537 list_capacity *= 2; /* maximum number of group items */
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
538 for (empty_group_field = pws3_file_first_empty_group(ctx->file);
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
539 empty_group_field != NULL;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
540 empty_group_field = pws3_file_next_empty_group(ctx->file,
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
541 empty_group_field)) {
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
542 list_capacity++;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
543 }
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
544 list_capacity++; /* terminating NULL */
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
545 list = xmalloc(sizeof (union list_item *) * list_capacity);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
546
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
547 RB_FOREACH(entry, record_id_tree, ctx->record_id_tree) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
548 pws3_record = pws3_file_get_record(ctx->file, entry->uuid);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
549 group_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
550 PWS3_RECORD_FIELD_GROUP);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
551 group = (group_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
552 pws3_field_get_text(group_field) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
553 title_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
554 PWS3_RECORD_FIELD_TITLE);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
555 title = (title_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
556 pws3_field_get_text(title_field) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
557
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
558 item = xmalloc(sizeof (union list_item));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
559 item->record.type = ITEM_TYPE_RECORD;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
560 item->record.group = (group != NULL) ? xstrdup(group) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
561 item->record.title = (title != NULL) ? xstrdup(title) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
562 item->record.id = entry->id;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
563 memcpy(item->record.uuid, entry->uuid,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
564 sizeof (item->record.uuid));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
565
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
566 list[list_len++] = item;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
567 }
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
568 /* sort records by group and title in order to find unqiue groups */
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
569 qsort(list, list_len, sizeof (union list_item *), list_item_cmp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
570
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
571 /* add groups based on the sorted records */
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
572 for (i = 0, j = list_len; i < list_len; i++) {
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
573 group = list[i]->record.group;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
574 if ((group != NULL) && ((prev_group == NULL) ||
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
575 (strcmp(prev_group, group) != 0))) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
576 item = xmalloc(sizeof (union list_item));
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
577 item->group.type = ITEM_TYPE_GROUP;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
578 item->group.group = (group != NULL) ? xstrdup(group) :
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
579 NULL;
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
580 list[j++] = item;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
581 prev_group = group;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
582 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
583 }
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
584 list_len = j;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
585
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
586 /* add empty groups to the list */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
587 for (empty_group_field = pws3_file_first_empty_group(ctx->file);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
588 empty_group_field != NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
589 empty_group_field = pws3_file_next_empty_group(ctx->file,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
590 empty_group_field)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
591 group = pws3_field_get_text(empty_group_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
592
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
593 item = xmalloc(sizeof (union list_item));
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
594 item->group.type = ITEM_TYPE_GROUP;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
595 item->group.group = xstrdup(group);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
596
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
597 list[list_len++] = item;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
598 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
599
3
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
600 /* terminate the list */
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
601 list[list_len] = NULL;
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
602 list = xrealloc(list, sizeof (union list_item *) * (list_len + 1));
1cc98a5677d9 Refactor the creation of the record and group list
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 2
diff changeset
603
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
604 /* sort the final list by group and title */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
605 qsort(list, list_len, sizeof (union list_item *), list_item_cmp);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
606
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
607 return (list);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
608 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
609
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
610 void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
611 pwfile_destroy_list(union list_item **list)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
612 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
613 size_t i;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
614
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
615 if (list == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
616 return;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
617 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
618
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
619 for (i = 0; list[i] != NULL; i++) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
620 if (list[i]->any.type == ITEM_TYPE_RECORD) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
621 free(list[i]->record.title);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
622 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
623 free(list[i]->any.group);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
624 free(list[i]);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
625 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
626
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
627 free(list);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
628 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
629
10
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
630 static int
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
631 parse_user_host(const char *user_host, char **userp, char **hostp)
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
632 {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
633 size_t user_host_len;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
634 size_t i;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
635 unsigned int user_len;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
636
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
637 user_host_len = strlen(user_host);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
638 if (user_host_len < 4) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
639 return (-1);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
640 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
641 for (i = 0; i < 4; i++) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
642 if (!isxdigit(user_host[i])) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
643 return (-1);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
644 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
645 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
646 if (sscanf(user_host, "%04x", &user_len) != 1) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
647 return (-1);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
648 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
649 if (4 + (size_t)user_len > user_host_len) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
650 return (-1);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
651 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
652
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
653 xasprintf(userp, "%.*s", (int)user_len, user_host + 4);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
654 xasprintf(hostp, "%s", user_host + 4 + user_len);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
655
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
656 return (0);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
657 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
658
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
659 struct metadata *
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
660 pwfile_get_metadata(struct pwm_ctx *ctx)
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
661 {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
662 struct metadata *metadata;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
663 struct pws3_field *version_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
664 struct pws3_field *save_app_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
665 struct pws3_field *save_timestamp_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
666 struct pws3_field *save_user_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
667 struct pws3_field *save_host_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
668 struct pws3_field *save_user_host_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
669
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
670 metadata = xmalloc(sizeof (struct metadata));
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
671
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
672 version_field = pws3_file_get_header_field(ctx->file,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
673 PWS3_HEADER_FIELD_VERSION);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
674 metadata->version = pws3_field_get_uint16(version_field);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
675
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
676 save_app_field = pws3_file_get_header_field(ctx->file,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
677 PWS3_HEADER_FIELD_SAVE_APPLICATION);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
678 metadata->application = (save_app_field != NULL) ?
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
679 xstrdup(pws3_field_get_text(save_app_field)) : NULL;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
680
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
681 save_timestamp_field = pws3_file_get_header_field(ctx->file,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
682 PWS3_HEADER_FIELD_SAVE_TIMESTAMP);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
683 metadata->timestamp = (save_timestamp_field != NULL) ?
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
684 pws3_field_get_time(save_timestamp_field) : 0;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
685
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
686 save_user_field = pws3_file_get_header_field(ctx->file,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
687 PWS3_HEADER_FIELD_SAVE_USER);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
688 save_host_field = pws3_file_get_header_field(ctx->file,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
689 PWS3_HEADER_FIELD_SAVE_HOST);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
690 save_user_host_field = pws3_file_get_header_field(ctx->file,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
691 PWS3_HEADER_FIELD_SAVE_USER_HOST);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
692 metadata->user = NULL;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
693 metadata->host = NULL;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
694 if ((save_user_field != NULL) && (save_host_field != NULL)) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
695 metadata->user = xstrdup(pws3_field_get_text(save_user_field));
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
696 metadata->host = xstrdup(pws3_field_get_text(save_host_field));
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
697 } else if (save_user_host_field != NULL) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
698 parse_user_host(pws3_field_get_text(save_user_host_field),
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
699 &metadata->user, &metadata->host);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
700 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
701
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
702 return (metadata);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
703 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
704
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
705 void
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
706 pwfile_destroy_metadata(struct metadata *metadata)
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
707 {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
708 if (metadata == NULL) {
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
709 return;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
710 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
711
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
712 free(metadata->user);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
713 free(metadata->host);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
714 free(metadata->application);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
715 free(metadata);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
716 }
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
717
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
718 static void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
719 update_record(struct pws3_record *pws3_record, struct record *record)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
720 {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
721 time_t now;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
722 struct pws3_field *ctime_field;
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
723 struct pws3_field *mtime_field;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
724 struct pws3_field *title_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
725 struct pws3_field *group_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
726 struct pws3_field *username_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
727 struct pws3_field *password_field;
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
728 struct pws3_field *password_mtime_field;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
729 struct pws3_field *notes_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
730 struct pws3_field *url_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
731
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
732 now = time(NULL);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
733
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
734 ctime_field = pws3_record_get_field(pws3_record,
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
735 PWS3_RECORD_FIELD_CREATION_TIME);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
736 if (ctime_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
737 ctime_field = pws3_field_create(0,
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
738 PWS3_RECORD_FIELD_CREATION_TIME);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
739 if (ctime_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
740 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
741 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
742 pws3_field_set_time(ctime_field, now);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
743 pws3_record_set_field(pws3_record, ctime_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
744 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
745
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
746 mtime_field = pws3_field_create(0, PWS3_RECORD_FIELD_MODIFICATION_TIME);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
747 if (mtime_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
748 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
749 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
750 pws3_field_set_time(mtime_field, now);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
751 pws3_record_set_field(pws3_record, mtime_field);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
752
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
753 if (record->title != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
754 title_field = pws3_field_create(0, PWS3_RECORD_FIELD_TITLE);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
755 if (title_field == NULL) {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
756 err(1, "pws3_field_create");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
757 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
758 if (pws3_field_set_text(title_field,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
759 record->title) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
760 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
761 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
762 pws3_record_set_field(pws3_record, title_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
763 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
764 if (record->group != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
765 group_field = pws3_field_create(0, PWS3_RECORD_FIELD_GROUP);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
766 if (group_field == NULL) {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
767 err(1, "pws3_field_create");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
768 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
769 if (pws3_field_set_text(group_field,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
770 record->group) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
771 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
772 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
773 pws3_record_set_field(pws3_record, group_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
774 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
775 if (record->username != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
776 username_field = pws3_field_create(0,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
777 PWS3_RECORD_FIELD_USERNAME);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
778 if (username_field == NULL) {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
779 err(1, "pws3_field_create");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
780 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
781 if (pws3_field_set_text(username_field,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
782 record->username) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
783 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
784 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
785 pws3_record_set_field(pws3_record, username_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
786 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
787 if (record->password != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
788 password_field = pws3_field_create(0,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
789 PWS3_RECORD_FIELD_PASSWORD);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
790 if (password_field == NULL) {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
791 err(1, "pws3_field_create");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
792 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
793 if (pws3_field_set_text(password_field,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
794 record->password) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
795 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
796 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
797 pws3_record_set_field(pws3_record, password_field);
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
798
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
799 password_mtime_field = pws3_field_create(0,
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
800 PWS3_RECORD_FIELD_PASSWORD_MODIFICATION_TIME);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
801 if (password_mtime_field == NULL) {
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
802 err(1, "pws3_field_create");
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
803 }
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
804 pws3_field_set_time(password_mtime_field, now);
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
805 pws3_record_set_field(pws3_record, password_mtime_field);
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
806 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
807 if (record->notes != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
808 notes_field = pws3_field_create(0, PWS3_RECORD_FIELD_NOTES);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
809 if (notes_field == NULL) {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
810 err(1, "pws3_field_create");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
811 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
812 if (pws3_field_set_text(notes_field, record->notes) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
813 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
814 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
815 pws3_record_set_field(pws3_record, notes_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
816 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
817 if (record->url != NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
818 url_field = pws3_field_create(0, PWS3_RECORD_FIELD_URL);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
819 if (url_field == NULL) {
9
60c8ab006e55 Update metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 5
diff changeset
820 err(1, "pws3_field_create");
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
821 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
822 if (pws3_field_set_text(url_field, record->url) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
823 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
824 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
825 pws3_record_set_field(pws3_record, url_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
826 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
827 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
828
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
829 int
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
830 pwfile_create_pws_record(struct pwm_ctx *ctx, struct record *record)
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
831 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
832 struct pws3_record *pws3_record;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
833 const unsigned char *uuid;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
834 struct record_id_entry *entry;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
835
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
836 pws3_record = pws3_record_create();
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
837 if (pws3_record == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
838 err(1, "pws3_record_create");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
839 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
840 update_record(pws3_record, record);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
841 pws3_file_insert_record(ctx->file, pws3_record);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
842
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
843 uuid = pws3_field_get_uuid(pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
844 PWS3_RECORD_FIELD_UUID));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
845 entry = xmalloc(sizeof (struct record_id_entry));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
846 entry->id = ctx->next_id++;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
847 memcpy(entry->uuid, uuid, sizeof (entry->uuid));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
848 RB_INSERT(record_id_tree, ctx->record_id_tree, entry);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
849
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
850 ctx->unsaved_changes = 1;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
851
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
852 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
853 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
854
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
855 int
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
856 pwfile_modify_pws_record(struct pwm_ctx *ctx, unsigned int id,
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
857 struct record *record)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
858 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
859 const unsigned char *uuid;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
860
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
861 uuid = record_id_tree_get_uuid(ctx->record_id_tree, id);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
862 if (uuid == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
863 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
864 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
865
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
866 update_record(pws3_file_get_record(ctx->file, uuid), record);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
867
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
868 ctx->unsaved_changes = 1;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
869
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
870 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
871 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
872
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
873 int
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
874 pwfile_remove_pws_record(struct pwm_ctx *ctx, unsigned int id)
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
875 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
876 const unsigned char *uuid;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
877 struct record_id_entry *entry;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
878
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
879 uuid = record_id_tree_get_uuid(ctx->record_id_tree, id);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
880 if (uuid == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
881 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
882 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
883
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
884 pws3_record_destroy(pws3_file_remove_record(ctx->file, uuid));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
885
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
886 entry = RB_FIND(record_id_tree, ctx->record_id_tree,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
887 &(struct record_id_entry){ .id = id });
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
888 free(RB_REMOVE(record_id_tree, ctx->record_id_tree, entry));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
889
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
890 ctx->unsaved_changes = 1;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
891
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
892 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
893 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
894
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
895 int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
896 pwfile_create_group(struct pwm_ctx *ctx, const char *group)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
897 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
898 struct pws3_record *pws3_record;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
899 struct pws3_field *group_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
900 struct pws3_field *empty_group_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
901
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
902 /* check for a record in the given group */
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
903 for (pws3_record = pws3_file_first_record(ctx->file);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
904 pws3_record != NULL; pws3_record = pws3_file_next_record(ctx->file,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
905 pws3_record)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
906 group_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
907 PWS3_RECORD_FIELD_GROUP);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
908 if ((group_field != NULL) &&
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
909 (strcmp(group, pws3_field_get_text(group_field)) == 0)) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
910 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
911 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
912 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
913
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
914 empty_group_field = pws3_field_create(1,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
915 PWS3_HEADER_FIELD_EMPTY_GROUPS);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
916 if (empty_group_field == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
917 err(1, "pws3_field_create");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
918 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
919 if (pws3_field_set_text(empty_group_field, group) != 0) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
920 err(1, "pws3_field_set_text");
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
921 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
922 pws3_file_insert_empty_group(ctx->file, empty_group_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
923
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
924 ctx->unsaved_changes = 1;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
925
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
926 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
927 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
928
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
929 int
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
930 pwfile_remove_group(struct pwm_ctx *ctx, const char *group)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
931 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
932 struct pws3_field *empty_group_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
933
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
934 empty_group_field = pws3_file_remove_empty_group(ctx->file, group);
4
b5c4267a7182 Fix check for successful deletion of a empty group
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 3
diff changeset
935 if (empty_group_field == NULL) {
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
936 return (-1);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
937 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
938 pws3_field_destroy(empty_group_field);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
939
13
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
940 ctx->unsaved_changes = 1;
cf81eb0c2d5a Warn before quitting if there are unsaved changes
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 10
diff changeset
941
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
942 return (0);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
943 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
944
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
945 struct record *
22
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
946 pwfile_create_record(void)
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
947 {
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
948 struct record *record;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
949
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
950 record = xmalloc(sizeof (struct record));
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
951 record->ctime = (time_t)0;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
952 record->mtime = (time_t)0;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
953 record->group = NULL;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
954 record->title = NULL;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
955 record->username = NULL;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
956 record->password = NULL;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
957 record->notes = NULL;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
958 record->url = NULL;
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
959
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
960 return (record);
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
961 }
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
962
ec01c579024a Add fully interactive mode
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 20
diff changeset
963 struct record *
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
964 pwfile_get_record(struct pwm_ctx *ctx, unsigned int id)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
965 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
966 struct record *record;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
967 const unsigned char *uuid;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
968 struct pws3_record *pws3_record;
10
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
969 struct pws3_field *ctime_field;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
970 struct pws3_field *mtime_field;
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
971 struct pws3_field *title_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
972 struct pws3_field *group_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
973 struct pws3_field *username_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
974 struct pws3_field *password_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
975 struct pws3_field *notes_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
976 struct pws3_field *url_field;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
977
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
978 uuid = record_id_tree_get_uuid(ctx->record_id_tree, id);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
979 if (uuid == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
980 return (NULL);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
981 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
982 pws3_record = pws3_file_get_record(ctx->file, uuid);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
983
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
984 record = xmalloc(sizeof (struct record));
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
985
10
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
986 ctime_field = pws3_record_get_field(pws3_record,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
987 PWS3_RECORD_FIELD_CREATION_TIME);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
988 record->ctime = (ctime_field != NULL) ?
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
989 pws3_field_get_time(ctime_field) : (time_t)0;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
990
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
991 mtime_field = pws3_record_get_field(pws3_record,
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
992 PWS3_RECORD_FIELD_MODIFICATION_TIME);
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
993 record->mtime = (mtime_field != NULL) ?
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
994 pws3_field_get_time(mtime_field) : (time_t)0;
17fb30016e64 Enable access to record and file metadata
Guido Berhoerster <guido+pwm@berhoerster.name>
parents: 9
diff changeset
995
0
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
996 title_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
997 PWS3_RECORD_FIELD_TITLE);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
998 record->title = (title_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
999 xstrdup(pws3_field_get_text(title_field)) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1000
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1001 group_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1002 PWS3_RECORD_FIELD_GROUP);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1003 record->group = (group_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1004 xstrdup(pws3_field_get_text(group_field)) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1005
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1006 username_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1007 PWS3_RECORD_FIELD_USERNAME);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1008 record->username = (username_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1009 xstrdup(pws3_field_get_text(username_field)) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1010
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1011 password_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1012 PWS3_RECORD_FIELD_PASSWORD);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1013 record->password = (password_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1014 xstrdup(pws3_field_get_text(password_field)) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1015
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1016 notes_field = pws3_record_get_field(pws3_record,
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1017 PWS3_RECORD_FIELD_NOTES);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1018 record->notes = (notes_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1019 xstrdup(pws3_field_get_text(notes_field)) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1020
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1021 url_field = pws3_record_get_field(pws3_record, PWS3_RECORD_FIELD_URL);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1022 record->url = (url_field != NULL) ?
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1023 xstrdup(pws3_field_get_text(url_field)) : NULL;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1024
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1025 return (record);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1026 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1027
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1028 void
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1029 pwfile_destroy_record(struct record *record)
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1030 {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1031 if (record == NULL) {
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1032 return;
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1033 }
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1034
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1035 free(record->title);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1036 free(record->group);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1037 free(record->username);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1038 free(record->password);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1039 free(record->notes);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1040 free(record->url);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1041 free(record);
a7e41e1a79c8 Initial revision
Guido Berhoerster <guido+pwm@berhoerster.name>
parents:
diff changeset
1042 }