void WriteELF::Write(const vector<uint64_t>& instructions, const DebugInfo& info, const char* filename) { // File name symbol { auto& sym = AddSymbol(filename); sym.st_info = (STB_LOCAL<<4) | STT_FILE; sym.st_shndx = SHN_ABS; } const size_t code_size = instructions.size() * sizeof(uint64_t); // Code fragment symbol, name = file name if (!NoStandardSymbols) { string name = stripextension(strippath(filename)); replacenonalphanum(name); AddGlobalSymbol(name).st_size = code_size; // End Symbol name.append("_end"); AddGlobalSymbol(name).st_value = code_size; // Size symbol name.erase(name.size() - 4); name.append("_size"); auto& sym = AddGlobalSymbol(name); sym.st_shndx = SHN_ABS; sym.st_value = code_size; } // Export global symbol table for (auto sym : info.GlobalsByName) { auto& value = AddGlobalSymbol(sym.first); value.st_value = (Elf32_Addr)sym.second.iValue; if (sym.second.Type == V_INT) value.st_shndx = SHN_ABS; } // write header WriteRaw(Hdr); // write section table WriteRaw(Sect0); WriteRaw(SectSNST); Elf32_Shdr sect = SectCode; sect.sh_size = code_size; WriteRaw(sect); sect = SectSym; sect.sh_offset += code_size; size_t sym_size = Symbols.size() * sizeof(Elf32_Sym); sect.sh_size = sym_size; WriteRaw(sect); sect = SectSymST; sect.sh_offset += code_size + sym_size; sect.sh_size = SymbolNames.size() + 1; WriteRaw(sect); // write section names WriteRaw(SNST); // write code checkedwrite(Target, &instructions.front(), code_size); // write symbol table checkedwrite(Target, &Symbols.front(), sizeof(Elf32_Sym) * Symbols.size()); // write symbol names checkedwrite(Target, SymbolNames.c_str(), SymbolNames.size() + 1); }
static CURLcode formdata_add_filename(const struct curl_httppost *file, struct FormData **form, curl_off_t *size) { CURLcode result = CURLE_OK; char *filename = file->showfilename; char *filebasename = NULL; char *filename_escaped = NULL; if(!filename) { filebasename = strippath(file->contents); if(!filebasename) return CURLE_OUT_OF_MEMORY; filename = filebasename; } if(strchr(filename, '\\') || strchr(filename, '"')) { char *p0, *p1; /* filename need be escaped */ filename_escaped = malloc(strlen(filename)*2+1); if(!filename_escaped) { free(filebasename); return CURLE_OUT_OF_MEMORY; } p0 = filename_escaped; p1 = filename; while(*p1) { if(*p1 == '\\' || *p1 == '"') *p0++ = '\\'; *p0++ = *p1++; } *p0 = '\0'; filename = filename_escaped; } result = AddFormDataf(form, size, "; filename=\"%s\"", filename); free(filename_escaped); free(filebasename); return result; }
CURLcode Curl_getformdata(struct SessionHandle *data, struct FormData **finalform, struct curl_httppost *post, const char *custom_content_type, curl_off_t *sizep) { struct FormData *form = NULL; struct FormData *firstform; struct curl_httppost *file; CURLcode result = CURLE_OK; curl_off_t size=0; /* support potentially ENORMOUS formposts */ char *boundary; char *fileboundary=NULL; struct curl_slist* curList; *finalform=NULL; /* default form is empty */ if(!post) return result; /* no input => no output! */ boundary = Curl_FormBoundary(); if(!boundary) return CURLE_OUT_OF_MEMORY; /* Make the first line of the output */ result = AddFormDataf(&form, NULL, "%s; boundary=%s\r\n", custom_content_type?custom_content_type: "Content-Type: multipart/form-data", boundary); if(result) { free(boundary); return result; } /* we DO NOT include that line in the total size of the POST, since it'll be part of the header! */ firstform = form; do { if(size) { result = AddFormDataf(&form, &size, "\r\n"); if(result) break; } /* boundary */ result = AddFormDataf(&form, &size, "--%s\r\n", boundary); if(result) break; /* Maybe later this should be disabled when a custom_content_type is passed, since Content-Disposition is not meaningful for all multipart types. */ result = AddFormDataf(&form, &size, "Content-Disposition: form-data; name=\""); if(result) break; result = AddFormData(&form, FORM_DATA, post->name, post->namelength, &size); if(result) break; result = AddFormDataf(&form, &size, "\""); if(result) break; if(post->more) { /* If used, this is a link to more file names, we must then do the magic to include several files with the same field name */ fileboundary = Curl_FormBoundary(); result = AddFormDataf(&form, &size, "\r\nContent-Type: multipart/mixed," " boundary=%s\r\n", fileboundary); if(result) break; } file = post; do { /* If 'showfilename' is set, that is a faked name passed on to us to use to in the formpost. If that is not set, the actually used local file name should be added. */ if(post->more) { /* if multiple-file */ char *filebasename= NULL; if(!file->showfilename) { filebasename = strippath(file->contents); if(!filebasename) { Curl_formclean(&firstform); free(boundary); return CURLE_OUT_OF_MEMORY; } } result = AddFormDataf(&form, &size, "\r\n--%s\r\nContent-Disposition: " "attachment; filename=\"%s\"", fileboundary, (file->showfilename?file->showfilename: filebasename)); if(filebasename) free(filebasename); if(result) break; } else if(post->flags & (HTTPPOST_FILENAME|HTTPPOST_BUFFER| HTTPPOST_CALLBACK)) { /* it should be noted that for the HTTPPOST_FILENAME and HTTPPOST_CALLBACK cases the ->showfilename struct member is always assigned at this point */ if(post->showfilename || (post->flags & HTTPPOST_FILENAME)) { char *filebasename= (!post->showfilename)?strippath(post->contents):NULL; result = AddFormDataf(&form, &size, "; filename=\"%s\"", (post->showfilename?post->showfilename: filebasename)); if(filebasename) free(filebasename); } if(result) break; } if(file->contenttype) { /* we have a specified type */ result = AddFormDataf(&form, &size, "\r\nContent-Type: %s", file->contenttype); if(result) break; } curList = file->contentheader; while(curList) { /* Process the additional headers specified for this form */ result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); if(result) break; curList = curList->next; } if(result) { Curl_formclean(&firstform); free(boundary); return result; } result = AddFormDataf(&form, &size, "\r\n\r\n"); if(result) break; if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_READFILE)) { /* we should include the contents from the specified file */ FILE *fileread; fileread = strequal("-", file->contents)? stdin:fopen(file->contents, "rb"); /* binary read for win32 */ /* * VMS: This only allows for stream files on VMS. Stream files are * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC, * every record needs to have a \n appended & 1 added to SIZE */ if(fileread) { if(fileread != stdin) { /* close the file again */ fclose(fileread); /* add the file name only - for later reading from this */ result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); } else { /* When uploading from stdin, we can't know the size of the file, * thus must read the full file as before. We *could* use chunked * transfer-encoding, but that only works for HTTP 1.1 and we * can't be sure we work with such a server. */ size_t nread; char buffer[512]; while((nread = fread(buffer, 1, sizeof(buffer), fileread)) != 0) { result = AddFormData(&form, FORM_CONTENT, buffer, nread, &size); if(result) break; } } } else { if(data) failf(data, "couldn't open file \"%s\"\n", file->contents); *finalform = NULL; result = CURLE_READ_ERROR; } } else if(post->flags & HTTPPOST_BUFFER) /* include contents of buffer */ result = AddFormData(&form, FORM_CONTENT, post->buffer, post->bufferlength, &size); else if(post->flags & HTTPPOST_CALLBACK) /* the contents should be read with the callback and the size is set with the contentslength */ result = AddFormData(&form, FORM_CALLBACK, post->userp, post->contentslength, &size); else /* include the contents we got */ result = AddFormData(&form, FORM_CONTENT, post->contents, post->contentslength, &size); file = file->more; } while(file && !result); /* for each specified file for this field */ if(result) { Curl_formclean(&firstform); free(boundary); return result; } if(post->more) { /* this was a multiple-file inclusion, make a termination file boundary: */ result = AddFormDataf(&form, &size, "\r\n--%s--", fileboundary); free(fileboundary); if(result) break; } } while((post = post->next) != NULL); /* for each field */ if(result) { Curl_formclean(&firstform); free(boundary); return result; } /* end-boundary for everything */ result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary); if(result) { Curl_formclean(&firstform); free(boundary); return result; } *sizep = size; free(boundary); *finalform=firstform; return result; }
/* return 0 on success * extract a file in tarball to appropriate directory, ignoring any paths in archive * note that szDestPath lacks slash at end * szFName is the file to extract * szWantedFile is the file to extract * szDestPath is the path to extract to (without trailing slash) - if NULL, extracted data wont be saved to disk * retBuf is a pointer to a bufferpointer - will be g_try_malloc'ed and filled with data if retBuf != NULL * retFileSize will be filled with the size of the file, if it's != NULL * * extraction routines derived from logic in zlib's contrib untgz.c program */ int UT_untgz(const char *szFName, const char *szWantedFile, const char *szDestPath, char **retBuf, int *retFileSize) { gzFile tarball; union tar_buffer buffer; int getheader = 1; int remaining = 0; int len; char fname[TGZ_BLOCKSIZE]; FILE *outfile = NULL; int fileSize = 0; if (retBuf) FREEP(*retBuf); if ((tarball = gzopen(szFName, "rb")) == NULL) { UT_DEBUGMSG(("untgz: Error while opening downloaded dictionary archive")); return 1; } bool done = false; while (!done) { if ((len = gzread(tarball, &buffer, TGZ_BLOCKSIZE)) != TGZ_BLOCKSIZE) { // error (gzerror(in, &err)); UT_DEBUGMSG(("untgz: gzread failed to read in complete block")); gzclose(tarball); return 1; } /* * If we have to get a tar header */ if (getheader == 1) { /* * if we met the end of the tar * or the end-of-tar block, * we are done */ if ((len == 0) || (buffer.header.name[0]== 0)) { done = true; continue; } // tartime = static_cast<time_t>(getoct(buffer.header.mtime,12)); strcpy(fname, buffer.header.name); strippath(fname); if ((buffer.header.typeflag == '\0') || // [A]REGTYPE, ie regular files (buffer.header.typeflag == '0') ) { remaining = getoct(buffer.header.size, 12); if ((remaining) && (g_ascii_strcasecmp(fname, szWantedFile) == 0)) { fileSize = remaining; if (retBuf) { if (!(*retBuf = static_cast<char *>(g_try_malloc(fileSize)))) *retBuf = NULL; } if (retFileSize) *retFileSize = fileSize; if (szDestPath) { UT_String outfilename(szDestPath); outfilename += "/"; outfilename += fname; if ((outfile = fopen(outfilename.c_str(), "wb")) == NULL) { UT_DEBUGMSG(("untgz: Unable to save %s", outfilename.c_str())); } } else outfile = NULL; } else outfile = NULL; /* * could have no contents */ getheader = (remaining) ? 0 : 1; } } else // if (getheader != 1) { unsigned int bytes = (remaining > TGZ_BLOCKSIZE) ? TGZ_BLOCKSIZE : remaining; if (retBuf && *retBuf) { memcpy(retBuf[fileSize - remaining], buffer.buffer, bytes); } if (outfile != NULL) { if (fwrite(&buffer,sizeof(char),bytes,outfile) != bytes) { UT_DEBUGMSG(("untgz: error writing, skipping %s", fname)); fclose(outfile); g_unlink(fname); } } remaining -= bytes; if (remaining == 0) { getheader = 1; if (outfile != NULL) { // TODO: should actually set proper time from archive, oh well fclose(outfile); outfile = NULL; } } } // if (getheader == 1) else end } if (tarball != NULL) gzclose(tarball); return 0; }
CURLcode Curl_getFormData(struct FormData **finalform, struct curl_httppost *post, curl_off_t *sizep) { struct FormData *form = NULL; struct FormData *firstform; struct curl_httppost *file; CURLcode result = CURLE_OK; curl_off_t size=0; /* support potentially ENORMOUS formposts */ char *boundary; char *fileboundary=NULL; struct curl_slist* curList; *finalform=NULL; /* default form is empty */ if(!post) return result; /* no input => no output! */ boundary = Curl_FormBoundary(); if(!boundary) return CURLE_OUT_OF_MEMORY; /* Make the first line of the output */ result = AddFormDataf(&form, NULL, "Content-Type: multipart/form-data;" " boundary=%s\r\n", boundary); if (result) { free(boundary); return result; } /* we DO NOT include that line in the total size of the POST, since it'll be part of the header! */ firstform = form; do { if(size) { result = AddFormDataf(&form, &size, "\r\n"); if (result) break; } /* boundary */ result = AddFormDataf(&form, &size, "--%s\r\n", boundary); if (result) break; result = AddFormDataf(&form, &size, "Content-Disposition: form-data; name=\""); if (result) break; result = AddFormData(&form, FORM_DATA, post->name, post->namelength, &size); if (result) break; result = AddFormDataf(&form, &size, "\""); if (result) break; if(post->more) { /* If used, this is a link to more file names, we must then do the magic to include several files with the same field name */ fileboundary = Curl_FormBoundary(); result = AddFormDataf(&form, &size, "\r\nContent-Type: multipart/mixed," " boundary=%s\r\n", fileboundary); if (result) break; } file = post; do { /* If 'showfilename' is set, that is a faked name passed on to us to use to in the formpost. If that is not set, the actually used local file name should be added. */ if(post->more) { /* if multiple-file */ char *filebasename= (!file->showfilename)?strippath(file->contents):NULL; result = AddFormDataf(&form, &size, "\r\n--%s\r\nContent-Disposition: " "attachment; filename=\"%s\"", fileboundary, (file->showfilename?file->showfilename: filebasename)); if (filebasename) free(filebasename); if (result) break; } else if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_BUFFER)) { char *filebasename= (!post->showfilename)?strippath(post->contents):NULL; result = AddFormDataf(&form, &size, "; filename=\"%s\"", (post->showfilename?post->showfilename: filebasename)); if (filebasename) free(filebasename); if (result) break; } if(file->contenttype) { /* we have a specified type */ result = AddFormDataf(&form, &size, "\r\nContent-Type: %s", file->contenttype); if (result) break; } curList = file->contentheader; while( curList ) { /* Process the additional headers specified for this form */ result = AddFormDataf( &form, &size, "\r\n%s", curList->data ); if (result) break; curList = curList->next; } if (result) { Curl_formclean(firstform); free(boundary); return result; } #if 0 /* The header Content-Transfer-Encoding: seems to confuse some receivers * (like the built-in PHP engine). While I can't see any reason why it * should, I can just as well skip this to the benefit of the users who * are using such confused receivers. */ if(file->contenttype && !checkprefix("text/", file->contenttype)) { /* this is not a text content, mention our binary encoding */ size += AddFormData(&form, "\r\nContent-Transfer-Encoding: binary", 0); } #endif result = AddFormDataf(&form, &size, "\r\n\r\n"); if (result) break; if((post->flags & HTTPPOST_FILENAME) || (post->flags & HTTPPOST_READFILE)) { /* we should include the contents from the specified file */ FILE *fileread; fileread = strequal("-", file->contents)? stdin:fopen(file->contents, "rb"); /* binary read for win32 */ /* * VMS: This only allows for stream files on VMS. Stream files are * OK, as are FIXED & VAR files WITHOUT implied CC For implied CC, * every record needs to have a \n appended & 1 added to SIZE */ if(fileread) { if(fileread != stdin) { /* close the file again */ fclose(fileread); /* add the file name only - for later reading from this */ result = AddFormData(&form, FORM_FILE, file->contents, 0, &size); } else { /* When uploading from stdin, we can't know the size of the file, * thus must read the full file as before. We *could* use chunked * transfer-encoding, but that only works for HTTP 1.1 and we * can't be sure we work with such a server. */ size_t nread; char buffer[512]; while((nread = fread(buffer, 1, sizeof(buffer), fileread))) { result = AddFormData(&form, FORM_DATA, buffer, nread, &size); if (result) break; } } if (result) { Curl_formclean(firstform); free(boundary); return result; } } else { Curl_formclean(firstform); free(boundary); *finalform = NULL; return CURLE_READ_ERROR; } } else if (post->flags & HTTPPOST_BUFFER) { /* include contents of buffer */ result = AddFormData(&form, FORM_DATA, post->buffer, post->bufferlength, &size); if (result) break; } else { /* include the contents we got */ result = AddFormData(&form, FORM_DATA, post->contents, post->contentslength, &size); if (result) break; } } while((file = file->more)); /* for each specified file for this field */ if (result) { Curl_formclean(firstform); free(boundary); return result; } if(post->more) { /* this was a multiple-file inclusion, make a termination file boundary: */ result = AddFormDataf(&form, &size, "\r\n--%s--", fileboundary); free(fileboundary); if (result) break; } } while((post=post->next)); /* for each field */ if (result) { Curl_formclean(firstform); free(boundary); return result; } /* end-boundary for everything */ result = AddFormDataf(&form, &size, "\r\n--%s--\r\n", boundary); if (result) { Curl_formclean(firstform); free(boundary); return result; } *sizep = size; free(boundary); *finalform=firstform; return result; }
int main(int argc, char **argv) { /* Command line parsing */ int opt; unsigned port = 0; unsigned step = 128; enum { INVALID, PEEK, POKE, SCREEN } mode = INVALID; const char *name = strippath(argv[0]); if (strcmp(name, "fw_peek") == 0) { mode = PEEK; } else if (strcmp(name, "fw_poke") == 0) { mode = POKE; #ifndef NO_FW_SCREEN } else if (strcmp(name, "fw_screen") == 0) { mode = SCREEN; #endif } if (mode == INVALID) { fprintf(stderr, "Could not decide, whether we are fw_peek or fw_poke.\n"); return EXIT_FAILURE; } while ((opt = getopt(argc, argv, "p:b:")) != -1) { switch (opt) { case 'p': port = strtoul(optarg, 0, 0); break; case 'b': step = strtoul(optarg, 0, 0); break; default: goto print_usage; } } if (((mode == PEEK) && (argc - optind) != 3) || ((mode == POKE) && (argc - optind) != 2) || ((mode == SCREEN) && (argc - optind) != 5)) { print_usage: fprintf(stderr, (mode == PEEK) ? usage_peek : (mode == POKE) ? usage_poke : usage_screen, name); return EXIT_FAILURE; } uint64_t guid = strtoull(argv[optind], NULL, 0); uint64_t address = strtoull(argv[optind + 1], NULL, 0); uint64_t length; uint32_t width, height, depth; if (mode == PEEK) length = strtoull(argv[optind + 2], NULL, 0); if (mode == SCREEN) { width = strtoul(argv[optind + 2], NULL, 0); height = strtoul(argv[optind + 3], NULL, 0); depth = strtoul(argv[optind + 4], NULL, 0); length = 1ULL * depth / 8 * width * height; } raw1394handle_t fw_handle = raw1394_new_handle_on_port(port); if (fw_handle == NULL) { perror("raw1394_new_handle_on_port"); return EXIT_FAILURE; } nodeid_t target; // 63 is broadcast. Ignore that. if (guid < 63) { // GUID is actually a node number. target = LOCAL_BUS | (nodeid_t)guid; } else { for (unsigned no = 0; no < 63; no++) { nodeid_t test_node = LOCAL_BUS | (nodeid_t)no; uint32_t guid_hi; uint32_t guid_lo; int res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 4*4, 4, &guid_lo); if (res != 0) { perror("read guid_lo"); return -1; } res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 3*4, 4, &guid_hi); if (res != 0) { perror("read guid_hi"); return -1; } uint64_t test_guid = (uint64_t)ntohl(guid_hi) << 32 | ntohl(guid_lo); if (test_guid == guid) { target = test_node; goto target_found; } } return -1; target_found: ; } quadlet_t buf[step/sizeof(quadlet_t)]; switch (mode) { case SCREEN: #ifndef NO_FW_SCREEN { if (SDL_Init(SDL_INIT_VIDEO) < 0) { perror("init sdl"); return -1; } SDL_Surface *screen = SDL_SetVideoMode(width, height, depth, SDL_SWSURFACE); if (!screen) { perror("sdl video mode"); return -1; } while (true) { quadlet_t * buf = reinterpret_cast<quadlet_t *>(screen->pixels); for (uint64_t cur = address; cur < address+length; cur += step, buf += step/sizeof(quadlet_t)) { size_t size = (cur + step > address+length) ? (address+length - cur) : step; int res = raw1394_read(fw_handle, target, cur, size, buf); if (res != 0) { perror("read data"); return EXIT_FAILURE; } } SDL_UpdateRect(screen, 0, 0, width, height); SDL_Delay(500); SDL_Event event; if (SDL_PollEvent(&event)) if (event.type == SDL_QUIT) exit(1); } } break; #else abort(); #endif // NO_FW_SCREEN case PEEK: for (uint64_t cur = address; cur < address+length; cur += step) { size_t size = (cur + step > address+length) ? (address+length - cur) : step; int tries = 5; again: int res = raw1394_read(fw_handle, target, cur, size, buf); if (res != 0) { if (tries-- > 0) goto again; perror("read data"); return EXIT_FAILURE; } if (write(STDOUT_FILENO, buf, size) < 0) { perror("write"); return EXIT_FAILURE; } } break; case POKE: for (uint64_t cur = address;;cur += step) { ssize_t size = read(STDIN_FILENO, buf, step); if (size == 0) break; if (size < 0) { perror("read"); return EXIT_FAILURE; } int res = raw1394_write(fw_handle, target, cur, size, buf); if (res != 0) { perror("write data"); return EXIT_FAILURE; } if (size < step) break; } } return 0; }
int main(int argc, char **argv) { /* Command line parsing */ int opt; unsigned port = 0; unsigned step = 128; enum { INVALID, PEEK, POKE } mode = INVALID; const char *name = strippath(argv[0]); if (strcmp(name, "fw_peek") == 0) { mode = PEEK; } else if (strcmp(name, "fw_poke") == 0) { mode = POKE; } if (mode == INVALID) { fprintf(stderr, "Could not decide, whether we are fw_peek or fw_poke.\n"); return EXIT_FAILURE; } while ((opt = getopt(argc, argv, "p:b:")) != -1) { switch (opt) { case 'p': port = strtoul(optarg, 0, 0); break; case 'b': step = strtoul(optarg, 0, 0); break; default: goto print_usage; } } if (((mode == PEEK) && (argc - optind) != 3) || ((mode == POKE) && (argc - optind) != 2)) { print_usage: fprintf(stderr, (mode == PEEK) ? usage_peek : usage_poke, name); return EXIT_FAILURE; } uint64_t guid = strtoull(argv[optind], NULL, 0); uint64_t address = strtoull(argv[optind + 1], NULL, 0); uint64_t length; if (mode == PEEK) length = strtoull(argv[optind + 2], NULL, 0); raw1394handle_t fw_handle = raw1394_new_handle_on_port(port); if (fw_handle == NULL) { perror("raw1394_new_handle_on_port"); return EXIT_FAILURE; } nodeid_t target; // 63 is broadcast. Ignore that. if (guid < 63) { // GUID is actually a node number. target = LOCAL_BUS | (nodeid_t)guid; } else { for (unsigned no = 0; no < 63; no++) { nodeid_t test_node = LOCAL_BUS | (nodeid_t)no; uint32_t guid_hi; uint32_t guid_lo; int res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 4*4, 4, &guid_lo); if (res != 0) { perror("read guid_lo"); return -1; } res = raw1394_read(fw_handle, test_node, CSR_REGISTER_BASE + CSR_CONFIG_ROM + 3*4, 4, &guid_hi); if (res != 0) { perror("read guid_hi"); return -1; } uint64_t test_guid = (uint64_t)ntohl(guid_hi) << 32 | ntohl(guid_lo); if (test_guid == guid) { target = test_node; goto target_found; } } return -1; target_found: ; } quadlet_t buf[step/sizeof(quadlet_t)]; switch (mode) { case PEEK: for (uint64_t cur = address; cur < address+length; cur += step) { size_t size = (cur + step > address+length) ? (address+length - cur) : step; int tries = 5; again: int res = raw1394_read(fw_handle, target, cur, size, buf); if (res != 0) { if (tries-- > 0) goto again; perror("read data"); return EXIT_FAILURE; } if (write(STDOUT_FILENO, buf, size) < 0) { perror("write"); return EXIT_FAILURE; } } break; case POKE: for (uint64_t cur = address;;cur += step) { ssize_t size = read(STDIN_FILENO, buf, step); if (size == 0) break; if (size < 0) { perror("read"); return EXIT_FAILURE; } int res = raw1394_write(fw_handle, target, cur, size, buf); if (res != 0) { perror("write data"); return EXIT_FAILURE; } if (size < step) break; } } return 0; }
/* update the directory with the archive */ static gboolean update(char *path) { struct rdup *rdup_entry; size_t line, i, pathsize; size_t pathlen; char *buf, *pathbuf, *n, *p; char delim; gboolean ok; GHashTable *uidhash; /* holds username -> uid */ GHashTable *gidhash; /* holds groupname -> gid */ p = NULL; buf = g_malloc(BUFSIZE + 1); pathbuf = g_malloc(BUFSIZE + 1); i = BUFSIZE; delim = '\n'; line = 0; ok = TRUE; uidhash = g_hash_table_new(g_str_hash, g_str_equal); gidhash = g_hash_table_new(g_str_hash, g_str_equal); if (path) pathlen = strlen(path); else pathlen = 0; while ((rdup_getdelim(&buf, &i, delim, stdin)) != -1) { line++; n = strrchr(buf, '\n'); if (n) *n = '\0'; if (!(rdup_entry = parse_entry(buf, line))) { /* msgs from entry.c */ exit(EXIT_FAILURE); } /* we have a valid entry, read the filename */ pathsize = fread(pathbuf, sizeof(char), rdup_entry->f_name_size, stdin); if (pathsize != rdup_entry->f_name_size) { msg(_ ("Reported name size (%zd) does not match actual name size (%zd)"), rdup_entry->f_name_size, pathsize); exit(EXIT_FAILURE); } pathbuf[pathsize] = '\0'; if (pathbuf[0] != '/') { msg(_("Pathname does not start with /: `%s\'"), pathbuf); exit(EXIT_FAILURE); } rdup_entry->f_name = pathbuf; /* extract target from rdup_entry */ if (S_ISLNK(rdup_entry->f_mode) || rdup_entry->f_lnk) { // filesize is spot where to cut rdup_entry->f_name[rdup_entry->f_size] = '\0'; rdup_entry->f_target = rdup_entry->f_name + rdup_entry->f_size + 4; } else { rdup_entry->f_target = NULL; } /* strippath must be inserted here */ if (opt_strip) strippath(rdup_entry); if (opt_path_strip) strippathname(rdup_entry); if (!rdup_entry->f_name) p = NULL; else { /* avoid // at the beginning */ if ((pathlen == 1 && path[0] == '/') || pathlen == 0) { p = g_strdup(rdup_entry->f_name); } else { g_free(p); p = g_strdup_printf("%s%s", path, rdup_entry->f_name); rdup_entry->f_name_size += pathlen; if (S_ISLNK(rdup_entry->f_mode) || rdup_entry->f_lnk) rdup_entry->f_size += pathlen; } } rdup_entry->f_name = p; if (mk_obj(stdin, path, rdup_entry, uidhash, gidhash) == FALSE) ok = FALSE; g_free(rdup_entry->f_user); g_free(rdup_entry->f_group); g_free(rdup_entry); } /* post-process hardlinks */ if (mk_hlink(hlink_list) == FALSE) ok = FALSE; g_free(buf); g_free(pathbuf); return ok; }