/* * Return true if specified fd maps to a path we're tracing. */ static int fdmatch(struct tcb *tcp, int fd) { const char *path = getfdpath(tcp, fd); return path && pathmatch(path); }
/* * This is a little odd, but it matches the default behavior of * gtar. In particular, 'a*b' will match 'foo/a1111/222b/bar' * */ static int match_exclusion(struct match *match, const char *pathname) { const char *p; if (*match->pattern == '*' || *match->pattern == '/') return (pathmatch(match->pattern, pathname) == 0); for (p = pathname; p != NULL; p = strchr(p, '/')) { if (*p == '/') p++; if (pathmatch(match->pattern, p) == 0) return (1); } return (0); }
/* * Return true if specified fd maps to a path we're tracing. */ static int fdmatch(struct tcb *tcp, int fd) { char path[PATH_MAX + 1]; int n = getfdpath(tcp, fd, path, sizeof(path)); return n >= 0 && pathmatch(path); }
/* * Return true if specified path (in user-space) matches. */ static int upathmatch(struct tcb *tcp, unsigned long upath) { char path[PATH_MAX + 1]; return umovestr(tcp, upath, sizeof path, path) > 0 && pathmatch(path); }
/* * Add a path to the set we're tracing. * Specifying NULL will delete all paths. */ static void storepath(const char *path) { unsigned i; if (pathmatch(path)) return; /* already in table */ i = num_selected++; paths_selected = realloc(paths_selected, num_selected * sizeof(paths_selected[0])); if (!paths_selected) die_out_of_memory(); paths_selected[i] = path; }
struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, const char *host, const char *path, bool secure) { struct Cookie *newco; struct Cookie *co; time_t now = time(NULL); struct Cookie *mainco=NULL; size_t matches = 0; if(!c || !c->cookies) return NULL; /* no cookie struct or no cookies in the struct */ co = c->cookies; while(co) { /* only process this cookie if it is not expired or had no expire date AND that if the cookie requires we're secure we must only continue if we are! */ if((!co->expires || (co->expires > now)) && (co->secure?secure:TRUE)) { /* now check if the domain is correct */ if(!co->domain || (co->tailmatch && tailmatch(co->domain, host)) || (!co->tailmatch && Curl_raw_equal(host, co->domain)) ) { /* the right part of the host matches the domain stuff in the cookie data */ /* now check the left part of the path with the cookies path requirement */ if(!co->spath || pathmatch(co->spath, path) ) { /* and now, we know this is a match and we should create an entry for the return-linked-list */ newco = malloc(sizeof(struct Cookie)); if(newco) { /* first, copy the whole source cookie: */ memcpy(newco, co, sizeof(struct Cookie)); /* then modify our next */ newco->next = mainco; /* point the main to us */ mainco = newco; matches++; } else { fail: /* failure, clear up the allocated chain and return NULL */ while(mainco) { co = mainco->next; free(mainco); mainco = co; } return NULL; } } } } co = co->next; } if(matches) { /* Now we need to make sure that if there is a name appearing more than once, the longest specified path version comes first. To make this the swiftest way, we just sort them all based on path length. */ struct Cookie **array; size_t i; /* alloc an array and store all cookie pointers */ array = malloc(sizeof(struct Cookie *) * matches); if(!array) goto fail; co = mainco; for(i=0; co; co = co->next) array[i++] = co; /* now sort the cookie pointers in path length order */ qsort(array, matches, sizeof(struct Cookie *), cookie_sort); /* remake the linked list order according to the new order */ mainco = array[0]; /* start here */ for(i=0; i<matches-1; i++) array[i]->next = array[i+1]; array[matches-1]->next = NULL; /* terminate the list */ free(array); /* remove the temporary data again */ } return mainco; /* return the new list */ }
/* * Again, mimic gtar: inclusions are always anchored (have to match * the beginning of the path) even though exclusions are not anchored. */ int match_inclusion(struct match *match, const char *pathname) { return (pathmatch(match->pattern, pathname) == 0); }
int pathmatch(const char *p, const char *s) { int r; int matched; const char *end; for (;;) { switch (*p) { case '[': ++p; end = p; /* Leading ']' is non-special. */ if (*end == ']') ++end; while (*end != '\0' && *end != ']') ++end; if (*end == '\0') { /* Unmatched '[' is plain char */ if (*s != '[') return (0); ++s; break; } matched = 0; while (!matched) { switch (*p) { case ']': if (p == end) return (0); else if (*s == ']') { p = end + 1; matched = 1; ++s; } else ++p; break; default: /* Trailing - is not special. */ if (p[1] == '-' && p + 2 < end) { if (p[0] <= *s && *s <= p[2]) { p = end + 1; matched = 1; ++s; } else p += 3; } else { if (*p == *s) { p = end + 1; matched = 1; ++s; } else ++p; } } } break; case '*': while (*p == '*') ++p; if (*p == '\0') return (1); while (*s) { r = pathmatch(p, s); if (r) return (r); ++s; } return (0); break; case '?': ++p; ++s; break; case '\0': return (*s == '\0'); break; default: if (*p != *s) return (0); ++p; ++s; break; } } }
struct Cookie *Curl_cookie_getlist(struct CookieInfo *c, const char *host, const char *path, bool secure) { struct Cookie *newco; struct Cookie *co; struct Cookie *mainco = NULL; size_t matches = 0; bool is_ip; const size_t myhash = cookiehash(host); if(!c || !c->cookies[myhash]) return NULL; /* no cookie struct or no cookies in the struct */ /* at first, remove expired cookies */ remove_expired(c); /* check if host is an IP(v4|v6) address */ is_ip = isip(host); co = c->cookies[myhash]; while(co) { /* if the cookie requires we're secure we must only continue if we are! */ if(co->secure?secure:TRUE) { /* now check if the domain is correct */ if(!co->domain || (co->tailmatch && !is_ip && tailmatch(co->domain, host)) || ((!co->tailmatch || is_ip) && strcasecompare(host, co->domain)) ) { /* the right part of the host matches the domain stuff in the cookie data */ /* now check the left part of the path with the cookies path requirement */ if(!co->spath || pathmatch(co->spath, path) ) { /* and now, we know this is a match and we should create an entry for the return-linked-list */ newco = dup_cookie(co); if(newco) { /* then modify our next */ newco->next = mainco; /* point the main to us */ mainco = newco; matches++; } else goto fail; } } } co = co->next; } if(matches) { /* Now we need to make sure that if there is a name appearing more than once, the longest specified path version comes first. To make this the swiftest way, we just sort them all based on path length. */ struct Cookie **array; size_t i; /* alloc an array and store all cookie pointers */ array = malloc(sizeof(struct Cookie *) * matches); if(!array) goto fail; co = mainco; for(i = 0; co; co = co->next) array[i++] = co; /* now sort the cookie pointers in path length order */ qsort(array, matches, sizeof(struct Cookie *), cookie_sort); /* remake the linked list order according to the new order */ mainco = array[0]; /* start here */ for(i = 0; i<matches-1; i++) array[i]->next = array[i + 1]; array[matches-1]->next = NULL; /* terminate the list */ free(array); /* remove the temporary data again */ } return mainco; /* return the new list */ fail: /* failure, clear up the allocated chain and return NULL */ Curl_cookie_freelist(mainco); return NULL; }