-
Notifications
You must be signed in to change notification settings - Fork 5
/
main.c
141 lines (111 loc) · 2.59 KB
/
main.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* main.c - MeowMeow, a stream encoder/decoder */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <libgen.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include "main.h"
#include "mmencode.h"
#include "mmdecode.h"
extern char *optarg;
extern int optopt;
extern int opterr;
extern int opterr;
#define OPTARG "i:o:hV"
#define MM_OP_INVALID 0
#define MM_OP_ENCODE 1
#define MM_OP_DECODE 2
int usage(char *, int);
int pick_operation(char *);
int main(int argc, char *argv[])
{
options_t options = OPTIONS_INIT;
int retval = -1;
int codec_op = MM_OP_INVALID;
int opt;
opterr = 0;
if ((codec_op = pick_operation(argv[0])) == MM_OP_INVALID) {
errno = EINVAL;
perror("meow/unmeow argv[0] unrecognized!");
exit(-1);
/* NOTREACHED */
}
while( (opt=getopt(argc, argv, OPTARG)) != EOF)
switch(opt) {
case 'i':
/* XXX handle "-" explicitly as stdin */
if (!(options.in_stream = fopen(optarg, "r"))) {
perror("Error opening input stream");
exit(-1);
/* NOTREACHED */
}
break;
case 'o':
/* XXX handle "-" explicitly as stdout */
if (!(options.out_stream = fopen(optarg, "w"))) {
perror("Error opening output stream");
exit(-1);
/* NOTREACHED */
}
break;
case 'V':
printf("%s version %s\n",
basename(argv[0]),
MEOWMEOW_VERSION);
exit(0);
/* NOTREACHED */
break;
case '?':
case 'h':
default:
usage(basename(argv[0]), optopt);
break;
}
switch(codec_op) {
case MM_OP_ENCODE:
retval = mm_encode(options.in_stream, options.out_stream);
break;
case MM_OP_DECODE:
retval = mm_decode(options.in_stream, options.out_stream);
break;
default:
retval = -1;
errno = EINVAL;
fprintf(stderr, "Impossible state: %s codec=%d\n", argv[0], codec_op);
break;
}
if (retval < 0) {
perror("codec failed");
}
return retval;
}
int usage(char *argv0, int opt)
{
if (!argv0) {
errno = EINVAL;
perror("main:usage called with NULL argv[0]");
exit(-1);
}
fprintf(stderr, "usage: %s [-i input] [-o output] [-V]\n",
basename(argv0));
if (opt != '?')
fprintf(stderr, "unknown option: \"%c\"\n", opt);
exit(-1);
/* NOTREACHED */
}
int pick_operation(char *argv0)
{
char *name;
if (!argv0) {
errno = EINVAL;
return MM_OP_INVALID;
}
name = basename(argv0);
if (strncmp(name, CMD_MEOW, strlen(CMD_MEOW)) == 0)
return MM_OP_ENCODE;
if (strncmp(name, CMD_UNMEOW, strlen(CMD_UNMEOW)) == 0)
return MM_OP_DECODE;
return MM_OP_INVALID;
}