int do_fs_walk(const char *file, int ignore_symlinks) { char *newfile; struct stat st; struct dirent *ent; DIR *dir; if (lstat(file, &st)) call_error_handler("stat %s", file); if (S_ISLNK(st.st_mode) && ignore_symlinks) return 0; single_file_processor(file, &st); if (!S_ISDIR(st.st_mode)) return 0; dir = opendir(file); if (!dir) call_error_handler("opendir %s", file); while ((ent = readdir(dir))) { char *fname = ent->d_name; if (!strcmp(fname, ".") || !strcmp(fname, "..")) continue; if (asprintf(&newfile, "%s/%s", file, fname) >= 0) { do_fs_walk(newfile, ignore_symlinks); free(newfile); } else { fprintf(stderr, "asprintf failed\n"); exit(1); } } closedir(dir); // directory metadata is resent; this makes the code simple, // and the atime/mtime is set correctly at the second time single_file_processor(file, &st); return 0; }
void wait_for_result(void) { struct result_header hdr; struct result_header_ext hdr_ext; char last_filename[MAX_PATH_LENGTH + 1]; char last_filename_prefix[] = "; Last file: "; if (!read_all(0, &hdr, sizeof(hdr))) { if (errno == EAGAIN) { // no result sent and stdin still open return; } else { // other read error or EOF exit(1); // hopefully remote has produced error message } } if (!read_all(0, &hdr_ext, sizeof(hdr_ext))) { // remote used old result_header struct hdr_ext.last_namelen = 0; } if (hdr_ext.last_namelen > MAX_PATH_LENGTH) { // read only at most MAX_PATH_LENGTH chars hdr_ext.last_namelen = MAX_PATH_LENGTH; } if (!read_all(0, last_filename, hdr_ext.last_namelen)) { fprintf(stderr, "Failed to get last filename\n"); hdr_ext.last_namelen = 0; } last_filename[hdr_ext.last_namelen] = '\0'; if (!hdr_ext.last_namelen) /* set prefix to empty string */ last_filename_prefix[0] = '\0'; errno = hdr.error_code; if (hdr.error_code != 0) { switch (hdr.error_code) { case EEXIST: call_error_handler("File copy: not overwriting existing file. Clean QubesIncoming dir, and retry copy%s%s", last_filename_prefix, last_filename); break; case EINVAL: call_error_handler("File copy: Corrupted data from packer%s%s", last_filename_prefix, last_filename); break; case EDQUOT: if (ignore_quota_error) { /* skip also CRC check as sender and receiver might be * desynchronized in this case */ return; } /* fall though */ default: call_error_handler("File copy: %s%s%s", strerror(hdr.error_code), last_filename_prefix, last_filename); } } if (hdr.crc32 != crc32_sum) { call_error_handler("File transfer failed: checksum mismatch"); } }
int single_file_processor(const char *filename, const struct stat *st) { struct file_header hdr; int fd; mode_t mode = st->st_mode; hdr.namelen = strlen(filename) + 1; hdr.mode = mode; hdr.atime = st->st_atim.tv_sec; hdr.atime_nsec = st->st_atim.tv_nsec; hdr.mtime = st->st_mtim.tv_sec; hdr.mtime_nsec = st->st_mtim.tv_nsec; if (S_ISREG(mode)) { int ret; fd = open(filename, O_RDONLY); if (fd < 0) call_error_handler("open %s", filename); hdr.filelen = st->st_size; write_headers(&hdr, filename); ret = copy_file(1, fd, hdr.filelen, &crc32_sum); if (ret != COPY_FILE_OK) { if (ret != COPY_FILE_WRITE_ERROR) call_error_handler("Copying file %s: %s", filename, copy_file_status_to_str(ret)); else { set_block(0); wait_for_result(); exit(1); } } close(fd); } if (S_ISDIR(mode)) { hdr.filelen = 0; write_headers(&hdr, filename); } if (S_ISLNK(mode)) { char name[st->st_size + 1]; if (readlink(filename, name, sizeof(name)) != st->st_size) call_error_handler("readlink %s", filename); hdr.filelen = st->st_size; write_headers(&hdr, filename); if (!write_all_with_crc(1, name, st->st_size)) { set_block(0); wait_for_result(); exit(1); } } // check for possible error from qfile-unpacker wait_for_result(); return 0; }
void gmx_fatal_mpi_va(int /*f_errno*/, const char *file, int line, gmx_bool bMaster, gmx_bool bFinalize, const char *fmt, va_list ap) { if (bMaster) { char msg[STRLEN]; vsprintf(msg, fmt, ap); call_error_handler("fatal", file, line, msg); } ExitType exitType = ExitType_CleanExit; if (!bFinalize) { exitType = bMaster ? ExitType_Abort : ExitType_NonMasterAbort; } gmx_exit_on_fatal_error(exitType, 1); }
void _gmx_error(const char *key, const char *msg, const char *file, int line) { call_error_handler(key, file, line, msg); gmx_exit_on_fatal_error(ExitType_Abort, 1); }