-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathurlEncoder.c
137 lines (123 loc) · 3.54 KB
/
urlEncoder.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
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <argp.h>
#define buffer_size 50
const char *argp_program_version = "URL encoder v1.0";
const char *argp_program_bug_address = "<ghostmhbr@gmail.com>";
static char doc[] = "simple URL encoder";
static char args_doc[] = "input";
static struct argp_option options[] = {
{.name = "output_file", .key = 'o', .arg = "FILE", .flags = 0, .doc = "output file instead of standard output. NOTE that if the output file exists, it will be overwritten"},
{.name = "input_file", .key = 'i', .arg = "FILE", .flags = 0, .doc = "input file instead of standard input"},
{.name = "escape_all", .key = 'a', .arg = 0, .flags = 0, .doc = "escape all characters including alphabet and digits"},
{.name = "delimiter", .key = 'd', .arg = "STRING", .flags = 0, .doc = "using STRING as delimiter between each character"},
{0}};
struct arguments
{
char *arg;
FILE *outputFile;
FILE *inputFile;
int escapeAll;
char *del;
};
static error_t parse_opt(int key, char *arg, struct argp_state *state)
{
struct arguments *arguments = state->input;
switch (key)
{
case 'o':
arguments->outputFile = fopen(arg, "w");
if (!arguments->outputFile)
{
perror("[-] Error opening output file");
exit(-1);
}
break;
case 'i':
arguments->inputFile = fopen(arg, "r");
if (!arguments->inputFile)
{
perror("[-] Error opening input file");
exit(-1);
}
break;
case 'a':
arguments->escapeAll = 1;
break;
case 'd':
arguments->del = arg;
break;
case ARGP_KEY_ARG:
if (state->arg_num > 1)
{
fprintf(stdout, "[-] Too many arguments\n");
argp_usage(state);
}
arguments->arg = arg;
break;
case ARGP_KEY_END:
if (state->arg_num < 1 && arguments->inputFile == NULL)
{
fprintf(stdout, "[-] Too few arguments\n");
argp_usage(state);
}
break;
default:
ARGP_ERR_UNKNOWN;
break;
}
return 0;
}
static struct argp argp = {
options, parse_opt, args_doc, doc};
int isAlNum(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9');
}
void writeOut(const char *const buffer, struct arguments args)
{
int i = 0;
char c = buffer[0];
while (c > 0)
{
if (args.escapeAll)
{
fprintf(args.outputFile, "%%%x", (int)c);
}
else
{
if (isAlNum(c))
{
fprintf(args.outputFile, "%c", c);
}
else
{
fprintf(args.outputFile, "%%%x", (int)c);
}
}
i++;
c = buffer[i];
if (c)
printf("%s", args.del);
}
}
int main(int argc, char **argv)
{
struct arguments arguments;
arguments.outputFile = stdout;
arguments.inputFile = NULL;
arguments.arg = NULL;
arguments.escapeAll = 0;
arguments.del = "";
char buffer[buffer_size];
argp_parse(&argp, argc, argv, 0, 0, &arguments);
if (arguments.inputFile)
while (fgets(buffer, buffer_size, arguments.inputFile))
writeOut(buffer, arguments);
else
writeOut(arguments.arg, arguments);
fprintf(arguments.outputFile, "\n");
return 0;
}