uint32_t ymd_file_filter(const char *name, const char *path, uint32_t keep_mask, mode_t ymd_mode, uid_t ymd_uid, gid_t ymd_gid) { asl_file_t *f = NULL; uint8_t km = keep_mask; uint32_t status, len, dstcount = 0; char src[MAXPATHLEN]; char dst[MAXPATHLEN]; if (snprintf(src, MAXPATHLEN, "%s/%s", path, name) >= MAXPATHLEN) return ASL_STATUS_FAILED; if (snprintf(dst, MAXPATHLEN, "%s/%s", path, name) >= MAXPATHLEN) return ASL_STATUS_FAILED; len = strlen(src) - 3; snprintf(dst + len, 4, "tmp"); //TODO: check if src file is already filtered debug_log(ASL_LEVEL_NOTICE, " filter %s %s ---> %s\n", src, keep_str(km), dst); status = ASL_STATUS_OK; if (dryrun == 0) { status = asl_file_open_read(name, &f); if (status != ASL_STATUS_OK) return status; status = asl_file_filter_level(f, dst, keep_mask, ymd_mode, ymd_uid, ymd_gid, &dstcount, aux_url_callback); asl_file_close(f); } filesystem_unlink(src); if ((status != ASL_STATUS_OK) || (dstcount == 0)) filesystem_unlink(dst); else filesystem_rename(dst, src); return status; }
/* move sequenced source files to dst dir, renaming as we go */ static int module_copy_rename(asl_out_dst_data_t *dst) { asl_out_file_list_t *src_list, *dst_list, *f, *dst_last; char *base, *dst_dir; char fpathsrc[MAXPATHLEN], fpathdst[MAXPATHLEN]; uint32_t src_count, dst_count; int32_t x, moved; if (dst == NULL) return -1; if (dst->path == NULL) return -1; base = strrchr(dst->path, '/'); if (base == NULL) return -1; src_list = asl_list_src_files(dst); if (src_list == 0) { debug_log(ASL_LEVEL_INFO, " no src files\n"); return 0; } debug_log(ASL_LEVEL_INFO, " src files\n"); src_count = 0; for (f = src_list; f != NULL; f = f->next) { debug_log(ASL_LEVEL_INFO, " %s\n", f->name); src_count++; } dst_list = asl_list_dst_files(dst); *base = '\0'; base++; dst_dir = dst->rotate_dir; if (dst_dir == NULL) dst_dir = dst->path; dst_count = 0; dst_last = dst_list; if (dst_list == NULL) debug_log(ASL_LEVEL_INFO, " no dst files\n"); else debug_log(ASL_LEVEL_INFO, " dst files\n"); for (f = dst_list; f != NULL; f = f->next) { debug_log(ASL_LEVEL_INFO, " %s\n", f->name); dst_last = f; dst_count++; } if (dst->flags & MODULE_FLAG_STYLE_SEQ) { for (f = dst_last; f != NULL; f = f->prev) { int is_gz = 0; char *dot = strrchr(f->name, '.'); if ((dot != NULL) && (!strcmp(dot, ".gz"))) is_gz = 1; snprintf(fpathsrc, sizeof(fpathsrc), "%s/%s", dst_dir, f->name); snprintf(fpathdst, sizeof(fpathdst), "%s/%s.%d%s", dst_dir, base, f->seq+src_count, (is_gz == 1) ? ".gz" : ""); filesystem_rename(fpathsrc, fpathdst); } for (f = src_list, x = 0; f != NULL; f = f->next, x++) { snprintf(fpathsrc, sizeof(fpathsrc), "%s/%s", dst->path, f->name); snprintf(fpathdst, sizeof(fpathdst), "%s/%s.%d", dst_dir, base, x); moved = filesystem_copy(dst, fpathsrc, fpathdst, dst->flags); if (moved != 0) { if (dst->flags & MODULE_FLAG_TRUNCATE) filesystem_truncate(fpathsrc); else filesystem_unlink(fpathsrc); } } } else { for (f = src_list; f != NULL; f = f->next) { /* final / active base stamped file looks like a checkpointed file - ignore it */ if ((dst->flags & MODULE_FLAG_BASESTAMP) && (f->next == NULL)) break; snprintf(fpathsrc, sizeof(fpathsrc), "%s/%s", dst->path, f->name); /* MODULE_FLAG_EXTERNAL files are not decorated with a timestamp */ if (dst->flags & MODULE_FLAG_EXTERNAL) { char tstamp[32]; asl_make_timestamp(f->ftime, dst->flags, tstamp, sizeof(tstamp)); snprintf(fpathdst, sizeof(fpathdst), "%s/%s.%s", dst_dir, base, tstamp); } else { snprintf(fpathdst, sizeof(fpathdst), "%s/%s", dst_dir, f->name); } moved = filesystem_copy(dst, fpathsrc, fpathdst, dst->flags); if (moved != 0) { if (dst->flags & MODULE_FLAG_TRUNCATE) filesystem_truncate(fpathsrc); else filesystem_unlink(fpathsrc); } } } asl_out_file_list_free(src_list); asl_out_file_list_free(dst_list); if (base != NULL) *--base = '/'; return 0; }
static void handle_filesystem_request(int so) { int error; int operation; char key[(NAME_MAX + 1) + sizeof(union webdav_request)]; size_t num_bytes; char *bytes; union webdav_reply reply; /* get the request from the socket */ error = get_request(so, &operation, key, sizeof(key)); if ( !error ) { #if DEBUG LogMessage(kTrace, "handle_filesystem_request: %s(%d)\n", (operation==WEBDAV_LOOKUP) ? "LOOKUP" : (operation==WEBDAV_CREATE) ? "CREATE" : (operation==WEBDAV_OPEN) ? "OPEN" : (operation==WEBDAV_CLOSE) ? "CLOSE" : (operation==WEBDAV_GETATTR) ? "GETATTR" : (operation==WEBDAV_SETATTR) ? "SETATTR" : (operation==WEBDAV_READ) ? "READ" : (operation==WEBDAV_WRITE) ? "WRITE" : (operation==WEBDAV_FSYNC) ? "FSYNC" : (operation==WEBDAV_REMOVE) ? "REMOVE" : (operation==WEBDAV_RENAME) ? "RENAME" : (operation==WEBDAV_MKDIR) ? "MKDIR" : (operation==WEBDAV_RMDIR) ? "RMDIR" : (operation==WEBDAV_READDIR) ? "READDIR" : (operation==WEBDAV_STATFS) ? "STATFS" : (operation==WEBDAV_UNMOUNT) ? "UNMOUNT" : (operation==WEBDAV_INVALCACHES) ? "INVALCACHES" : "???", operation ); #endif bzero((void *)&reply, sizeof(union webdav_reply)); /* If the connection is down just return EBUSY, but always let UNMOUNT and INVALCACHES requests */ /* go through regardless of the state of the connection. */ if ( (get_connectionstate() == WEBDAV_CONNECTION_DOWN) && (operation != WEBDAV_UNMOUNT) && (operation != WEBDAV_INVALCACHES) ) { error = ETIMEDOUT; send_reply(so, (void *)&reply, sizeof(union webdav_reply), error); } else { /* call the function to handle the request */ switch ( operation ) { case WEBDAV_LOOKUP: error = filesystem_lookup((struct webdav_request_lookup *)key, (struct webdav_reply_lookup *)&reply); send_reply(so, (void *)&reply, sizeof(struct webdav_reply_lookup), error); break; case WEBDAV_CREATE: error = filesystem_create((struct webdav_request_create *)key, (struct webdav_reply_create *)&reply); send_reply(so, (void *)&reply, sizeof(struct webdav_reply_create), error); break; case WEBDAV_OPEN: error = filesystem_open((struct webdav_request_open *)key, (struct webdav_reply_open *)&reply); send_reply(so, (void *)&reply, sizeof(struct webdav_reply_open), error); break; case WEBDAV_CLOSE: error = filesystem_close((struct webdav_request_close *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_GETATTR: error = filesystem_getattr((struct webdav_request_getattr *)key, (struct webdav_reply_getattr *)&reply); send_reply(so, (void *)&reply, sizeof(struct webdav_reply_getattr), error); break; case WEBDAV_READ: bytes = NULL; num_bytes = 0; error = filesystem_read((struct webdav_request_read *)key, &bytes, &num_bytes); send_reply(so, (void *)bytes, (int)num_bytes, error); if (bytes) { free(bytes); } break; case WEBDAV_FSYNC: error = filesystem_fsync((struct webdav_request_fsync *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_REMOVE: error = filesystem_remove((struct webdav_request_remove *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_RENAME: error = filesystem_rename((struct webdav_request_rename *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_MKDIR: error = filesystem_mkdir((struct webdav_request_mkdir *)key, (struct webdav_reply_mkdir *)&reply); send_reply(so, (void *)&reply, sizeof(struct webdav_reply_mkdir), error); break; case WEBDAV_RMDIR: error = filesystem_rmdir((struct webdav_request_rmdir *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_READDIR: error = filesystem_readdir((struct webdav_request_readdir *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_STATFS: error = filesystem_statfs((struct webdav_request_statfs *)key, (struct webdav_reply_statfs *)&reply); send_reply(so, (void *)&reply, sizeof(struct webdav_reply_statfs), error); break; case WEBDAV_UNMOUNT: webdav_kill(-2); /* tell the main select loop to exit */ send_reply(so, (void *)0, 0, error); break; case WEBDAV_INVALCACHES: error = filesystem_invalidate_caches((struct webdav_request_invalcaches *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_WRITESEQ: error = filesystem_write_seq((struct webdav_request_writeseq *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_DUMP_COOKIES: dump_cookies((struct webdav_request_cookies *)key); send_reply(so, (void *)0, 0, error); break; case WEBDAV_CLEAR_COOKIES: reset_cookies((struct webdav_request_cookies *)key); send_reply(so, (void *)0, 0, error); break; default: error = ENOTSUP; break; } } #if DEBUG LogMessage(kError, "handle_filesystem_request: error %d, %s(%d)\n", error, (operation==WEBDAV_LOOKUP) ? "LOOKUP" : (operation==WEBDAV_CREATE) ? "CREATE" : (operation==WEBDAV_OPEN) ? "OPEN" : (operation==WEBDAV_CLOSE) ? "CLOSE" : (operation==WEBDAV_GETATTR) ? "GETATTR" : (operation==WEBDAV_SETATTR) ? "SETATTR" : (operation==WEBDAV_READ) ? "READ" : (operation==WEBDAV_WRITE) ? "WRITE" : (operation==WEBDAV_FSYNC) ? "FSYNC" : (operation==WEBDAV_REMOVE) ? "REMOVE" : (operation==WEBDAV_RENAME) ? "RENAME" : (operation==WEBDAV_MKDIR) ? "MKDIR" : (operation==WEBDAV_RMDIR) ? "RMDIR" : (operation==WEBDAV_READDIR) ? "READDIR" : (operation==WEBDAV_STATFS) ? "STATFS" : (operation==WEBDAV_UNMOUNT) ? "UNMOUNT" : (operation==WEBDAV_INVALCACHES) ? "INVALCACHES" : "???", operation ); #endif } else { LogMessage(kError, "handle_filesystem_request: get_request failed %d\n", error); send_reply(so, NULL, 0, error); } close(so); }