void put(PtrLen<const char> str) { if( str.len>=Len ) { put_full(str.suffix(Len)); } else { put_short(str); } }
static void read_files(metafile_t *m, queue_t *q, unsigned char *pos) { int fd; /* file descriptor */ flist_t *f; /* pointer to a place in the file list */ ssize_t r = 0; /* number of bytes read from file(s) into the read buffer */ #ifndef NO_HASH_CHECK off_t counter = 0; /* number of bytes hashed should match size when done */ #endif piece_t *p = get_free(q, m->piece_length); /* go through all the files in the file list */ for (f = m->file_list; f; f = f->next) { /* open the current file for reading */ if ((fd = open(f->path, OPENFLAGS)) == -1) { fprintf(stderr, "Error opening '%s' for reading: %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } while (1) { ssize_t d = read(fd, p->data + r, m->piece_length - r); if (d < 0) { fprintf(stderr, "Error reading from '%s': %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } if (d == 0) /* end of file */ break; r += d; if (r == m->piece_length) { p->dest = pos; p->len = m->piece_length; put_full(q, p); pos += SHA_DIGEST_LENGTH; #ifndef NO_HASH_CHECK counter += r; #endif r = 0; p = get_free(q, m->piece_length); } } /* now close the file */ if (close(fd)) { fprintf(stderr, "Error closing '%s': %s\n", f->path, strerror(errno)); exit(EXIT_FAILURE); } } /* finally append the hash of the last irregular piece to the hash string */ if (r) { p->dest = pos; p->len = r; put_full(q, p); } else put_free(q, p, 0); #ifndef NO_HASH_CHECK counter += r; if (counter != m->size) { fprintf(stderr, "Counted %" PRIoff " bytes, " "but hashed %" PRIoff " bytes. " "Something is wrong...\n", m->size, counter); exit(EXIT_FAILURE); } #endif }