Exemplo n.º 1
0
int
NCD4_readDAP(NCD4INFO* state, int flags)
{
    int stat = NC_NOERR;
    long lastmod = -1;

    if((flags & NCF_ONDISK) == 0) {
        stat = readpacket(state,state->uri,state->curl->packet,NCD4_DAP,&lastmod);
        if(stat == NC_NOERR)
            state->data.daplastmodified = lastmod;
    } else { /*((flags & NCF_ONDISK) != 0) */
        NCURI* url = state->uri;
        int fileprotocol = (strcmp(url->protocol,"file")==0);
        if(fileprotocol) {
            stat = readfiletofile(state, url, ".dap", state->data.ondiskfile, &state->data.datasize);
        } else {
	    char* readurl = NULL;
            int flags = 0;
            if(!fileprotocol) flags |= NCURIQUERY;
            flags |= NCURIENCODE;
	    flags |= NCURIPWD;
#ifdef FIX
            ncurisetconstraints(url,state->constraint);
#endif
	    readurl = ncuribuild(url,NULL,".dods",NCURISVC);
	    if(readurl == NULL)
		return THROW(NC_ENOMEM);
            stat = NCD4_fetchurl_file(state->curl, readurl, state->data.ondiskfile,
                                   &state->data.datasize, &lastmod);
            nullfree(readurl);
            if(stat == NC_NOERR)
                state->data.daplastmodified = lastmod;
        }
    }
    return THROW(stat);
}
Exemplo n.º 2
0
/* Do a simple uri parse: return 0 if fail, 1 otherwise*/
int
ncuriparse(const char* uri0, NCURI** durip)
{
    NCURI* duri = NULL;
    char* uri = NULL;
    char* p;
    struct NC_ProtocolInfo* proto;
    int i,nprotos;

    /* accumulate parse points*/
    char* protocol = NULL;
    char* host = NULL;
    char* port = NULL;
    char* constraint = NULL;
    char* user = NULL;
    char* pwd = NULL;
    char* file = NULL;
    char* prefixparams = NULL;
    char* suffixparams = NULL;

    if(uri0 == NULL || strlen(uri0) == 0)
	{THROW(1); goto fail;}

    duri = (NCURI*)calloc(1,sizeof(NCURI));
    if(duri == NULL)
	{THROW(2); goto fail;}
	
    /* save original uri */
    duri->uri = nulldup(uri0);

    /* make local copy of uri */
    uri = (char*)malloc(strlen(uri0)+1+PADDING); /* +1 for trailing null,
                                                    +PADDING for shifting */
    if(uri == NULL)
	{THROW(3); goto fail;}

    /* strings will be broken into pieces with intermixed '\0; characters;
       first char is guaranteed to be '\0' */

    duri->strings = uri;
    uri++; 

    /* dup the incoming url */
    strcpy(uri,uri0);

    /* Walk the uri and do the following:
	1. remove all whitespace
	2. remove all '\\' (Temp hack to remove escape characters
                            inserted by Windows or MinGW)
    */
    for(p=uri;*p;p++) {
	if(*p == '\\' || *p < ' ')
	    nclshift1(p); /* compress out */
    }	

    p = uri;

    /* break up the uri string into big chunks: prefixparams, protocol,
       host section, and the file section (i.e. remainder)
    */

    /* collect any prefix bracketed parameters */
    if(*p == LBRACKET) {
	prefixparams = p+1;
	/* find end of the clientparams; convert LB,RB to '&' */
        for(;*p;p++) {
	    if(p[0] == RBRACKET && p[1] == LBRACKET) {
		p[0] = '&';
		nclshift1(p+1);
	    } else if(p[0] == RBRACKET && p[1] != LBRACKET)
		break;
	}
	if(*p == 0)
	    {THROW(4); goto fail; /* malformed client params*/}
        terminate(p); /* nul term the prefixparams (overwrites
                         the final RBRACKET) */
	p++; /* move past the final RBRACKET */
    }

    /* Tag the protocol */
    protocol = p;    
    p = strchr(p,':');
    if(!p)
	{THROW(5); goto fail;}
    terminate(p); /*overwrite colon*/
    p++; /* skip the colon */

    /* verify that the uri starts with an acceptable protocol*/
    nprotos = (sizeof(legalprotocols)/sizeof(struct NC_ProtocolInfo));
    proto = NULL;
    for(i=0;i<nprotos;i++) {
        if(strcmp(protocol,legalprotocols[i].name)==0) {
	    proto = &legalprotocols[i];
	    break;	    
	}
    }
    if(proto == NULL)
	{THROW(6); goto fail; /* illegal protocol*/}

    /* skip // */
    if(p[0] != '/' && p[1] != '/')
	{THROW(7); goto fail;}
    p += 2;

    /* If this is all we have (proto://) then fail */
    if(*p == EOFCHAR)
	{THROW(8); goto fail;}

    /* establish the start of the file section */
    if(proto->filelike) {/* everything after proto:// */
	file = p;
	host = NULL; /* and no host section */
    } else { /*!proto->filelike => This means there should be a host section */
        /* locate the end of the host section and therefore the start
           of the file section */
	host = p;
        p  = nclocate(p,"/?#");
	if(p == NULL) {
	    file = endof(host); /* there is no file section */
	} else {
	    ncrshift1(p); /* make room to terminate the host section
                             without overwriting the leading character */
	    terminate(p); /* terminate the host section */
	    file = p+1; /* +1 becauseof the shift */
	}
    }
    
    /* If you shift in the code below, you must reset file beginning */

    if(host != NULL) {/* Parse the host section */
	/* Check for leading user:pwd@ */
        p = strchr(host,'@');
        if(p) {
	    if(p == host)
		{THROW(9); goto fail; /* we have proto://@ */}
	    user = host;
	    terminate(p); /* overwrite '@' */
	    host = p+1; /* start of host ip name */
	    p = strchr(user,':');
 	    if(p == NULL)
		{THROW(10); goto fail; /* malformed */}
	    terminate(p); /*overwrite colon */
	    pwd = p+1;
	}

        /* extract host and port */
	p = host;
        p = strchr(p,':');
        if(p != NULL) {
	    terminate(p);
	    p++;
	    port = p;
	    if(*port == EOFCHAR)
		{THROW(11); goto fail; /* we have proto://...:/ */}
	    /* The port must look something like a number */
	    for(;*p;p++) {
	        if(strchr("0123456789-",*p) == NULL)
		    {THROW(12); goto fail;  /* probably not a real port, fail */}
	    }
	} /* else *p == NULL */


        /* check for empty host section */
	if(*host == EOFCHAR)
	    {THROW(13); goto fail;}

    }

    assert(file != NULL);
    p = file;

    /* find the end of the file section and the start of the
       constraints and/or suffixparams
    */
    p = nclocate(p,"?#");
    if(p != NULL) { /* we have constraint and/or suffixparams */
	char* fileend = p; /* save the end of the file section */
	char* constraintend = NULL; 
	if(*p == '?')
            constraint = p+1;
	else
	    constraint = NULL;
	p = strchr(p,'#'); /* may repeat effect of nclocate above */
	if(p != NULL) {
	    constraintend = p;
	    suffixparams = p+1;
	} else
	    suffixparams = NULL;
	/* Ok, terminate the pieces */
	terminate(fileend); /* terminate file section */
	if(constraint != NULL && constraintend != NULL)
	    terminate(constraintend);
	/* Suffix params are already terminated
           since they should be the last section
           of the original url
        */
    }

    /* check for empty sections */
    if(file != NULL && *file == EOFCHAR)
	file = NULL; /* empty file section */
    if(constraint != NULL && *constraint == EOFCHAR)
	constraint = NULL; /* empty constraint section */
    if(suffixparams != NULL && *suffixparams == EOFCHAR)
	suffixparams = NULL; /* empty suffixparams section */

    if(suffixparams != NULL) {
	/* there really are suffix params; so rebuild the suffix params */
	if(*suffixparams == LBRACKET) suffixparams++;
        p = suffixparams;
	/* convert RBRACKET LBRACKET to '&' */
        for(;*p;p++) {
	    if(p[0] == RBRACKET && p[1] == LBRACKET) {
	        p[0] = '&';
		nclshift1(p+1);
	    } else if(p[0] == RBRACKET && p[1] != LBRACKET) {
		/* terminate suffixparams */
		*p = EOFCHAR;
		break;
	    }
	}
	if(*suffixparams == EOFCHAR)
	    suffixparams = NULL; /* suffixparams are empty */
    }

    /* do last minute empty check */
    
    if(protocol != NULL && *protocol == EOFCHAR) protocol = NULL;
    if(user != NULL && *user == EOFCHAR) user = NULL;
    if(pwd != NULL && *pwd == EOFCHAR) pwd = NULL;
    if(host != NULL && *host == EOFCHAR) host = NULL;
    if(port != NULL && *port == EOFCHAR) port = NULL;
    if(file != NULL && *file == EOFCHAR) file = NULL;
    if(constraint != NULL && *constraint == EOFCHAR) constraint = NULL;

    /* assemble the component pieces */
    duri->protocol = protocol;
    duri->user = user;
    duri->password = pwd;
    duri->host = host;
    duri->port = port;
    duri->file = file;

    ncurisetconstraints(duri,constraint);

    /* concat suffix and prefix params */
    if(prefixparams != NULL || suffixparams != NULL) {
	int plen = prefixparams ? strlen(prefixparams) : 0;
	int slen = suffixparams ? strlen(suffixparams) : 0;
	int space = plen + slen + 1;
	/* add 1 for an extra ampersand if both are defined */
        space++;
        duri->params = (char*)malloc(space);
	duri->params[0] = EOFCHAR; /* so we can use strcat */
	if(plen > 0) {
            strcat(duri->params,prefixparams);
	    if(slen > 0)
		strcat(duri->params,"&");
	}
	if(slen > 0)
            strcat(duri->params,suffixparams);
    }

#ifdef NCXDEBUG
	{
        fprintf(stderr,"duri:");
        fprintf(stderr," params=|%s|",FIX(duri->params));
        fprintf(stderr," protocol=|%s|",FIX(duri->protocol));
        fprintf(stderr," host=|%s|",FIX(duri->host));
        fprintf(stderr," port=|%s|",FIX(duri->port));
        fprintf(stderr," file=|%s|",FIX(duri->file));
        fprintf(stderr," constraint=|%s|",FIX(duri->constraint));
        fprintf(stderr,"\n");
    }
#endif
    if(durip != NULL) 
      *durip = duri;
    else
      ncurifree(duri);

    return 1;

fail:
    if(duri != NULL) {
	ncurifree(duri);
    }
    return 0;
}