Factor out open_offset_file() from read_offset().
[easyotp.git] / libotp.c
blob2fba3dcf6fc7ff8fdc3c67d8b9e1639337b9c1c1
1 /** Practical One-time Pad Library
3 * Created:20080514
4 * By Jeff Connelly
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <sysexits.h>
10 #include <string.h>
12 #define MARKER_TO "to:"
13 #define MARKER_BEGIN "--EMOTP_BEGIN--"
14 #define MARKER_END "--EMOTP_END--"
16 #define OFFSET_FILE_EXTENSION ".off"
17 #define OFFSET_SIZE 11 /* strlen("4294967296") + 1 */
19 /** Packaged up encrypted message, ready for transport. */
20 typedef struct _PACKAGE {
21 unsigned long offset;
22 char *pad_name;
23 char *cipher_text;
24 } PACKAGE;
26 typedef struct _PAD {
27 char *local_filename;
28 char *name;
29 unsigned long offset;
30 FILE *fp;
31 struct _PAD *next;
32 } PAD;
34 PAD *pads = NULL;
36 /** Show a list of all loaded pads. */
37 void show_pads()
39 PAD *p;
41 for (p = pads; p; p = p->next) {
42 printf("Pad: %s: %s\n", p->name, p->local_filename);
46 /** Open a companion offset file for given pad. Caller must close. */
47 FILE *open_offset_file(PAD *p)
49 FILE *ofp;
50 char *offset_filename;
51 size_t filename_length;
53 /* Offset is stored in a separate file; pad plus OFFSET_FILE_NAME_EXTENSION. */
54 filename_length = strlen(p->local_filename) + strlen(OFFSET_FILE_EXTENSION) + 1;
55 offset_filename = malloc(filename_length);
56 if (!offset_filename) {
57 perror("malloc");
58 exit(EX_UNAVAILABLE);
60 snprintf(offset_filename, filename_length, "%s" OFFSET_FILE_EXTENSION, p->local_filename);
62 /* Read offset from file. */
63 ofp = fopen(offset_filename, "rt");
64 if (!ofp) {
65 fprintf(stderr, "opening offset file %s failed\n", offset_filename);
66 perror("fopen");
67 free(offset_filename);
68 exit(EX_IOERR);
70 free(offset_filename);
72 return ofp;
75 /** Read the pad offset of a given pad. */
76 unsigned long read_offset(PAD *p)
78 FILE *ofp;
79 char buffer[OFFSET_SIZE];
80 unsigned long offset;
82 ofp = open_offset_file(p);
84 memset(buffer, 0, OFFSET_SIZE);
85 if (fread(buffer, 1, OFFSET_SIZE - 1, ofp) < 1) {
86 fprintf(stderr, "could not read offset file for %s\n", p->local_filename);
87 exit(EX_IOERR);
90 fclose(ofp);
92 /* We finally got it! */
93 offset = atol(buffer);
95 return offset;
98 void write_offset(unsigned long offset)
102 /** Load a pad file from disk, adding to 'pads' global. */
103 void load_pad(char *local_filename)
105 FILE *fp;
106 PAD *new_pad;
108 fp = fopen("/Volumes/Not Backed Up/otp/otp-dazzlement", "rb");
109 if (!fp) {
110 perror("fopen");
111 exit(EXIT_FAILURE);
114 new_pad = malloc(sizeof(PAD));
115 if (!new_pad) {
116 perror("malloc");
117 exit(EX_UNAVAILABLE);
120 new_pad->local_filename = strdup(local_filename);
121 new_pad->name = strdup("dc"); /* TODO */
122 new_pad->offset = -1; /* TODO */
123 new_pad->fp = fp;
124 new_pad->next = NULL;
126 /* Add to linked list. */
127 if (!pads) {
128 pads = new_pad;
129 } else {
130 PAD *p, *tail;
132 /* Find tail */
133 for (p = pads; p; p = p->next)
134 tail = p;
135 tail->next = new_pad;
139 /** Close all pads and free allocated memory. */
140 void free_pads()
142 PAD *p, *next;
144 for (p = pads; p; p = next) {
145 free(p->name);
146 free(p->local_filename);
147 fclose(p->fp);
148 next = p->next;
149 free(p);
153 int main()
155 load_pad("/Volumes/Not Backed Up/otp/otp-dazzlement");
156 load_pad("/Volumes/Not Backed Up/otp/otp-dazzlement");
157 load_pad("/Volumes/Not Backed Up/otp/otp-dazzlement");
159 printf("offset=%ld\n", read_offset(pads));
161 show_pads();
162 free_pads();
164 return 0;