pacparser  1.3.7
About: pacparser is a library to parse Proxy Auto-Config (PAC) files (incl. a pactester).
  Fossies Dox: pacparser-1.3.7.tar.gz  ("inofficial" and yet experimental doxygen-generated source code documentation)  

pactester.c
Go to the documentation of this file.
1 // Copyright (C) 2008 Manu Garg.
2 // Author: Manu Garg <manugarg@gmail.com>
3 //
4 // This file implements pactester using pacparser.
5 //
6 // pacparser is a library that provides methods to parse proxy auto-config
7 // (PAC) files. Please read README file included with this package for more
8 // information about this library.
9 //
10 // pacparser is free software; you can redistribute it and/or
11 // modify it under the terms of the GNU Lesser General Public
12 // License as published by the Free Software Foundation; either
13 // version 3 of the License, or (at your option) any later version.
14 
15 // pacparser is distributed in the hope that it will be useful,
16 // but WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23 
24 #include "pacparser.h"
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <unistd.h>
29 
30 #define STREQ(s1, s2) (strcmp((s1), (s2)) == 0)
31 
32 #define LINEMAX 4096 // Max length of any line read from text files (4 KiB)
33 #define PACMAX (1024 * 1024) // Max size of the PAC script (1 MiB)
34 
35 void usage(const char *progname)
36 {
37  fprintf(stderr, "\nUsage: %s <-p pacfile> <-u url> [-h host] "
38  "[-c client_ip] [-e]", progname);
39  fprintf(stderr, "\n %s <-p pacfile> <-f urlslist> "
40  "[-c client_ip] [-e]\n", progname);
41  fprintf(stderr, "\nOptions:\n");
42  fprintf(stderr, " -p pacfile : PAC file to test (specify '-' to read "
43  "from standard input)\n");
44  fprintf(stderr, " -u url : URL to test for\n");
45  fprintf(stderr, " -h host : Host part of the URL\n");
46  fprintf(stderr, " -c client_ip : client IP address (as returned by "
47  "myIpAddres() function\n");
48  fprintf(stderr, " in PAC files), defaults to IP address "
49  "on which it is running.\n");
50  fprintf(stderr, " -e : Deprecated: IPv6 extensions are enabled"
51  "by default now.\n");
52  fprintf(stderr, " -f urlslist : a file containing list of URLs to be "
53  "tested.\n");
54  fprintf(stderr, " -v : print version and exit\n");
55  exit(1);
56 }
57 
58 char *get_host_from_url(const char *url)
59 {
60  // copy url to a pointer that we'll use to seek through the string.
61  char *p = strdup(url);
62  // Move to :
63  while (*p != ':' && *p != '\0')
64  p++;
65  if (p[0] == '\0'|| // We reached end without hitting :
66  p[1] != '/' || p[2] != '/' // Next two characters are not //
67  ) {
68  fprintf(stderr, "pactester.c: Not a proper URL\n");
69  return NULL;
70  }
71  p = p + 3; // Get past '://'
72  // Host part starts from here.
73  char *host = p;
74  if (*p == '\0' || *p == '/' || *p == ':') { // If host part is null.
75  fprintf(stderr, "pactester.c: Not a proper URL\n");
76  return NULL;
77  }
78  // Seek until next /, : or end of string.
79  while (*p != '/' && *p != ':' && *p != '\0')
80  p++;
81  *p = '\0';
82  return host;
83 }
84 
85 int main(int argc, char* argv[])
86 {
87  char *pacfile = NULL, *url = NULL, *host = NULL, *urlslist = NULL,
88  *client_ip = NULL;
89 
90  if (argv[1] && (STREQ(argv[1], "--help") || STREQ(argv[1], "--helpshort"))) {
91  usage(argv[0]);
92  }
93 
94  signed char c;
95  while ((c = getopt(argc, argv, "evp:u:h:f:c:")) != -1)
96  switch (c)
97  {
98  case 'v':
99  printf("%s\n", pacparser_version());
100  return 0;
101  case 'p':
102  pacfile = optarg;
103  break;
104  case 'u':
105  url = optarg;
106  break;
107  case 'h':
108  host = optarg;
109  break;
110  case 'f':
111  urlslist = optarg;
112  break;
113  case 'c':
114  client_ip = optarg;
115  break;
116  case 'e':
117  break;
118  case '?':
119  usage(argv[0]);
120  /* fallthrough */
121  default:
122  abort ();
123  }
124 
125  if (!pacfile) {
126  fprintf(stderr, "pactester.c: You didn't specify the PAC file\n");
127  usage(argv[0]);
128  }
129  if (!url && !urlslist) {
130  fprintf(stderr, "pactester.c: You didn't specify the URL\n");
131  usage(argv[0]);
132  }
133 
134  // Initialize pacparser.
135  if (!pacparser_init()) {
136  fprintf(stderr, "pactester.c: Could not initialize pacparser\n");
137  return 1;
138  }
139 
140  // Read pacfile from stdin.
141  if (STREQ("-", pacfile)) {
142  char *script;
143  size_t script_size = 1; // for the null terminator
144  char buffer[LINEMAX];
145 
146  script = (char *) malloc(sizeof(char) * LINEMAX);
147  if (script == NULL) {
148  perror("pactetser.c: Failed to allocate the memory for the script");
149  return 1;
150  }
151  script[0] = '\0'; // Null terminate to prepare for strcat
152 
153  while (fgets(buffer, LINEMAX, stdin)) {
154  if (strlen(buffer) == 0)
155  break;
156  char *old = script;
157  script_size += strlen(buffer);
158  if (script_size > PACMAX) {
159  fprintf(stderr, "Input file is too big. Maximum allowed size is: %d",
160  PACMAX);
161  free(script);
162  return 1;
163  }
164  script = realloc(script, script_size);
165  if (script == NULL) {
166  perror("pactester.c: Failed to allocate the memory for the script");
167  free(old);
168  return 1;
169  }
170  strcat(script, buffer);
171  }
172 
173  if (ferror(stdin)) {
174  free(script);
175  perror("pactester.c: Error reading from stdin");
176  return 1;
177  }
178 
179  if (!pacparser_parse_pac_string(script)) {
180  fprintf(stderr, "pactester.c: Could not parse the pac script: %s\n",
181  script);
182  free(script);
184  return 1;
185  }
186  free(script);
187  }
188  else {
189  if (!pacparser_parse_pac_file(pacfile)) {
190  fprintf(stderr, "pactester.c: Could not parse the pac file: %s\n",
191  pacfile);
193  return 1;
194  }
195  }
196 
197  if (client_ip)
198  pacparser_setmyip(client_ip);
199 
200  char *proxy;
201 
202  if (url) {
203  // If the host was not explicitly given, get it from the URL.
204  // If that fails, return with error (the get_host_from_url()
205  // function will print a proper error message in that case).
206  host = host ? host: get_host_from_url(url);
207  if (!host) {
208  return 1;
209  }
210  proxy = pacparser_find_proxy(url, host);
211  if (proxy == NULL) {
212  fprintf(stderr, "pactester.c: %s %s.\n",
213  "Problem in finding proxy for", url);
215  return 1;
216  }
217  printf("%s\n", proxy);
218  }
219 
220  else if (urlslist) {
221  char line[LINEMAX];
222  FILE *fp;
223  if (!(fp = fopen(urlslist, "r"))) {
224  fprintf(stderr, "pactester.c: Could not open urlslist: %s", urlslist);
226  return 1;
227  }
228  while (fgets(line, sizeof(line), fp)) {
229  char *url = line;
230  // Remove spaces from the beginning.
231  while (*url == ' ' || *url == '\t')
232  url++;
233  // Skip comment lines.
234  if (*url == '#') {
235  printf("%s", url);
236  continue;
237  }
238  char *urlend = url;
239  while (*urlend != '\r' && *urlend != '\n' && *urlend != '\0' &&
240  *urlend != ' ' && *urlend != '\t')
241  urlend++; // keep moving till you hit space or end of string
242  *urlend = '\0';
243  if (!(host = get_host_from_url(url)) )
244  continue;
245  proxy = NULL;
246  proxy = pacparser_find_proxy(url, host);
247  if (proxy == NULL) {
248  fprintf(stderr, "pactester.c: %s %s.\n",
249  "Problem in finding proxy for", url);
251  return 1;
252  }
253  if (proxy)
254  printf("%s : %s\n", url, proxy);
255  }
256  fclose(fp);
257  }
258 
260  return 0;
261 }
STREQ
#define STREQ(s1, s2)
Definition: pactester.c:30
get_host_from_url
char * get_host_from_url(const char *url)
Definition: pactester.c:58
pacparser_parse_pac_file
int pacparser_parse_pac_file(const char *pacfile)
Parses the given PAC file.
Definition: pacparser.c:373
pacparser_version
char * pacparser_version(void)
Returns pacparser version.
Definition: pacparser.c:528
PACMAX
#define PACMAX
Definition: pactester.c:33
pacparser_setmyip
void pacparser_setmyip(const char *ip)
Sets my IP address.
Definition: pacparser.c:265
pacparser.h
pacparser_init
int pacparser_init()
Initializes pac parser.
Definition: pacparser.c:288
pacparser_cleanup
void pacparser_cleanup()
Destroys JavaSctipt context.
Definition: pacparser.c:468
pacparser_find_proxy
char * pacparser_find_proxy(const char *url, const char *host)
Finds proxy for the given URL and Host.
Definition: pacparser.c:409
main
int main(int argc, char *argv[])
Definition: pactester.c:85
pacparser_parse_pac_string
int pacparser_parse_pac_string(const char *script)
Parses the given PAC script string.
Definition: pacparser.c:344
usage
void usage(const char *progname)
Definition: pactester.c:35
LINEMAX
#define LINEMAX
Definition: pactester.c:32