+static void get_arg(char *buf, int buf_size, const char **pp)
+{
+ const char *p;
+ char *q;
+ int quote;
+
+ p = *pp;
+ while (isspace(*p)) p++;
+ q = buf;
+ quote = 0;
+ if (*p == '\"' || *p == '\'')
+ quote = *p++;
+ for(;;) {
+ if (quote) {
+ if (*p == quote)
+ break;
+ } else {
+ if (isspace(*p))
+ break;
+ }
+ if (*p == '\0')
+ break;
+ if ((q - buf) < buf_size - 1)
+ *q++ = *p;
+ p++;
+ }
+ *q = '\0';
+ if (quote && *p == quote)
+ p++;
+ *pp = p;
+}
+
+static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_acl,
+ const char *p, const char *filename, int line_num)
+{
+ char arg[1024];
+ IPAddressACL acl;
+ int errors = 0;
+
+ get_arg(arg, sizeof(arg), &p);
+ if (strcasecmp(arg, "allow") == 0)
+ acl.action = IP_ALLOW;
+ else if (strcasecmp(arg, "deny") == 0)
+ acl.action = IP_DENY;
+ else {
+ fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
+ filename, line_num, arg);
+ errors++;
+ }
+
+ get_arg(arg, sizeof(arg), &p);
+
+ if (resolve_host(&acl.first, arg) != 0) {
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
+ filename, line_num, arg);
+ errors++;
+ } else
+ acl.last = acl.first;
+
+ get_arg(arg, sizeof(arg), &p);
+
+ if (arg[0]) {
+ if (resolve_host(&acl.last, arg) != 0) {
+ fprintf(stderr, "%s:%d: ACL refers to invalid host or ip address '%s'\n",
+ filename, line_num, arg);
+ errors++;
+ }
+ }
+
+ if (!errors) {
+ IPAddressACL *nacl = av_mallocz(sizeof(*nacl));
+ IPAddressACL **naclp = 0;
+
+ acl.next = 0;
+ *nacl = acl;
+
+ if (stream)
+ naclp = &stream->acl;
+ else if (feed)
+ naclp = &feed->acl;
+ else if (ext_acl)
+ naclp = &ext_acl;
+ else {
+ fprintf(stderr, "%s:%d: ACL found not in <stream> or <feed>\n",
+ filename, line_num);
+ errors++;
+ }
+
+ if (naclp) {
+ while (*naclp)
+ naclp = &(*naclp)->next;
+
+ *naclp = nacl;
+ }
+ }
+}
+
+
+static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
+{
+ FILE* f;
+ char line[1024];
+ char cmd[1024];
+ IPAddressACL *acl = NULL;
+ int line_num = 0;
+ const char *p;
+
+ f = fopen(stream->dynamic_acl, "r");
+ if (!f) {
+ perror(stream->dynamic_acl);
+ return NULL;
+ }
+
+ acl = av_mallocz(sizeof(IPAddressACL));
+
+ /* Build ACL */
+ for(;;) {
+ if (fgets(line, sizeof(line), f) == NULL)
+ break;
+ line_num++;
+ p = line;
+ while (isspace(*p))
+ p++;
+ if (*p == '\0' || *p == '#')
+ continue;
+ get_arg(cmd, sizeof(cmd), &p);
+
+ if (!strcasecmp(cmd, "ACL"))
+ parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
+ }
+ fclose(f);
+ return acl;
+}
+
+
+static void free_acl_list(IPAddressACL *in_acl)
+{
+ IPAddressACL *pacl,*pacl2;
+
+ pacl = in_acl;
+ while(pacl) {
+ pacl2 = pacl;
+ pacl = pacl->next;
+ av_freep(pacl2);
+ }
+}
+
+static int validate_acl_list(IPAddressACL *in_acl, HTTPContext *c)