char *t, *u, *v, *w, *url;
char *t, *u, *url;
static int f_process_imap(struct request *r, FILE *fp){	char input[PATHLEN], default_url[PATHLEN];	struct token tok[2 * MAXVERTS + 2];	point testpoint, pointarray[MAXVERTS];	long dist, mindist;	int i, k, l, line, sawpoint, text;	char *t, *u, *v, *w, *url;	const char *status;	testpoint.x = 0;	testpoint.y = 0;	text = 1;	if (r->args) {		t = strchr(r->args, ',');		if (t == 0 || *++t == 0)			return 400;		testpoint.x = atol(r->args);		testpoint.y = atol(t);		if (testpoint.x || testpoint.y)			text = 0;	}	line = 0;	sawpoint = 0;	*default_url = 0;	mindist = 0;	status = 0;	url = 0;	while (fgetline(input, PATHLEN, fp) != -1) {		if (++line > MAXLINES) {			status = "too many lines";			break;		}		l = separate(input, tok, 2 * MAXVERTS + 2);		if (l < 2)			continue;		if (l % 2) {			status = "odd number of coords";			break;		}		t = input + tok[0].pos;		t[tok[0].len] = 0;		u = input + tok[1].pos;		u[tok[1].len] = 0;		i = 2;		k = 0;		while (i < l) {			pointarray[k].x = atol(input + tok[i++].pos);			pointarray[k++].y = atol(input + tok[i++].pos);		}		if (k >= MAXVERTS) {			status = "too many points";			break;		}		if (!strcmp(t, "default"))			strcpy(default_url, u);		else if (!strcmp(t, "text")) {			if (text) {				url = u;				break;			}		} else if (!strcmp(t, "point")) {			if (k < 1) {				status = "no point";				break;			}			if (text == 0) {				dist = sqr(pointarray[0].x - testpoint.x) + sqr(pointarray[0].y - testpoint.y);				if (sawpoint == 0 || dist < mindist) {					sawpoint = 1;					mindist = dist;					strcpy(default_url, u);				}			}		} else if (!strcmp(t, "rect")) {			if (k < 2) {				status = "too few rect points";				break;			}			if (text == 0 && pointinrect(testpoint, pointarray)) {				url = u;				break;			}		} else if (!strcmp(t, "circle")) {			if (k < 2) {				status = "too few circle points";				break;			}			if (text == 0 && pointincircle(testpoint, pointarray)) {				url = u;				break;			}		} else if (!strcmp(t, "spoly")) {			if (k < 3) {				status = "too few spoly points";				break;			}			if (text == 0 && pointinpoly(testpoint, pointarray, k)) {				url = u;				break;			}		} else if (!strcmp(t, "poly")) {			if (k < 3) {				status = "too few poly points";				break;			}			if (text == 0 && pointinpoly(testpoint, pointarray, k) & 1) {				url = u;				break;			}		} else {			status = "unknown keyword";			break;		}	}	if (status) {		log_d("imagemap: error on line %d of %s", line, r->path_translated);		log_d("imagemap: %s", status);		return 500;	}	if (url || (*default_url && (url = default_url))) {		l = snprintf(r->newloc, PATHLEN, "%s", url);		if (l >= PATHLEN) {			log_d("imagemap: url too large");			return 500;		}		r->location = r->newloc;		return 302;	}	return 204;}