Beispiel #1
0
int main(int argc, char **argv)
{
    char input[MAXLINE], *mapname, def[MAXLINE], conf[MAXLINE], errstr[MAXLINE];
    double testpoint[2], pointarray[MAXVERTS][2];
    int i, j, k;
    FILE *fp;
    char *t;
    double dist, mindist;
    int sawpoint = 0;
    
    if (argc != 2)
        servererr("Wrong number of arguments, client may not support ISMAP.");
    mapname=getenv("PATH_INFO");

    if((!mapname) || (!mapname[0]))
        servererr("No map name given. Please read the <A HREF=\"http://hoohoo.ncsa.uiuc.edu/docs/tutorials/imagemapping.html\">instructions</A>.<P>");


    mapname++;
    if(!(t = strchr(argv[1],',')))
        servererr("Your client doesn't support image mapping properly.");
    *t++ = '\0';
    testpoint[X] = (double) atoi(argv[1]);
    testpoint[Y] = (double) atoi(t);

    /*
     * if the mapname contains a '/', it represents a unix path -
     * we get the translated path, and skip reading the configuration file.
     */
    if (strchr(mapname,'/')) {
      strcpy(conf,getenv("PATH_TRANSLATED"));
      goto openconf;
    }
    
    if ((fp = fopen(CONF_FILE, "r")) == NULL){
      /* Assume new style request if CONF_FILE doesn't exist
       */
       goto openconf;
    }

    while(!(mygetline(input,MAXLINE,fp))) {
        char confname[MAXLINE];
        if((input[0] == '#') || (!input[0]))
            continue;
        for(i=0;isname(input[i]) && (input[i] != ':');i++)
            confname[i] = input[i];
        confname[i] = '\0';
        if(!strcmp(confname,mapname))
            goto found;
    }
    /*
     * if mapname was not found in the configuration file, it still
     * might represent a file in the server root directory -
     * we get the translated path, and check to see if a file of that
     * name exists, jumping to the opening of the map file if it does.
     */
    if(feof(fp)) {
      struct stat sbuf;
      strcpy(conf,getenv("PATH_TRANSLATED"));
      if (!stat(conf,&sbuf) && ((sbuf.st_mode & S_IFMT) == S_IFREG))
	goto openconf;
      else
	servererr("Map not found in configuration file.");
    }
    
  found:
    fclose(fp);
    while(isspace(input[i]) || input[i] == ':') ++i;

    for(j=0;input[i] && isname(input[i]);++i,++j)
        conf[j] = input[i];
    conf[j] = '\0';

  openconf:
    if(!(fp=fopen(conf,"r"))){
	sprintf(errstr, "Couldn't open configuration file: %s", conf);
        servererr(errstr);
    }

    while(!(mygetline(input,MAXLINE,fp))) {
        char type[MAXLINE];
        char url[MAXLINE];
        char num[10];

        if((input[0] == '#') || (!input[0]))
            continue;

        type[0] = '\0';url[0] = '\0';

        for(i=0;isname(input[i]) && (input[i]);i++)
            type[i] = input[i];
        type[i] = '\0';

        while(isspace(input[i])) ++i;
        for(j=0;input[i] && isname(input[i]);++i,++j)
            url[j] = input[i];
        url[j] = '\0';

        if(!strcmp(type,"default") && !sawpoint) {
            strcpy(def,url);
            continue;
        }

        k=0;
        while (input[i]) {
            while (isspace(input[i]) || input[i] == ',')
                i++;
            j = 0;
            while (isdigit(input[i]))
                num[j++] = input[i++];
            num[j] = '\0';
            if (num[0] != '\0')
                pointarray[k][X] = (double) atoi(num);
            else
                break;
            while (isspace(input[i]) || input[i] == ',')
                i++;
            j = 0;
            while (isdigit(input[i]))
                num[j++] = input[i++];
            num[j] = '\0';
            if (num[0] != '\0')
                pointarray[k++][Y] = (double) atoi(num);
            else {
                fclose(fp);
                servererr("Missing y value.");
            }
        }
        pointarray[k][X] = -1;
        if(!strcmp(type,"poly"))
            if(pointinpoly(testpoint,pointarray))
                sendmesg(url);
        if(!strcmp(type,"circle"))
            if(pointincircle(testpoint,pointarray))
                sendmesg(url);
        if(!strcmp(type,"rect"))
            if(pointinrect(testpoint,pointarray))
                sendmesg(url);
        if(!strcmp(type,"point")) {
	    /* Don't need to take square root. */
	    dist = ((testpoint[X] - pointarray[0][X])
		    * (testpoint[X] - pointarray[0][X]))
		   + ((testpoint[Y] - pointarray[0][Y])
		      * (testpoint[Y] - pointarray[0][Y]));
	    /* If this is the first point, or the nearest, set the default. */
	    if ((! sawpoint) || (dist < mindist)) {
		mindist = dist;
	        strcpy(def,url);
	    }
	    sawpoint++;
	}
    }
    if(def[0])
        sendmesg(def);
    servererr("No default specified.");
}
Beispiel #2
0
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, *url;
    const char *status;

    testpoint.x = 0;
    testpoint.y = 0;
    text = 1;
    if (r->args) {
        t = strchr(r->args, ',');
        if (t == 0 || *++t == 0) {
            r->status = 400;
            return 0;
        }
        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: %s on line %d of %s", status, line, r->path_translated);
        r->status = 500;
        return 0;
    }
    if (url == 0)
        if (*default_url)
            url = default_url;
    if (url) {
        l = snprintf(r->newloc, PATHLEN, "%s", url);
        if (l >= PATHLEN) {
            log_d("imagemap: url too large");
            r->status = 500;
            return 0;
        }
        r->location = r->newloc;
        r->status = 302;
        return 0;
    }
    r->status = 204;
    return 0;
}
Beispiel #3
0
/* NCSA Imagemap files use: method URL coord1 coord2
 * CERN Imagemap files use: method (coord1) (coord2) URL
 * This version of imagemap will probably work with either in the same file,
 * as long as a full line is in one format or the other.
 */
int send_imagemap(per_request* reqInfo, struct stat* fi, char allow_options)
{
    char *input, *def, *szPoint, *url, *type;
    double testpoint[2], pointarray[MAXVERTS][2];
    int i, j, k;
    int error_num = 0;
    FILE *fp;
    char *t;
    double dist, mindist = -1;
    int sawpoint = 0;
    int sawparen = 0;
    int Found = 0;

    
    input = newString(HUGE_STRING_LEN,STR_TMP);
    def = newString(MAX_STRING_LEN,STR_TMP);
    szPoint = newString(MAX_STRING_LEN,STR_TMP);
    type = newString(MAX_STRING_LEN,STR_TMP);
    url = newString(MAX_STRING_LEN,STR_TMP);

    def[0] = '\0';
    strcpy(szPoint, reqInfo->args);

    if(!(t = strchr(szPoint,','))) {
        error_num = IMAP_ERR_INCORRECT_ARGS;
	goto imagemap_error;
    }

    *t++ = '\0';
    testpoint[X] = (double) atoi(szPoint);
    testpoint[Y] = (double) atoi(t);

    if(!(fp=FOpen(reqInfo->filename,"r"))){
	log_reason(reqInfo, "File permissions deny server access",
		   reqInfo->filename);
        freeString(input);
        freeString(def);
        freeString(szPoint);
        freeString(url);
        freeString(type);
	die(reqInfo, SC_FORBIDDEN, reqInfo->url);
    }

    while (!Found && fgets(input,HUGE_STRING_LEN,fp)) {
        char num[10];

        /* Skip lines with # as comments and blank lines */
        if((input[0] == '#') || (!input[0]))
            continue;

        type[0] = '\0';url[0] = '\0';

        /* Copy the shape keyword into type */
        for(i=0;!isspace(input[i]) && (input[i]);i++)
            type[i] = input[i];
        type[i] = '\0';

        /* Forward to next word */
        while(isspace(input[i])) ++i;

        /* If no coordinates, must be url for default, or NCSA format  */
	if (input[i] != '(') {
          for(j=0;input[i] && !isspace(input[i]);++i,++j)
            url[j] = input[i];
          url[j] = '\0';
        }

	/* Handle default keyword */
        if(!strcmp(type,"default") && !sawpoint) {
            strcpy(def,url);
            continue;
        }

        /* Looking for Coordinates */
        k=0;
        while (input[i]) {
	    /* Move over spaces and commas */
            while (isspace(input[i]) || input[i] == ',')
                i++;
	    
	    /* Under CERN, coordinates are in parenthesis */
            if (input[i] == '(') {
                sawparen = 1;
                while (isspace(input[++i]));
            }

            /* Copy digits into num array */
            j = 0;
            while (isdigit(input[i]))
                num[j++] = input[i++];

            num[j] = '\0';
            if (!j) break;
            pointarray[k][X] = (double) atoi(num);

            /* Skip to next digit */
            while (isspace(input[i]) || input[i] == ',')
                i++;
            /* Copy other number into num */
            j = 0;
            while (isdigit(input[i]))
                num[j++] = input[i++];
            num[j] = '\0';

            if (!j && !sawparen && k > 0) {
              pointarray[k++][Y] = -127;
              break;
            }
  
            if (j)
                pointarray[k++][Y] = (double) atoi(num);
            else {
		error_num = IMAP_ERR_INCORRECT_COORDS;
	        FClose(fp);
		goto imagemap_error;
            }
            
            /* End of parenthesis for coordinates under CERN */
            if (input[i] == ')') {
	      i++;
	      sawparen = 0;
	    } else if (sawparen) {
	      error_num = IMAP_ERR_CERN_MISSING_RIGHT_PAREN;
              FClose(fp);
              goto imagemap_error;	
	    }
        }
        if (url[0] == '\0' && input[i]) {
          while (isspace(input[i])) i++;
          for (j = 0; input[i] && !isspace(input[i]); ++i, ++j)
             url[j] = input[i];
          url[j] = '\0';
        }
        pointarray[k][X] = -1;
        if(!strncmp(type, "poly", 4))
            if(pointinpoly(testpoint,pointarray))
	       Found = 1;
        if(!strncmp(type, "circ", 4))
            if(pointincircle(testpoint,pointarray))
	      Found = 1;
        if(!strncmp(type, "rect", 4))
            if(pointinrect(testpoint,pointarray))
	      Found = 1;
        if(!strcmp(type,"point")) {
	    /* Don't need to take square root. */
	    dist = ((testpoint[X] - pointarray[0][X])
		    * (testpoint[X] - pointarray[0][X]))
		   + ((testpoint[Y] - pointarray[0][Y])
		      * (testpoint[Y] - pointarray[0][Y]));
	    /* If this is the first point, or the nearest, set the default. */
	    if ((! sawpoint) || (dist < mindist)) {
		mindist = dist;
	        strcpy(def,url);
	    }
	    sawpoint++;
	}
    }
    if(Found) {
      sendmesg(reqInfo, url, fp);
      goto imagemap_ok;
    } else {
      if(def[0]) {
        sendmesg(reqInfo, def, fp);
	goto imagemap_ok;
      }
    }
/* No reason to log each of these as an "error" */
/*    log_reason(reqInfo, "No default defined in imagemap.",
	       reqInfo->filename); */
    FClose(fp);
    freeString(input);
    freeString(def);
    freeString(szPoint);
    freeString(url);
    freeString(type);
    die(reqInfo, SC_NO_CONTENT, reqInfo->url);
    return 0;
 
 imagemap_ok:
    FClose(fp);
    freeString(input);
    freeString(def);
    freeString(szPoint);
    freeString(url);
    freeString(type);
    return 1;
 
 imagemap_error:
   freeString(input);
   freeString(def);
   freeString(szPoint);
   freeString(url);
   freeString(type);
   log_reason(reqInfo,imagemap_errors[error_num-1],reqInfo->filename);
   die(reqInfo,SC_BAD_IMAGEMAP,imagemap_errors[error_num-1]);
   return -1;
}