Permalink
Cannot retrieve contributors at this time
Name already in use
A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
meowmeow/main.c
Go to fileThis commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
141 lines (111 sloc)
2.59 KB
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* 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; | |
| } |