Browse code

Support streaming from stdin

Shawn Webb authored on 2014/01/15 01:43:49
Showing 1 changed files
... ...
@@ -10,6 +10,8 @@
10 10
 
11 11
 #define OPTS "e:p:n:N:H:h?"
12 12
 
13
+char *read_stream(void);
14
+
13 15
 void usage(char *name)
14 16
 {
15 17
     fprintf(stderr, "USAGE: %s -hHinp?\n", name);
... ...
@@ -19,6 +21,7 @@ void usage(char *name)
19 19
     fprintf(stderr, "    -n [FILE]\tSubmit a false negative (FN)\n");
20 20
     fprintf(stderr, "    -N [NAME]\tYour name (required)\n");
21 21
     fprintf(stderr, "    -p [FILE]\tSubmit a fase positive (FP)\n");
22
+    fprintf(stderr, "You must specify -n or -p. Both are mutually exclusive. Pass in - as the filename for stdin.\n");
22 23
     exit(0);
23 24
 }
24 25
 
... ...
@@ -30,8 +33,17 @@ int main(int argc, char *argv[])
30 30
     struct curl_httppost *post=NULL, *last=NULL;
31 31
     struct curl_slist *slist = NULL;
32 32
     char *type;
33
-    char *name=NULL, *email=NULL;
33
+    char *name=NULL, *email=NULL, *filename=NULL;
34 34
     struct cl_engine *engine;
35
+    int setURL=0, fromStream=0;
36
+
37
+    curl_global_init(CURL_GLOBAL_ALL);
38
+
39
+    curl = curl_easy_init();
40
+    if (!(curl)) {
41
+        fprintf(stderr, "ERROR: Could not initialize libcurl\n");
42
+        exit(1);
43
+    }
35 44
 
36 45
     while ((ch = my_getopt(argc, argv, OPTS)) > 0) {
37 46
         switch (ch) {
... ...
@@ -41,68 +53,126 @@ int main(int argc, char *argv[])
41 41
             case 'N':
42 42
                 name = optarg;
43 43
                 break;
44
+            case 'p':
45
+                if (setURL)
46
+                    usage(argv[0]);
47
+
48
+                filename = optarg;
49
+
50
+                curl_easy_setopt(curl, CURLOPT_URL, "http://cgi.clamav.net/sendfp.cgi");
51
+                setURL=1;
52
+                break;
53
+            case 'n':
54
+                if (setURL)
55
+                    usage(argv[0]);
56
+
57
+                filename = optarg;
58
+
59
+                curl_easy_setopt(curl, CURLOPT_URL, "http://cgi.clamav.net/sendmalware.cgi");
60
+                setURL=1;
61
+                break;
44 62
             case 'h':
45 63
             case '?':
64
+            default:
46 65
                 usage(argv[0]);
47 66
         }
48 67
     }
49 68
 
50
-    if (!(name) || !(email))
69
+    if (!(name) || !(email) || !(filename))
51 70
         usage(argv[0]);
52 71
 
53
-    /* Reset getopt */
54
-    optind = opterr = 1;
55
-    optopt = 0;
56
-    optarg = NULL;
57
-
58
-    curl_global_init(CURL_GLOBAL_ALL);
72
+    if (strlen(filename) == 1 && filename[0] == '-') {
73
+        filename = read_stream();
74
+        if (!(filename)) {
75
+            fprintf(stderr, "ERROR: Unable to read stream\n");
76
+            exit(1);
77
+        }
59 78
 
60
-    curl = curl_easy_init();
79
+        fromStream=1;
80
+    }
61 81
 
62 82
     slist = curl_slist_append(slist, "Expect:");
63 83
     curl_easy_setopt(curl, CURLOPT_HTTPHEADER, slist);
64 84
 
65
-    while ((ch = my_getopt(argc, argv, OPTS)) > 0) {
66
-        if (ch == 'p')
67
-            curl_easy_setopt(curl, CURLOPT_URL, "http://cgi.clamav.net/sendfp.cgi");
68
-        else if (ch == 'n')
69
-            curl_easy_setopt(curl, CURLOPT_URL, "http://cgi.clamav.net/sendmalware.cgi");
70
-        else
71
-            continue;
85
+    if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendername", CURLFORM_COPYCONTENTS, name, CURLFORM_END)) {
86
+        fprintf(stderr, "Unable to specify name in libcurl form for file %s\n", optarg);
87
+        goto end;
88
+    }
72 89
 
73
-        if ((post))
74
-            curl_formfree(post);
90
+    if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "email", CURLFORM_COPYCONTENTS, email, CURLFORM_END)) {
91
+        fprintf(stderr, "Unable to specify email in libcurl form for file %s\n", optarg);
92
+        goto end;
93
+    }
75 94
 
76
-        post = last = NULL;
95
+    if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, filename, CURLFORM_END)) {
96
+        fprintf(stderr, "Unable to specify file path in libcurl form for file %s\n", optarg);
97
+        goto end;
98
+    }
77 99
 
78
-        if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "sendername", CURLFORM_COPYCONTENTS, name, CURLFORM_END)) {
79
-            fprintf(stderr, "Unable to specify name in libcurl form for file %s\n", optarg);
80
-            break;
81
-        }
100
+    curl_formadd(&post, &last, CURLFORM_COPYNAME, "action", CURLFORM_COPYCONTENTS, "submit", CURLFORM_END);
101
+    curl_formadd(&post, &last, CURLFORM_COPYNAME, "privacy", CURLFORM_COPYCONTENTS, "yes", CURLFORM_END);
102
+    curl_formadd(&post, &last, CURLFORM_COPYNAME, "notify", CURLFORM_COPYCONTENTS, "yes", CURLFORM_END);
82 103
 
83
-        if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "email", CURLFORM_COPYCONTENTS, email, CURLFORM_END)) {
84
-            fprintf(stderr, "Unable to specify email in libcurl form for file %s\n", optarg);
85
-            break;
86
-        }
104
+    curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
105
+    res = curl_easy_perform(curl);
87 106
 
88
-        if (curl_formadd(&post, &last, CURLFORM_COPYNAME, "file", CURLFORM_FILE, optarg, CURLFORM_END)) {
89
-            fprintf(stderr, "Unable to specify file path in libcurl form for file %s\n", optarg);
90
-            break;
91
-        }
107
+    if (res) {
108
+        fprintf(stderr, "Error: %s\n", curl_easy_strerror(res));
109
+    }
92 110
 
93
-        curl_formadd(&post, &last, CURLFORM_COPYNAME, "action", CURLFORM_COPYCONTENTS, "submit", CURLFORM_END);
94
-        curl_formadd(&post, &last, CURLFORM_COPYNAME, "privacy", CURLFORM_COPYCONTENTS, "yes", CURLFORM_END);
95
-        curl_formadd(&post, &last, CURLFORM_COPYNAME, "notify", CURLFORM_COPYCONTENTS, "yes", CURLFORM_END);
111
+end:
112
+    curl_easy_cleanup(curl);
113
+    if (fromStream) {
114
+        remove(filename);
115
+        free(filename);
116
+    }
96 117
 
97
-        curl_easy_setopt(curl, CURLOPT_HTTPPOST, post);
98
-        res = curl_easy_perform(curl);
118
+    return 0;
119
+}
99 120
 
100
-        if (res) {
101
-            fprintf(stderr, "Error: %s\n", curl_easy_strerror(res));
121
+char *read_stream(void)
122
+{
123
+    char *filename;
124
+    char buf[512];
125
+    size_t nread, nwritten;
126
+    FILE *fp;
127
+
128
+    filename = cli_gentemp(NULL);
129
+    if (!(filename)) {
130
+        return NULL;
131
+    }
132
+
133
+    fp = fopen(filename, "w");
134
+    if (!(fp)) {
135
+        free(filename);
136
+        return NULL;
137
+    }
138
+
139
+    while (!feof(stdin)) {
140
+        nwritten = 0;
141
+        nread = fread(buf, 1, sizeof(buf), stdin);
142
+        if (nread == 0) {
143
+            fclose(fp);
144
+            remove(filename);
145
+            free(filename);
146
+            return NULL;
147
+        }
148
+
149
+        while (nwritten < nread) {
150
+            size_t i;
151
+            i = fwrite(buf, 1, nread, fp);
152
+            if (i == 0) {
153
+                fclose(fp);
154
+                remove(filename);
155
+                free(filename);
156
+                return NULL;
157
+            }
158
+
159
+            nwritten += i;
102 160
         }
103 161
     }
104 162
 
105
-    curl_easy_cleanup(curl);
163
+    fclose(fp);
106 164
 
107
-    return 0;
165
+    return filename;
108 166
 }