/* {{{ MongoCursor::addOption */ PHP_METHOD(MongoCursor, addOption) { char *key; int key_len; zval *query, *value; mongo_cursor *cursor; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &key, &key_len, &value) == FAILURE) { return; } cursor = (mongo_cursor*)zend_object_store_get_object(getThis() TSRMLS_CC); MONGO_CHECK_INITIALIZED(cursor->link, MongoCursor); if (cursor->started_iterating) { zend_throw_exception(mongo_ce_CursorException, "cannot modify cursor after beginning iteration.", 0 TSRMLS_CC); return; } make_special(cursor); query = cursor->query; add_assoc_zval(query, key, value); zval_add_ref(&value); RETURN_ZVAL(getThis(), 1, 0); }
void gcl_init_num_rand(void) { Vrandom_state = make_special("*RANDOM-STATE*", make_random_state(Ct)); make_function("RANDOM", Lrandom); make_function("MAKE-RANDOM-STATE", Lmake_random_state); make_function("RANDOM-STATE-P", Lrandom_state_p); }
/* Read a local directory and create the same tree in the generated filesystem. Calls itself recursively with each directory in the given directory. full_path is an absolute or relative path, with a trailing slash, to the directory on disk that should be copied, or NULL if this is a directory that does not exist on disk (e.g. lost+found). dir_path is an absolute path, with trailing slash, to the same directory if the image were mounted at the specified mount point */ static u32 build_directory_structure(const char *full_path, const char *dir_path, u32 dir_inode, fs_config_func_t fs_config_func, int verbose, time_t fixed_time) { int entries = 0; struct dentry *dentries; struct dirent **namelist = NULL; struct stat stat; int ret; int i; u32 inode; u32 entry_inode; u32 dirs = 0; bool needs_lost_and_found = false; /* alphasort is locale-dependent; let's fix the locale to some sane value */ setlocale(LC_ALL, "C"); if (full_path) { entries = scandir(full_path, &namelist, filter_dot, (void*)alphasort); if (entries < 0) { #ifdef __GLIBC__ /* The scandir function implemented in glibc has a bug that makes it erroneously fail with ENOMEM under certain circumstances. As a workaround we can retry the scandir call with the same arguments. GLIBC BZ: https://sourceware.org/bugzilla/show_bug.cgi?id=17804 */ if (errno == ENOMEM) entries = scandir(full_path, &namelist, filter_dot, (void*)alphasort); #endif if (entries < 0) { error_errno("scandir"); return EXT4_ALLOCATE_FAILED; } } } if (dir_inode == 0) { /* root directory, check if lost+found already exists */ for (i = 0; i < entries; i++) if (strcmp(namelist[i]->d_name, "lost+found") == 0) break; if (i == entries) needs_lost_and_found = true; } dentries = calloc(entries, sizeof(struct dentry)); if (dentries == NULL) critical_error_errno("malloc"); for (i = 0; i < entries; i++) { dentries[i].filename = strdup(namelist[i]->d_name); if (dentries[i].filename == NULL) critical_error_errno("strdup"); asprintf(&dentries[i].path, "%s%s", dir_path, namelist[i]->d_name); asprintf(&dentries[i].full_path, "%s%s", full_path, namelist[i]->d_name); free(namelist[i]); ret = lstat(dentries[i].full_path, &stat); if (ret < 0) { error_errno("lstat"); i--; entries--; continue; } dentries[i].size = stat.st_size; dentries[i].mode = stat.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); if (fixed_time == -1) { dentries[i].mtime = stat.st_mtime; } else { dentries[i].mtime = fixed_time; } uint64_t capabilities; if (fs_config_func != NULL) { unsigned int mode = 0; unsigned int uid = 0; unsigned int gid = 0; int dir = S_ISDIR(stat.st_mode); if (fs_config_func(dentries[i].path, dir, &uid, &gid, &mode, &capabilities)) { dentries[i].mode = mode; dentries[i].uid = uid; dentries[i].gid = gid; dentries[i].capabilities = capabilities; } } if (S_ISREG(stat.st_mode)) { dentries[i].file_type = EXT4_FT_REG_FILE; } else if (S_ISDIR(stat.st_mode)) { dentries[i].file_type = EXT4_FT_DIR; dirs++; } else if (S_ISCHR(stat.st_mode)) { dentries[i].file_type = EXT4_FT_CHRDEV; } else if (S_ISBLK(stat.st_mode)) { dentries[i].file_type = EXT4_FT_BLKDEV; } else if (S_ISFIFO(stat.st_mode)) { dentries[i].file_type = EXT4_FT_FIFO; } else if (S_ISSOCK(stat.st_mode)) { dentries[i].file_type = EXT4_FT_SOCK; } else if (S_ISLNK(stat.st_mode)) { dentries[i].file_type = EXT4_FT_SYMLINK; dentries[i].link = calloc(info.block_size, 1); readlink(dentries[i].full_path, dentries[i].link, info.block_size - 1); } else { error("unknown file type on %s", dentries[i].path); i--; entries--; } } free(namelist); if (needs_lost_and_found) { /* insert a lost+found directory at the beginning of the dentries */ struct dentry *tmp = calloc(entries + 1, sizeof(struct dentry)); memset(tmp, 0, sizeof(struct dentry)); memcpy(tmp + 1, dentries, entries * sizeof(struct dentry)); dentries = tmp; dentries[0].filename = strdup("lost+found"); asprintf(&dentries[0].path, "%slost+found", dir_path); dentries[0].full_path = NULL; dentries[0].size = 0; dentries[0].mode = S_IRWXU; dentries[0].file_type = EXT4_FT_DIR; dentries[0].uid = 0; dentries[0].gid = 0; entries++; dirs++; } inode = make_directory(dir_inode, entries, dentries, dirs); for (i = 0; i < entries; i++) { if (dentries[i].file_type == EXT4_FT_REG_FILE) { entry_inode = make_file(dentries[i].full_path, dentries[i].size); } else if (dentries[i].file_type == EXT4_FT_DIR) { char *subdir_full_path = NULL; char *subdir_dir_path; if (dentries[i].full_path) { ret = asprintf(&subdir_full_path, "%s/", dentries[i].full_path); if (ret < 0) critical_error_errno("asprintf"); } ret = asprintf(&subdir_dir_path, "%s/", dentries[i].path); if (ret < 0) critical_error_errno("asprintf"); entry_inode = build_directory_structure(subdir_full_path, subdir_dir_path, inode, fs_config_func, verbose, fixed_time); free(subdir_full_path); free(subdir_dir_path); } else if (dentries[i].file_type == EXT4_FT_SYMLINK) { entry_inode = make_link(dentries[i].link); } else if (dentries[i].file_type == EXT4_FT_CHRDEV || dentries[i].file_type == EXT4_FT_BLKDEV || dentries[i].file_type == EXT4_FT_SOCK || dentries[i].file_type == EXT4_FT_FIFO) { entry_inode = make_special(dentries[i].full_path); } else { error("unknown file type on %s", dentries[i].path); entry_inode = 0; } *dentries[i].inode = entry_inode; ret = inode_set_permissions(entry_inode, dentries[i].mode, dentries[i].uid, dentries[i].gid, dentries[i].mtime); if (ret) error("failed to set permissions on %s\n", dentries[i].path); ret = inode_set_capabilities(entry_inode, dentries[i].capabilities); if (ret) error("failed to set capability on %s\n", dentries[i].path); free(dentries[i].path); free(dentries[i].full_path); free(dentries[i].link); free((void *)dentries[i].filename); } free(dentries); return inode; }