/* * Reposition the device to file, block * * Returns: false on failure * true on success */ bool generic_tape_device::reposition(DCR *dcr, uint32_t rfile, uint32_t rblock) { Dmsg4(100, "reposition from %u:%u to %u:%u\n", file, block_num, rfile, rblock); if (rfile < file) { Dmsg0(100, "Rewind\n"); if (!rewind(NULL)) { return false; } } if (rfile > file) { Dmsg1(100, "fsf %d\n", rfile-file); if (!fsf(rfile-file)) { Dmsg1(100, "fsf failed! ERR=%s\n", bstrerror()); return false; } Dmsg2(100, "wanted_file=%d at_file=%d\n", rfile, file); } if (rblock < block_num) { Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); Dmsg0(100, "bsf 1\n"); bsf(1); Dmsg0(100, "fsf 1\n"); fsf(1); Dmsg2(100, "wanted_blk=%d at_blk=%d\n", rblock, block_num); } if (has_cap(CAP_POSITIONBLOCKS) && rblock > block_num) { /* * Ignore errors as Bareos can read to the correct block. */ Dmsg1(100, "fsr %d\n", rblock-block_num); return fsr(rblock-block_num); } else { while (rblock > block_num) { if (!dcr->read_block_from_dev(NO_BLOCK_NUMBER_CHECK)) { berrno be; dev_errno = errno; Dmsg2(30, "Failed to find requested block on %s: ERR=%s", prt_name, be.bstrerror()); return false; } Dmsg2(300, "moving forward wanted_blk=%d at_blk=%d\n", rblock, block_num); } } return true; }
int main(int argc, char **argv, char **envp) { int postsize; char *xmldata, *data; xmlDocPtr doc; xmlNodePtr cur, anode; int bbdnsock; int bbdnport; char *status = NULL; struct config_t maincfg; /* Read in config file */ maincfg = maincfgopen(); bbdnport = maincfg_get_int(&maincfg, "BLDPORT"); maincfgclose(&maincfg); key_get(systemkey); char *request_method; if (!bbdn_conect(&bbdnsock, "", bbdnport)) cgi_error(500, bstrerror()); request_method = getenv("HTTP_REQUEST_METHOD")!=NULL ? strdup(getenv("HTTP_REQUEST_METHOD")) : strdup(getenv("REQUEST_METHOD")); // We will handel the post stuf our self. Set REQUEST_METHOD to GET so cgi-util ignores it. setenv("REQUEST_METHOD", "GET", 1); if (cgi_init() != CGIERR_NONE) { cgi_error(500, "Can't init cgi-util"); } /* * Either called from command line, and then we want a file. * or a http get/put * Or we are handling a web request, and getting the data from stdin. */ if ((cgi_getentrystr("method") != NULL) && (strcmp(cgi_getentrystr("method"),"rest") == 0)) { char api[100], coll[100], url[512]; char *requrle; if (getenv("REQUEST_URI") == NULL) { cgi_error(500, "Can't read REQUEST_URI"); } requrle = strdup(getenv("REQUEST_URI")); unescape_url(requrle); sscanf(requrle,"/%[a-z]/%[a-zA-Z0-9_-]/%[^?]", api, coll, url); #ifdef DEBUG fprintf(stderr, "api: \"%s\"\n",api); fprintf(stderr, "coll: \"%s\"\n",coll); fprintf(stderr, "url: \"%s\"\n",url); fprintf(stderr, "request_method: \"%s\"\n",request_method); fprintf(stderr, "reques url \"%s\"\n",getenv("REQUEST_URI")); fprintf(stderr, "reques url unescaped \"%s\"\n",requrle); #endif free(requrle); if (strcmp(request_method,"POST") == 0 || strcmp(request_method,"ADDDELAYED") == 0 || strcmp(request_method,"PUT") == 0) { if (getenv("CONTENT_LENGTH") == NULL) { cgi_error(500, "Can't read CONTENT_LENGTH"); } // Get data length postsize = atoi(getenv("CONTENT_LENGTH")); data = malloc(postsize + 1); if (data == NULL) { cgi_error(500, "Can't allocate data."); } // Read data fread(data, 1, postsize, stdin); data[postsize] = '\0'; // add in to repo if (bbdn_docadd(bbdnsock, coll, // collection name url, // url cgi_getentrystr("documenttype"), // document type data, // data postsize, // data size 0, // lastmodified cgi_getentrystr("acl_allow")!=NULL ? cgi_getentrystr("acl_allow") : "Everyone", // acl allow cgi_getentrystr("acl_denied"), // acl denied cgi_getentrystr("title"), // title cgi_getentrystr("documentformat"), // document format cgi_getentrystr("attributes"), // attributes NULL, // image 0 // image size ) != 1) { cgi_error(500, "bbdn_docadd() failed. Can't add document."); } if (strcmp(request_method,"ADDDELAYED") != 0) { // close it sd_close(bbdnsock, coll); } asprintf(&status,"Added %s to %s\n",url,coll); } else if (strcmp(request_method,"DELETE") == 0) { if (url[0] == '\0') { if (sd_deletecollection(bbdnsock, coll) != 1) { cgi_error(500, "Can't delete collection"); } asprintf(&status,"Deleted collection %s\n",coll); } else { if (bbdn_deleteuri(bbdnsock, coll, url) != 1) { cgi_error(500, "Can't delete document"); } asprintf(&status,"Deleted url %s in %s\n",url,coll); } } else if (strcmp(request_method,"CLOSE") == 0) { sd_close(bbdnsock, coll); asprintf(&status,"Closed %s\n",coll); } else { cgi_error(500, "Unknown request method \"%s\"", request_method ); } #ifdef DEBUG // Print the envirement so we can better see what is going on. char** env; for (env = envp; *env != 0; env++) { char* thisEnv = *env; fprintf(stderr, "%s\n", thisEnv); } #endif } else if ((cgi_getentrystr("do") != NULL) && (strcmp(cgi_getentrystr("do"),"add") == 0)) { char *data; int datasize; int n; const char *url = getenv("HTTP_X_FILENAME") ? getenv("HTTP_X_FILENAME") : cgi_getentrystr("url"); const char *coll = cgi_getentrystr("collection"); if (url == NULL) { cgi_error(500, "No url specified. Either set http header HTTP_X_FILENAME or get parameter 'url'.\n"); } if (coll == NULL) { cgi_error(500, "No collection specified\n"); } char *tmpname; FILE *fh; asprintf(&tmpname,"/tmp/%s",url); fh = fopen(tmpname,"wb"); if (fh == NULL) { cgi_error(500, "Can't open file %s",tmpname); } if ((data = malloc( atoi(getenv("CONTENT_LENGTH")) )) == NULL) { cgi_error(500, "Can't malloc data"); } datasize = 0; while ((n = fread ((unsigned char *)(data + datasize),1,1024,stdin)) > 0) { datasize += n; } fwrite(data,1,datasize,fh); fclose(fh); free(tmpname); // bbdn_docadd(bbdnsock, xmldoc.collection, uri, xmldoc.documenttype, xmldoc.body, xmldoc.bodysize, // xmldoc.lastmodified, xmldoc.aclallow, xmldoc.acldeny, xmldoc.title, xmldoc.documentformat, xmldoc.attributes, image, image_size); bbdn_docadd(bbdnsock, coll, url, "", data, datasize, 0, "Everyone", "", "omp1", "", "", NULL, 0); // close it sd_close(bbdnsock, coll); } else if ((cgi_getentrystr("do") != NULL) && (strcmp(cgi_getentrystr("do"),"delete") == 0)) { const char *url = getenv("HTTP_X_FILENAME") ? getenv("HTTP_X_FILENAME") : cgi_getentrystr("url"); const char *coll = cgi_getentrystr("collection"); if (url == NULL) { cgi_error(500, "No url specified. Either set http header HTTP_X_FILENAME or get parameter 'url'.\n"); } if (coll == NULL) { cgi_error(500, "No collection specified\n"); } bbdn_deleteuri(bbdnsock, coll, url); asprintf(&status,"%s deleted.\n", url); } else if (getenv("CONTENT_LENGTH") != NULL) { // Get data length postsize = atoi(getenv("CONTENT_LENGTH")); xmldata = malloc(postsize + 1); // Read data fread(xmldata, 1, postsize, stdin); xmldata[postsize] = '\0'; //fprintf(stderr, "Received %i bytes.\n", postsize); //fprintf(stderr, "Got document:\n%s\n", xmldata); //parsing xml doc = xmlParseDoc((xmlChar*)xmldata); if (doc == NULL) cgi_error(500, "Unable to parse document"); cur = xmlDocGetRootElement(doc); if (cur == NULL) { xmlFreeDoc(doc); cgi_error(500, "empty document"); } // Some document checking if (xmlStrcmp(cur->name, (const xmlChar *)ROOT_NODE_NAME)) { xmlFreeDoc(doc); cgi_error(500, "document of the wrong type, root node != %s, but %s\n", ROOT_NODE_NAME, cur->name); } if ((anode = xml_find_child(cur, "key")) != NULL) { char *p; p = (char *)xmlNodeListGetString(doc, anode->xmlChildrenNode, 1); if (p == NULL) cgi_error(500, "No key data"); if ((systemkey[0] != '\0') && (!key_equal(systemkey, p))) { cgi_error(500, "Keys does not match: Got \"%s\" but wanted \"%s\"\n",p,systemkey); } } else { cgi_error(500, "Did not receive a key"); } if ((anode = xml_find_child(cur, "version")) != NULL) { xmlChar *p; p = xmlNodeListGetString(doc, anode->xmlChildrenNode, 1); version = atoi((char*)p); xmlFree(p); } else { cgi_error(500, "Did not receive a version number"); } for (cur = cur->xmlChildrenNode; cur != NULL; cur = cur->next) { if ((!xmlStrcmp(cur->name, (const xmlChar *) "key"))){ // Ignore } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "version"))){ // Ignore } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "add"))){ xml_add(bbdnsock, doc, cur); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "delete"))){ xml_delete(bbdnsock, doc, cur); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "close"))) { xml_close(bbdnsock, doc, cur); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "create"))) { xml_create(bbdnsock, doc, cur); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "users"))) { xml_users(doc, cur); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "gcwhispers"))) { xml_gcwhispers(bbdnsock, doc, cur); } else if ((!xmlStrcmp(cur->name, (const xmlChar *) "error"))) { xml_errormsg(bbdnsock, doc, cur); } else if ((!xmlStrcmp(cur->name, (xmlChar*)"text"))) { //fprintf(stderr, "Got text: %s\n", xmlNodeListGetString(doc, cur, 1)); // Ignore for now } else { warnx("Unknown xml node '%s'", cur->name); } } } else { cgi_error(500, "Didn't receive any command or data."); } if (status != NULL) { printf("Content-type: text/plain\n\n"); printf(status); } else { cgi_error(500, "Reached end of program without status."); } return 0; }