]> git.cworth.org Git - mnemon/blob - mnemon.c
Initial commit of mnemon
[mnemon] / mnemon.c
1 /*
2  * Copyright © 2006 Carl Worth
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2, or (at your option)
7  * any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA."
17  */
18
19 /* for asprintf */
20 #define _GNU_SOURCE
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <stdarg.h>
24
25 #include <sys/types.h>
26 #include <dirent.h>
27 #include <errno.h>
28 #include <string.h>
29
30 typedef struct _mnemon {
31     int dummy;
32 } mnemon_t;
33
34 typedef struct _ic {
35     int bin;
36     char *challenge;
37     char *response;
38 } ic_t;
39
40 static void
41 xasprintf (char **strp, const char *fmt, ...)
42 {
43     va_list ap;
44     int ret;
45
46     va_start (ap, fmt);
47     ret = vasprintf (strp, fmt, ap);
48     va_end (ap);
49
50     if (ret < 0) {
51         fprintf (stderr, "Error: out of memory\n");
52         exit (1);
53     }
54 }
55
56 static void
57 chomp (char *s)
58 {
59     int len = strlen (s);
60     if (len == 0)
61         return;
62     if (s[len - 1] == '\n')
63         s[len - 1] = '\0';
64 }
65
66 static void
67 mnemon_load_from_file (mnemon_t *mnemon,
68                        char *path)
69 {
70     FILE *file;
71     char *line = NULL, *end;
72     size_t line_size = 0;
73     ssize_t bytes_read;
74     int line_count = 0;
75
76     file = fopen (path, "r");
77     if (file == NULL) {
78         fprintf (stderr, "Error: Failed to open %s: %s\n",
79                  path, strerror (errno));
80         exit (1);
81     }
82
83     while (1) {
84         ic_t ic;
85
86         /* Read bin number (ignoring blank separator lines) */
87         do {
88             bytes_read = getline (&line, &line_size, file);
89             if (bytes_read == -1)
90                 goto END_OF_FILE;
91             line_count++;
92             chomp (line);
93         } while (*line == '\0');
94
95         ic.bin = strtol (line, &end, 10);
96         if (*end != '\0') {
97             fprintf (stderr, "Failed to parse bin number from \"%s\" at %s:%d\n",
98                      line, path, line_count);
99             exit (1);
100         }
101
102         /* Read challenge */
103         bytes_read = getline (&line, &line_size, file);
104         if (bytes_read == -1)
105             break;
106         line_count++;
107         chomp (line);
108         ic.challenge = strdup (line);
109
110         /* Read response */
111         bytes_read = getline (&line, &line_size, file);
112         if (bytes_read == -1)
113             break;
114         line_count++;
115         chomp (line);
116         ic.response = strdup (line);
117
118         /* XXX: Add ic to mnemon here */
119         printf ("%d: %s => %s\n", ic.bin, ic.challenge, ic.response);
120         free (ic.challenge);
121         free (ic.response);
122     }
123   END_OF_FILE:
124
125     free (line);
126     fclose (file);
127 }
128
129 static void
130 mnemon_load_from_directory_recursive (mnemon_t *mnemon,
131                                       char *path)
132 {
133     DIR *dir;
134     struct dirent *dirent;
135     char *child_path;
136
137     dir = opendir (path);
138     if (dir == NULL) {
139         fprintf (stderr, "Error: Failed to open directory %s: %s\n",
140                  path, strerror (errno));
141         exit (1);
142     }
143
144     while (1) {
145         dirent = readdir (dir);
146         if (dirent == NULL)
147             break;
148
149         xasprintf (&child_path, "%s/%s", path, dirent->d_name);
150         if (dirent->d_type == DT_DIR) {
151             if (strcmp (dirent->d_name, ".") &&
152                 strcmp (dirent->d_name, ".."))
153             {
154                 mnemon_load_from_directory_recursive (mnemon, child_path);
155             }
156         } else if (dirent->d_type == DT_REG) {
157             /* Ignore files matching *~, (yes, this shouldn't be
158              * hard-coded in such an ad-hoc way, but there you go. */
159             if (child_path[strlen(child_path)-1] != '~')
160                 mnemon_load_from_file (mnemon, child_path);
161         } else {
162             fprintf (stderr, "Warning: Ignoring file %s\n", child_path);
163         }
164
165         free (child_path);
166     }
167
168     closedir (dir);
169 }
170
171 static void
172 mnemon_init (mnemon_t *mnemon)
173 {
174     char *dot_mnemon;
175     char *home;
176
177     home = getenv ("HOME");
178     if (home == NULL)
179         home = "";
180
181     xasprintf (&dot_mnemon, "%s/.mnemon", getenv ("HOME"));
182
183     mnemon_load_from_directory_recursive (mnemon, dot_mnemon);
184
185     free (dot_mnemon);
186 }
187
188 int
189 main (int argc, char *argv[])
190 {
191     mnemon_t mnemon;
192
193     mnemon_init (&mnemon);
194
195     return 0;
196 }