/* Isolate the "CURL." prefix to allow changing to something else */ static char* curllookup(char* suffix, char* url) { char key[2048]; char* value = NULL; if(!occopycat(key,sizeof(key),2,HTTPPREFIX,suffix)) return NULL; value = ocdodsrc_lookup(key,url); if(value == NULL) { if(!occopycat(key,sizeof(key),2,HTTPPREFIXDEPRECATED,suffix)) return NULL; value = ocdodsrc_lookup(key,url); } return value; }
static int readfile(const char* path, const char* suffix, OCbytes* packet) { int stat = OC_NOERR; char buf[1024]; char filename[1024]; int fd = -1; int flags = 0; off_t filesize = 0; off_t totalread = 0; /* check for leading file:/// */ if(ocstrncmp(path,"file://",7)==0) path += 7; /* assume absolute path*/ if(!occopycat(filename,sizeof(filename),2,path,(suffix != NULL ? suffix : ""))) return OCTHROW(OC_EOVERRUN); flags = O_RDONLY; #ifdef O_BINARY flags |= O_BINARY; #endif fd = open(filename,flags); if(fd < 0) { oclog(OCLOGERR,"open failed:%s",filename); return OCTHROW(OC_EOPEN); } /* Get the file size */ filesize = lseek(fd,(off_t)0,SEEK_END); if(filesize < 0) { stat = OC_EIO; oclog(OCLOGERR,"lseek failed: %s",filename); goto done; } /* Move file pointer back to the beginning of the file */ (void)lseek(fd,(off_t)0,SEEK_SET); stat = OC_NOERR; for(totalread=0;;) { off_t count = (off_t)read(fd,buf,sizeof(buf)); if(count == 0) break; /*eof*/ else if(count < 0) { stat = OC_EIO; oclog(OCLOGERR,"read failed: %s",filename); goto done; } ocbytesappendn(packet,buf,(unsigned long)count); totalread += count; } if(totalread < filesize) { stat = OC_EIO; oclog(OCLOGERR,"short read: |%s|=%lu read=%lu\n", filename,(unsigned long)filesize,(unsigned long)totalread); goto done; } done: #ifdef OCDEBUG fprintf(stderr,"readfile: filesize=%lu totalread=%lu\n", (unsigned long)filesize,(unsigned long)totalread); #endif if(fd >= 0) close(fd); return OCTHROW(stat); }
/* Set curl properties for link based on rc files */ static void ocsetcurlproperties(OCstate* state) { CURLcode cstat = CURLE_OK; /* process the triple store wrt to this state */ if(ocdodsrc_process(state) != OC_NOERR) { oclog(OCLOGERR,"Malformed .opendaprc configuration file"); goto fail; } if(state->creds.username == NULL && state->creds.password == NULL) { if(state->uri->user != NULL && state->uri->password != NULL) { /* this overrides .dodsrc */ if(state->creds.password) free(state->creds.password); state->creds.password = nulldup(state->uri->password); if(state->creds.username) free(state->creds.username); state->creds.username = nulldup(state->uri->user); } } if(state->curlflags.useragent == NULL) { size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1; char* agent = (char*)malloc(len+1); if(occopycat(agent,len,2,DFALTUSERAGENT,VERSION)) state->curlflags.useragent = agent; else free(agent); } return; fail: if(cstat != CURLE_OK) oclog(OCLOGERR, "curl error: %s", curl_easy_strerror(cstat)); return; }
char* occombinehostport(const OCURI* uri) { char* hp; int len = 0; if(uri->host == NULL) return NULL; else len += strlen(uri->host); if(uri->port != NULL) len += strlen(uri->port); hp = (char*)malloc(len+1); if(hp == NULL) return NULL; if(uri->port == NULL) occopycat(hp,len+1,1,uri->host); else occopycat(hp,len+1,3,uri->host,":",uri->port); return hp; }
int ocmktmp(const char* base, char** tmpnamep, int* fdp) { int fd; char* tmpname = NULL; mode_t oldmask; size_t tmpsize = strlen(base)+strlen("XXXXXX") + 1; tmpname = (char*)malloc(tmpsize); if(tmpname == NULL) return OC_ENOMEM; if(!occopycat(tmpname,tmpsize,1,base)) { free(tmpname); return OC_EOVERRUN; } #ifdef HAVE_MKSTEMP if(!occoncat(tmpname,tmpsize,1,"XXXXXX")) { free(tmpname); return OC_EOVERRUN; } /* Note Potential problem: old versions of this function leave the file in mode 0666 instead of 0600 */ oldmask= umask(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); fd = mkstemp(tmpname); umask(oldmask); /* restore */ #else /* !HAVE_MKSTEMP */ /* Need to simulate by using some kind of pseudo-random number */ { int rno = rand(); char spid[7]; if(rno < 0) rno = -rno; snprintf(spid,sizeof(spid),"%06d",rno); if(!occoncat(tmpname,tmpsize,1,spid)) { free(tmpname); return OC_EOVERRUN; } #if defined(_WIN32) || defined(_WIN64) fd=open(tmpname,O_RDWR|O_BINARY|O_CREAT|O_EXCL|FILE_ATTRIBUTE_TEMPORARY, _S_IREAD|_S_IWRITE); # else fd=open(tmpname,O_RDWR|O_CREAT|O_EXCL, S_IRWXU); # endif } #endif /* !HAVE_MKSTEMP */ if(fd < 0) { if(tmpname != NULL) free(tmpname); return OC_EOPEN; } if(tmpnamep) *tmpnamep = tmpname; else if(tmpname != NULL) {free(tmpname);} if(fdp) *fdp = fd; else if(fd >= 0) close(fd); return OC_NOERR; }
static char* ocrc_lookup(char* suffix, char* url) { char* value = NULL; char key[MAXRCLINESIZE+1]; const char** p = prefixes; for(;*p;p++) { if(!occopycat(key,sizeof(key),2,*p,suffix)) return NULL; value = ocrc_lookup(key,url); if(value != NULL) return value; } return value; }
static char* combinecredentials(const char* user, const char* pwd) { int userPassSize; char *userPassword; if(user == NULL) user = ""; if(pwd == NULL) pwd = ""; userPassSize = strlen(user) + strlen(pwd) + 2; userPassword = malloc(sizeof(char) * userPassSize); if (!userPassword) { oclog(OCLOGERR,"Out of Memory\n"); return NULL; } occopycat(userPassword,userPassSize-1,3,user,":",pwd); return userPassword; }
int createtempfile1(char* tmppath, char** tmpnamep) { int fd = 0; char* tmpname = NULL; size_t tmpsize = strlen(tmppath)+strlen("dataddsXXXXXX") + 1; tmpname = (char*)malloc(tmpsize); if(tmpname == NULL) return -1; if(!occopycat(tmpname,tmpsize,1,tmppath)) return OC_EOVERRUN; #ifdef HAVE_MKSTEMP if(!occoncat(tmpname,tmpsize,1,"dataddsXXXXXX")) return OC_EOVERRUN; /* Note Potential problem: old versions of this function leave the file in mode 0666 instead of 0600 */ umask(S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH); fd = mkstemp(tmpname); #else /* !HAVE_MKSTEMP */ /* Need to simulate by using some kind of pseudo-random number */ if(!occoncat(tmpname,tmpsize,1,"datadds")) return OC_EOVERRUN; { int rno = rand(); char spid[7]; if(rno < 0) rno = -rno; snprintf(spid,sizeof(spid),"%06d",rno); if(!occoncat(tmpname,tmpsize,1,spid)) return OC_EOVERRUN; # ifdef _WIN32 fd=open(tmpname,O_RDWR|O_BINARY|O_CREAT|O_EXCL|FILE_ATTRIBUTE_TEMPORARY, _S_IREAD|_S_IWRITE); # else fd=open(tmpname,O_RDWR|O_CREAT|O_EXCL, S_IRWXU); # endif } #endif /* !HAVE_MKSTEMP */ if(tmpname == NULL) return -1; if(tmpnamep) *tmpnamep = tmpname; else free(tmpname); return fd; }
static OCerror createtempfile(OCstate* state, OCtree* tree) { int stat = OC_NOERR; char* path = NULL; char* name = NULL; int len; len = strlen(ocglobalstate.tempdir) + 1 /* '/' */ + strlen(DATADDSFILE); path = (char*)malloc(len+1); if(path == NULL) return OC_ENOMEM; occopycat(path,len,3,ocglobalstate.tempdir,"/",DATADDSFILE); stat = ocmktmp(path,&name); free(path); if(stat != OC_NOERR) goto fail; #ifdef OCDEBUG oclog(OCLOGNOTE,"oc_open: creating tmp file: %s",name); #endif tree->data.filename = name; /* remember our tmp file name */ name = NULL; tree->data.file = fopen(tree->data.filename,"w+"); if(tree->data.file == NULL) return OC_EOPEN; /* unlink the temp file so it will automatically be reclaimed */ if(ocdebug == 0) unlink(tree->data.filename); return stat; fail: if(name != NULL) { oclog(OCLOGERR,"oc_open: attempt to create tmp file failed: %s",name); free(name); } else { oclog(OCLOGERR,"oc_open: attempt to create tmp file failed: NULL"); } return OCTHROW(stat); }
/** * Prefix must end in '/' */ static OCerror rc_search(const char* prefix, const char* rcname, char** pathp) { char* path = NULL; FILE* f = NULL; int plen = strlen(prefix); int rclen = strlen(rcname); OCerror stat = OC_NOERR; size_t pathlen = plen+rclen+1+1; /*+1 for '/' +1 for nul*/ path = (char*)malloc(pathlen); if(path == NULL) { stat = OC_ENOMEM; goto done; } if(!occopycat(path,pathlen,3,prefix,"/",rcname)) { stat = OC_EOVERRUN; goto done; } /* see if file is readable */ f = fopen(path,"r"); if(f != NULL) oclog(OCLOGDBG, "Found rc file=%s",path); done: if(f == NULL || stat != OC_NOERR) { if(path != NULL) free(path); path = NULL; } if(f != NULL) fclose(f); if(pathp != NULL) *pathp = path; return OCTHROW(stat); }
/* Set curl properties for link based on rc files etc. */ static OCerror ocset_curlproperties(OCstate* state) { OCerror stat = OC_NOERR; /* extract the relevant triples int state */ ocrc_process(state); if(state->curlflags.useragent == NULL) { size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1; char* agent = (char*)malloc(len+1); if(occopycat(agent,len,2,DFALTUSERAGENT,VERSION)) state->curlflags.useragent = agent; else free(agent); } /* Some servers (e.g. thredds and columbia) appear to require a place to put cookies in order for some security functions to work */ if(state->curlflags.cookiejar != NULL && strlen(state->curlflags.cookiejar) == 0) { free(state->curlflags.cookiejar); state->curlflags.cookiejar = NULL; } if(state->curlflags.cookiejar == NULL) { /* If no cookie file was defined, define a default */ char tmp[OCPATHMAX+1]; int stat; pid_t pid = getpid(); snprintf(tmp,sizeof(tmp)-1,"%s/%s.%ld/",ocglobalstate.tempdir,OCDIR,(long)pid); #ifdef _MSC_VER stat = mkdir(tmp); #else stat = mkdir(tmp,S_IRUSR | S_IWUSR | S_IXUSR); #endif if(stat != 0 && errno != EEXIST) { fprintf(stderr,"Cannot create cookie directory\n"); goto fail; } errno = 0; /* Create the unique cookie file name */ stat = ocmktmp(tmp,&state->curlflags.cookiejar); state->curlflags.createdflags |= COOKIECREATED; if(stat != OC_NOERR && errno != EEXIST) { fprintf(stderr,"Cannot create cookie file\n"); goto fail; } errno = 0; } OCASSERT(state->curlflags.cookiejar != NULL); /* Make sure the cookie jar exists and can be read and written */ { FILE* f = NULL; char* fname = state->curlflags.cookiejar; /* See if the file exists already */ f = fopen(fname,"r"); if(f == NULL) { /* Ok, create it */ f = fopen(fname,"w+"); if(f == NULL) { fprintf(stderr,"Cookie file cannot be read and written: %s\n",fname); {stat = OC_EPERM; goto fail;} } } else { /* test if file can be written */ fclose(f); f = fopen(fname,"r+"); if(f == NULL) { fprintf(stderr,"Cookie file is cannot be written: %s\n",fname); {stat = OC_EPERM; goto fail;} } } if(f != NULL) fclose(f); } #if 0 /* Create a netrc file if specified and required, where required => >1 NETRC triples exist */ if(ocrc_netrc_required(state)) { /* WARNING: it appears that a user+pwd was specified specifically, then the netrc file will be completely disabled. */ if(state->creds.userpwd != NULL) { oclog(OCLOGWARN,"The rc file specifies both netrc and user+pwd; this will cause curl to ignore the netrc file"); } stat = oc_build_netrc(state); } #endif return stat; fail: return OCTHROW(stat); }
int ocinternalinitialize(void) { int stat = OC_NOERR; if(!ocglobalstate.initialized) { memset((void*)&ocglobalstate,0,sizeof(ocglobalstate)); ocglobalstate.initialized = 1; } /* Capture $HOME */ { char* p; char* q; char* home = getenv("HOME"); char cwd[4096]; if(ocglobalstate.home == NULL) { #if defined(_WIN32) || defined(_WIN64) home = getenv("TEMP"); #else home = "/tmp"; #endif } if(home == NULL) { home = getcwd(cwd,sizeof(cwd)); if(home == NULL || *home == '\0') home = "."; } /* Convert '\' to '/' */ ocglobalstate.home = (char*)malloc(strlen(home) + 1); for(p=home,q=ocglobalstate.home;*p;p++,q++) { if(*p == '\\') {*q = '/'; } else {*q = *p;} } *q = '\0'; } /* Compute some xdr related flags */ xxdr_init(); ocloginit(); oc_curl_protocols(&ocglobalstate); /* see what protocols are supported */ /* compile the .dodsrc, if any */ { char* path = NULL; char** alias; FILE* f = NULL; /* locate the configuration files: . first in '.', then $HOME */ for(alias=rcfilenames;*alias;alias++) { size_t pathlen = strlen("./")+strlen(*alias)+1; path = (char*)malloc(pathlen); if(path == NULL) return OC_ENOMEM; if(!occopycat(path,pathlen,2,"./",*alias)) { if(path) free(path); return OC_EOVERRUN; } /* see if file is readable */ f = fopen(path,"r"); if(f != NULL) break; if(path != NULL) {free(path); path = NULL;} /* cleanup */ } if(f == NULL) { /* try $HOME */ OCASSERT(path == NULL); for(alias=rcfilenames;*alias;alias++) { size_t pathlen = strlen(ocglobalstate.home)+1+strlen(*alias)+1; path = (char*)malloc(pathlen); if(path == NULL) return OC_ENOMEM; if(!occopycat(path,pathlen,3,ocglobalstate.home,"/",*alias)) { if(path) free(path); return OC_EOVERRUN; } f = fopen(path,"r"); if(f != NULL) break; if(path != NULL) {free(path); path=NULL;} } } if(f == NULL) { oclog(OCLOGDBG,"Cannot find runtime configuration file"); } else { OCASSERT(path != NULL); fclose(f); if(ocdebug > 1) fprintf(stderr, "DODS RC file: %s\n", path); if(ocdodsrc_read(*alias,path) == 0) oclog(OCLOGERR, "Error parsing %s\n",path); } if(path != NULL) free(path); } return OCTHROW(stat); }
/* Set curl properties for link based on rc files etc. */ static int ocsetcurlproperties(OCstate* state) { CURLcode cstat = CURLE_OK; /* process the triple store wrt to this state */ if(ocdodsrc_process(state) != OC_NOERR) { oclog(OCLOGERR,"Malformed .opendaprc configuration file"); goto fail; } if(state->creds.username == NULL && state->creds.password == NULL) { if(state->uri->user != NULL && state->uri->password != NULL) { /* this overrides .dodsrc */ if(state->creds.password) free(state->creds.password); state->creds.password = nulldup(state->uri->password); if(state->creds.username) free(state->creds.username); state->creds.username = nulldup(state->uri->user); } } if(state->curlflags.useragent == NULL) { size_t len = strlen(DFALTUSERAGENT) + strlen(VERSION) + 1; char* agent = (char*)malloc(len+1); if(occopycat(agent,len,2,DFALTUSERAGENT,VERSION)) state->curlflags.useragent = agent; else free(agent); } /* Some servers (e.g. thredds and columbia) appear to require a place to put cookies in order for some security functions to work */ if(state->curlflags.cookiejar == NULL || *state->curlflags.cookiejar) { #if 1 /* Apparently anything non-null will work */ state->curlflags.cookiejar = strdup(""); #else /* If no cookie file was defined, define a default */ char* tmp; int fd; int stat; tmp = (char*)malloc(strlen(ocglobalstate.home) +strlen("/") +strlen(OCDIR) +strlen("/") +1); if(tmp == NULL) return OC_ENOMEM; strcpy(tmp,ocglobalstate.home); strcat(tmp,"/"); strcat(tmp,OCDIR); strcat(tmp,"/"); stat = mkdir(tmp,S_IRUSR | S_IWUSR | S_IXUSR); if(stat != 0 && errno != EEXIST) { fprintf(stderr,"Cannot create cookie file\n"); return stat; } errno = 0; /* Create the actual cookie file */ stat = ocmktmp(tmp,&state->curlflags.cookiejar,&fd); close(fd); #if 0 fd = creat(tmp,S_IRUSR | S_IWUSR); if(fd < 0) { fprintf(stderr,"Cannot create cookie file\n"); return OC_EPERM; }else close(fd); #endif #endif } return OC_NOERR; fail: if(cstat != CURLE_OK) oclog(OCLOGERR, "curl error: %s", curl_easy_strerror(cstat)); return OC_ECURL; }
int ocinternalinitialize(void) { int stat = OC_NOERR; if(!ocglobalstate.initialized) { memset((void*)&ocglobalstate,0,sizeof(ocglobalstate)); ocglobalstate.initialized = 1; } /* Compute some xdr related flags */ xxdr_init(); ocloginit(); oc_curl_protocols(&ocglobalstate); /* see what protocols are supported */ /* compile the .dodsrc, if any */ { char* path = NULL; char* homepath = NULL; char** alias; FILE* f = NULL; /* locate the configuration files: . first in '.', then $HOME */ for(alias=rcfilenames;*alias;alias++) { size_t pathlen = strlen("./")+strlen(*alias)+1; path = (char*)malloc(pathlen); if(path == NULL) return OC_ENOMEM; if(!occopycat(path,pathlen,2,"./",*alias)) { if(path) free(path); return OC_EOVERRUN; } /* see if file is readable */ f = fopen(path,"r"); if(f != NULL) break; if(path != NULL) {free(path); path = NULL;} /* cleanup */ } if(f == NULL) { /* try $HOME */ OCASSERT(path == NULL); homepath = getenv("HOME"); if (homepath!= NULL) { for(alias=rcfilenames;*alias;alias++) { size_t pathlen = strlen(homepath)+1+strlen(*alias)+1; path = (char*)malloc(pathlen); if(path == NULL) return OC_ENOMEM; if(!occopycat(path,pathlen,3,homepath,"/",*alias)) { if(path) {free(path);} return OC_EOVERRUN; } f = fopen(path,"r"); if(f != NULL) break; if(path != NULL) {free(path); path=NULL;} } } } if(f == NULL) { oclog(OCLOGDBG,"Cannot find runtime configuration file"); } else { OCASSERT(path != NULL); fclose(f); if(ocdebug > 1) fprintf(stderr, "DODS RC file: %s\n", path); if(ocdodsrc_read(*alias,path) == 0) oclog(OCLOGERR, "Error parsing %s\n",path); } if(path != NULL) free(path); } return OCTHROW(stat); }