/* unpack element from buffer and return number of bytes read */ static size_t list_elem_unpack2(const void* buf, elem_t* elem) { /* set pointer to start of buffer */ const char* start = (const char*) buf; const char* ptr = start; /* extract detail field */ uint32_t detail; mfu_unpack_uint32(&ptr, &detail); /* extract length of file name field */ uint32_t chars; mfu_unpack_uint32(&ptr, &chars); /* get name and advance pointer */ const char* file = ptr; ptr += chars; /* copy path */ elem->file = MFU_STRDUP(file); /* set depth */ elem->depth = mfu_flist_compute_depth(file); elem->detail = (int) detail; if (detail) { /* extract fields */ mfu_unpack_uint64(&ptr, &elem->mode); mfu_unpack_uint64(&ptr, &elem->uid); mfu_unpack_uint64(&ptr, &elem->gid); mfu_unpack_uint64(&ptr, &elem->atime); mfu_unpack_uint64(&ptr, &elem->atime_nsec); mfu_unpack_uint64(&ptr, &elem->mtime); mfu_unpack_uint64(&ptr, &elem->mtime_nsec); mfu_unpack_uint64(&ptr, &elem->ctime); mfu_unpack_uint64(&ptr, &elem->ctime_nsec); mfu_unpack_uint64(&ptr, &elem->size); /* use mode to set file type */ elem->type = mfu_flist_mode_to_filetype((mode_t)elem->mode); } else { /* only have type */ uint32_t type; mfu_unpack_uint32(&ptr, &type); elem->type = (mfu_filetype) type; } size_t bytes = (size_t)(ptr - start); return bytes; }
static void mfu_unpack_param(const char** pptr, mfu_param_path* param) { /* initialize all values */ mfu_param_path_init(param); /* unpack original path */ mfu_unpack_str(pptr, ¶m->orig); /* unpack reduced path */ mfu_unpack_str(pptr, ¶m->path); /* unpack reduce path stat data */ if (param->path != NULL) { uint32_t val; mfu_unpack_uint32(pptr, &val); param->path_stat_valid = (int) val; if (param->path_stat_valid) { mfu_unpack_stat(pptr, ¶m->path_stat); } } /* unpack target path */ mfu_unpack_str(pptr, ¶m->target); /* unpack target path stat data */ if (param->target != NULL) { uint32_t val; mfu_unpack_uint32(pptr, &val); param->target_stat_valid = (int) val; if (param->target_stat_valid) { mfu_unpack_stat(pptr, ¶m->target_stat); } } return; }
/* unpack a string from a buffer, and return as newly allocated memory, * caller must free returned string */ static void mfu_unpack_str(const char** pptr, char** pstr) { /* assume we don't have a string */ *pstr = NULL; /* unpack the flag */ uint32_t flag; mfu_unpack_uint32(pptr, &flag); /* if we have a string, unpack the string */ if (flag) { /* make a copy of the string to return to caller */ const char* str = *pptr; *pstr = MFU_STRDUP(str); /* advance caller's pointer */ size_t len = strlen(str) + 1; *pptr += len; } return; }