static void update_one(const char *path) { if (!verify_path(path)) { fprintf(stderr, "Ignoring path %s\n", path); return; } if (mark_valid_only) { if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG)) die("Unable to mark file %s", path); return; } if (mark_skip_worktree_only) { if (mark_ce_flags(path, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG)) die("Unable to mark file %s", path); return; } if (force_remove) { if (remove_file_from_cache(path)) die("git update-index: unable to remove %s", path); report("remove '%s'", path); return; } if (process_path(path)) die("Unable to process path %s", path); report("add '%s'", path); }
static int add_cacheinfo(unsigned int mode, const struct object_id *oid, const char *path, int stage) { int size, len, option; struct cache_entry *ce; if (!verify_path(path)) return error("Invalid path '%s'", path); len = strlen(path); size = cache_entry_size(len); ce = xcalloc(1, size); oidcpy(&ce->oid, oid); memcpy(ce->name, path, len); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = len; ce->ce_mode = create_ce_mode(mode); if (assume_unchanged) ce->ce_flags |= CE_VALID; option = allow_add ? ADD_CACHE_OK_TO_ADD : 0; option |= allow_replace ? ADD_CACHE_OK_TO_REPLACE : 0; if (add_cache_entry(ce, option)) return error("%s: cannot add to the index - missing --add option?", path); report("add '%s'", path); return 0; }
int main(int argc, char **argv) { int i, newfd, entries; entries = read_cache(); if (entries < 0) { perror("cache corrupted"); return -1; } newfd = open(".dircache/index.lock", O_RDWR | O_CREAT | O_EXCL, 0600); if (newfd < 0) { perror("unable to create new cachefile"); return -1; } for (i = 1 ; i < argc; i++) { char *path = argv[i]; if (!verify_path(path)) { fprintf(stderr, "Ignoring path %s\n", argv[i]); continue; } if (add_file_to_cache(path)) { fprintf(stderr, "Unable to add %s to database\n", path); goto out; } } if (!write_cache(newfd, active_cache, active_nr) && !rename(".dircache/index.lock", ".dircache/index")) return 0; out: unlink(".dircache/index.lock"); }
/*===========================================================================* * go_down * *===========================================================================*/ static int go_down( char path[PATH_MAX], /* path to add the name to */ struct inode *parent, /* inode of the current directory */ char *name, /* name of the directory entry */ struct inode **res_ino, /* place to store resulting inode */ struct sffs_attr *attr /* place to store inode attributes */ ) { /* Given a directory inode and a name, progress into a directory entry. */ struct inode *ino; int r, stale = 0; if ((r = push_path(path, name)) != OK) return r; dprintf(("%s: go_down: name '%s', path now '%s'\n", sffs_name, name, path)); ino = lookup_dentry(parent, name); dprintf(("%s: lookup_dentry('%s') returned %p\n", sffs_name, name, ino)); if (ino != NULL) r = verify_path(path, ino, attr, &stale); else r = sffs_table->t_getattr(path, attr); dprintf(("%s: path query returned %d\n", sffs_name, r)); if (r != OK) { if (ino != NULL) { put_inode(ino); ino = NULL; } if (!stale) return r; } dprintf(("%s: name '%s'\n", sffs_name, name)); if (ino == NULL) { if ((ino = get_free_inode()) == NULL) return ENFILE; dprintf(("%s: inode %p ref %d\n", sffs_name, ino, ino->i_ref)); ino->i_flags = MODE_TO_DIRFLAG(attr->a_mode); add_dentry(parent, name, ino); } *res_ino = ino; return OK; }
JournalStore* journal_store_open(JamAccount *acc, gboolean create, GError **err) { JournalStore *js = NULL; char *path = NULL; sqlite3 *db = NULL; int ret; gboolean exists; path = conf_make_account_path(acc, "journal.db"); exists = g_file_test(path, G_FILE_TEST_EXISTS); if (!exists && !create) { g_set_error(err, 0, 0, "No offline copy of this journal."); goto out; } if (!verify_path(path, FALSE, &err)) goto out; ret = sqlite3_open(path, &db); if (ret != SQLITE_OK) { g_set_error(err, 0, 0, "sqlite error %d: %s", ret, sqlite3_errmsg(db)); goto out; } sqlite3_trace(db, sql_trace, NULL); if (exists) { if (!check_version(db)) { g_set_error(err, 0, 0, "The on-disk journal version differs from " "the version understood by this version of LogJam. " "You need to resynchronize your journal."); goto out; } } else { if (!init_db(db, err)) goto out; } js = g_new0(JournalStore, 1); js->account = acc; js->db = db; out: g_free(path); if (!js && db) sqlite3_close(db); return js; }
static void update_one(const char *path) { int stat_errno = 0; struct stat st; if (mark_valid_only || mark_skip_worktree_only || force_remove || mark_fsmonitor_only) st.st_mode = 0; else if (lstat(path, &st) < 0) { st.st_mode = 0; stat_errno = errno; } /* else stat is valid */ if (!verify_path(path, st.st_mode)) { fprintf(stderr, "Ignoring path %s\n", path); return; } if (mark_valid_only) { if (mark_ce_flags(path, CE_VALID, mark_valid_only == MARK_FLAG)) die("Unable to mark file %s", path); return; } if (mark_skip_worktree_only) { if (mark_ce_flags(path, CE_SKIP_WORKTREE, mark_skip_worktree_only == MARK_FLAG)) die("Unable to mark file %s", path); return; } if (mark_fsmonitor_only) { if (mark_ce_flags(path, CE_FSMONITOR_VALID, mark_fsmonitor_only == MARK_FLAG)) die("Unable to mark file %s", path); return; } if (force_remove) { if (remove_file_from_cache(path)) die("git update-index: unable to remove %s", path); report("remove '%s'", path); return; } if (process_path(path, &st, stat_errno)) die("Unable to process path %s", path); report("add '%s'", path); }
int msh_exec(char **args, t_env *tenv) { char *path; char **env; pid_t pid; if ((path = verify_path(tenv, args)) == NULL) return (-1); env = tenv_to_star(tenv); pid = fork(); if (pid == 0) { execve(path, args, env); exit(0); } if (pid > 0) waitpid(pid, 0, 0); ft_strdel(&path); ft_starfree(env); return (0); }
/*===========================================================================* * verify_inode * *===========================================================================*/ int verify_inode( struct inode *ino, /* inode to verify */ char path[PATH_MAX], /* buffer in which to store the path */ struct sffs_attr *attr /* buffer for attributes, or NULL */ ) { /* Given an inode, construct a path identifying the inode, and check whether * that path is still valid for that inode (as far as we can tell). As a side * effect, store attributes in the given attribute structure if not NULL (its * a_mask member must then be set). */ struct sffs_attr attr2; int r; if ((r = make_path(path, ino)) != OK) return r; if (attr == NULL) { attr2.a_mask = 0; attr = &attr2; } return verify_path(path, ino, attr, NULL); }
static void read_index_info(int line_termination) { struct strbuf buf = STRBUF_INIT; struct strbuf uq = STRBUF_INIT; while (strbuf_getline(&buf, stdin, line_termination) != EOF) { char *ptr, *tab; char *path_name; unsigned char sha1[20]; unsigned int mode; unsigned long ul; int stage; /* This reads lines formatted in one of three formats: * * (1) mode SP sha1 TAB path * The first format is what "git apply --index-info" * reports, and used to reconstruct a partial tree * that is used for phony merge base tree when falling * back on 3-way merge. * * (2) mode SP type SP sha1 TAB path * The second format is to stuff "git ls-tree" output * into the index file. * * (3) mode SP sha1 SP stage TAB path * This format is to put higher order stages into the * index file and matches "git ls-files --stage" output. */ errno = 0; ul = strtoul(buf.buf, &ptr, 8); if (ptr == buf.buf || *ptr != ' ' || errno || (unsigned int) ul != ul) goto bad_line; mode = ul; tab = strchr(ptr, '\t'); if (!tab || tab - ptr < 41) goto bad_line; if (tab[-2] == ' ' && '0' <= tab[-1] && tab[-1] <= '3') { stage = tab[-1] - '0'; ptr = tab + 1; /* point at the head of path */ tab = tab - 2; /* point at tail of sha1 */ } else { stage = 0; ptr = tab + 1; /* point at the head of path */ } if (get_sha1_hex(tab - 40, sha1) || tab[-41] != ' ') goto bad_line; path_name = ptr; if (line_termination && path_name[0] == '"') { strbuf_reset(&uq); if (unquote_c_style(&uq, path_name, NULL)) { die("git update-index: bad quoting of path name"); } path_name = uq.buf; } if (!verify_path(path_name)) { fprintf(stderr, "Ignoring path %s\n", path_name); continue; } if (!mode) { /* mode == 0 means there is no such path -- remove */ if (remove_file_from_cache(path_name)) die("git update-index: unable to remove %s", ptr); } else { /* mode ' ' sha1 '\t' name * ptr[-1] points at tab, * ptr[-41] is at the beginning of sha1 */ ptr[-42] = ptr[-1] = 0; if (add_cacheinfo(mode, sha1, path_name, stage)) die("git update-index: unable to update %s", path_name); } continue; bad_line: die("malformed index info %s", buf.buf); } strbuf_release(&buf); strbuf_release(&uq); }
static GString *append_listing(GString *object, const char *name, gboolean pcsuite, size_t *size, int *err) { struct stat fstat, dstat; struct dirent *ep; DIR *dp; gboolean root; int ret; root = g_str_equal(name, obex_option_root_folder()); dp = opendir(name); if (dp == NULL) { if (err) *err = -ENOENT; goto failed; } if (root) object = g_string_append(object, FL_PARENT_FOLDER_ELEMENT); ret = verify_path(name); if (ret < 0) { *err = ret; goto failed; } ret = stat(name, &dstat); if (ret < 0) { if (err) *err = -errno; goto failed; } while ((ep = readdir(dp))) { char *filename; char *fullname; char *line; if (ep->d_name[0] == '.') continue; filename = g_filename_to_utf8(ep->d_name, -1, NULL, NULL, NULL); if (name == NULL) { error("g_filename_to_utf8: invalid filename"); continue; } fullname = g_build_filename(name, ep->d_name, NULL); ret = stat(fullname, &fstat); if (ret < 0) { DBG("stat: %s(%d)", strerror(errno), errno); g_free(filename); g_free(fullname); continue; } g_free(fullname); line = file_stat_line(filename, &fstat, &dstat, root, FALSE); if (line == NULL) { g_free(filename); continue; } g_free(filename); object = g_string_append(object, line); g_free(line); } closedir(dp); object = g_string_append(object, FL_BODY_END); if (size) *size = object->len; if (err) *err = 0; return object; failed: if (dp) closedir(dp); g_string_free(object, TRUE); return NULL; }
char *qdb_read(qdb_handle_t h, char *path, unsigned int *value_len) { struct qdb_hdr hdr; char *value; uint32_t got_data; rw_ret_t ret; if (!h) return NULL; if (!verify_path(path)) return NULL; hdr.type = QDB_CMD_READ; /* already verified string length */ #ifdef WIN32 StringCbCopyA(hdr.path, sizeof(hdr.path), path); #else strcpy(hdr.path, path); #endif hdr.data_len = 0; if (!send_command_to_daemon(h, &hdr, NULL)) /* some fatal error perhaps? */ return NULL; if (!get_response(h, &hdr)) return NULL; /* TODO: make this distinguishable from other errors */ if (hdr.type == QDB_RESP_ERROR_NOENT) { errno = ENOENT; return NULL; } if (hdr.type == QDB_RESP_ERROR) { /* TODO? */ assert(hdr.data_len == 0); return NULL; } assert(hdr.type == QDB_RESP_READ); /* +1 for terminating \0 */ value = malloc(hdr.data_len+1); if (!value) return NULL; got_data = 0; while (got_data < hdr.data_len) { #ifdef WIN32 ret = hdr.data_len - got_data; // this function always reads the requested size if (!QioReadBuffer(h->read_pipe, value+got_data, hdr.data_len-got_data)) { #else ret = read(h->fd, value+got_data, hdr.data_len-got_data); if (ret <= 0) { #endif free(value); return NULL; } got_data += ret; } value[got_data] = '\0'; if (value_len) *value_len = got_data; return value; } char **qdb_list(qdb_handle_t h, char *path, unsigned int *list_len) { struct qdb_hdr hdr; struct path_list *plist = NULL; struct path_list *plist_tmp; int count = 0; char **ret; if (!h) return NULL; if (!verify_path(path)) return NULL; hdr.type = QDB_CMD_LIST; /* already verified string length */ #ifdef WIN32 StringCbCopyA(hdr.path, sizeof(hdr.path), path); #else strcpy(hdr.path, path); #endif hdr.data_len = 0; if (!send_command_to_daemon(h, &hdr, NULL)) /* some fatal error perhaps? */ return NULL; /* receive entries (QDB_RESP_LIST messages) and add them to plist at the * beginning. This means that list will be in reverse order. */ while (1) { if (!get_response(h, &hdr)) { free_path_list(plist); return NULL; } /* TODO: QDB_RESP_ERROR ? (current daemon do not send such response to * list */ assert(hdr.type == QDB_RESP_LIST); if (!hdr.path[0]) /* end of list */ break; plist_tmp = malloc(sizeof(*plist_tmp)); if (!plist_tmp) { /* OOM */ free_path_list(plist); return NULL; } plist_tmp->path = strdup(hdr.path); if (!plist_tmp->path) { /* OOM */ free_path_list(plist); return NULL; } plist_tmp->next = plist; plist = plist_tmp; count++; } ret = malloc((count+1) * sizeof(char*)); if (!ret) { /* OOM */ free_path_list(plist); return NULL; } /* End of table marker */ ret[count] = NULL; if (list_len) *list_len = count; /* write responses to array, in reverse order so entries will be back * sorted */ while (plist && count) { ret[--count] = plist->path; plist_tmp = plist; plist = plist->next; free(plist_tmp); } return ret; } char **qdb_multiread(qdb_handle_t h, char *path, unsigned int **values_len, unsigned int *list_len) { struct qdb_hdr hdr; int count = 0; char *value; uint32_t got_data; char **ret = NULL, **ret2; rw_ret_t read_ret; unsigned int *len_ret = NULL, *len_ret2; if (!h) return NULL; if (!verify_path(path)) return NULL; hdr.type = QDB_CMD_MULTIREAD; /* already verified string length */ #ifdef WIN32 StringCbCopyA(hdr.path, sizeof(hdr.path), path); #else strcpy(hdr.path, path); #endif hdr.data_len = 0; if (!send_command_to_daemon(h, &hdr, NULL)) /* some fatal error perhaps? */ return NULL; /* initial arrays */ ret = malloc(2*sizeof(char*)); if (!ret) { return NULL; } if (values_len) { len_ret = malloc(sizeof(unsigned int)); if (!len_ret) { free(ret); return NULL; } } /* receive entries (QDB_RESP_MULTIREAD messages) */ while (1) { if (!get_response(h, &hdr)) { free(ret); free(len_ret); return NULL; } assert(hdr.type == QDB_RESP_MULTIREAD); if (!hdr.path[0]) /* end of list */ break; /* +1 for terminating \0 */ value = malloc(hdr.data_len+1); if (!value) { free(ret); free(len_ret); return NULL; } got_data = 0; while (got_data < hdr.data_len) { #ifdef WIN32 read_ret = hdr.data_len - got_data; // this function always reads the requested size if (!QioReadBuffer(h->read_pipe, value+got_data, hdr.data_len-got_data)) { #else read_ret = read(h->fd, value+got_data, hdr.data_len-got_data); if (read_ret <= 0) { #endif free(value); free(ret); free(len_ret); return NULL; } got_data += read_ret; } value[got_data] = '\0'; /* (path+value)*count + NULL,NULL * Note that count is still unchanged */ ret2 = realloc(ret, 2*(count+2)*sizeof(char*)); if (!ret2) { free(ret); free(value); free(len_ret); return NULL; } ret = ret2; if (values_len) { len_ret2 = realloc(len_ret, (count+2)*sizeof(unsigned int)); if (!len_ret2) { free(len_ret); free(value); free(ret); return NULL; } len_ret = len_ret2; } /* first path */ ret[2*count] = strdup(hdr.path); /* then data */ ret[2*count+1] = value; /* and data len if requested */ if (values_len) len_ret[count] = hdr.data_len; count++; } /* End of table marker */ ret[2*count] = NULL; ret[2*count+1] = NULL; if (values_len) *values_len = len_ret; if (list_len) *list_len = count; return ret; } /** Write single value to QubesDB, will override existing entry. */ int qdb_write(qdb_handle_t h, char *path, char *value, unsigned int value_len) { struct qdb_hdr hdr; if (!h) return 0; /* daemon will verify data anyway, but check here to return meaningful * error message */ if (!verify_path(path)) return 0; if (!value || value_len > QDB_MAX_DATA) return 0; hdr.type = QDB_CMD_WRITE; /* already verified string length */ #ifdef WIN32 StringCbCopyA(hdr.path, sizeof(hdr.path), path); #else strcpy(hdr.path, path); #endif hdr.data_len = value_len; if (!send_command_to_daemon(h, &hdr, value)) /* some fatal error perhaps? */ return 0; if (!get_response(h, &hdr)) return 0; if (hdr.type == QDB_RESP_ERROR) { /* TODO? */ assert(hdr.data_len == 0); return 0; } assert(hdr.type == QDB_RESP_OK); assert(hdr.data_len == 0); return 1; } /** Common function for simple commands - only path as argument and no return data. * @param h Connection handle * @param path Entry path * @param cmd Command (hdr.type content) * @return 1 on success, 0 on failure */ static int qdb__simple_cmd(qdb_handle_t h, char *path, int cmd) { struct qdb_hdr hdr; if (!h) return 0; if (!verify_path(path)) return 0; hdr.type = cmd; /* already verified string length */ #ifdef WIN32 StringCbCopyA(hdr.path, sizeof(hdr.path), path); #else strcpy(hdr.path, path); #endif hdr.data_len = 0; if (!send_command_to_daemon(h, &hdr, NULL)) /* some fatal error perhaps? */ return 0; if (!get_response(h, &hdr)) return 0; /* TODO: ignore NOENT for now */ if (hdr.type == QDB_RESP_ERROR_NOENT) { return 1; } if (hdr.type == QDB_RESP_ERROR) { /* TODO? */ assert(hdr.data_len == 0); return 0; } assert(hdr.type == QDB_RESP_OK); assert(hdr.data_len == 0); return 1; } int qdb_watch(qdb_handle_t h, char *path) { return qdb__simple_cmd(h, path, QDB_CMD_WATCH); } int qdb_unwatch(qdb_handle_t h, char *path) { return qdb__simple_cmd(h, path, QDB_CMD_UNWATCH); } int qdb_rm(qdb_handle_t h, char *path) { return qdb__simple_cmd(h, path, QDB_CMD_RM); } #ifdef WIN32 HANDLE #else int #endif qdb_watch_fd(qdb_handle_t h) { #ifdef WIN32 /* TODO: begin overlapped read operation and return event handle */ /* TODO: for overlapped read, pipe should be opened in overlapped mode */ return INVALID_HANDLE_VALUE; #else if (!h->connected) { if (!connect_to_daemon(h)) { /* reconnect failed */ errno = EPIPE; return -1; } /* FIXME: register watches again */ } return h->fd; #endif } char *qdb_read_watch(qdb_handle_t h) { struct qdb_hdr hdr; struct path_list *w; char *ret = NULL; int len; if (!h) return 0; /** already received event */ if (h->watch_list) { w = h->watch_list; h->watch_list = w->next; ret = w->path; free(w); } else { #ifdef WIN32 len = sizeof(hdr); if (!QioReadBuffer(h->read_pipe, &hdr, sizeof(hdr))) { #else if ((len=read(h->fd, &hdr, sizeof(hdr))) < sizeof(hdr)) { #endif if (len==0) errno = EPIPE; return NULL; } /* only MULTIREAD is handled with multiple qdb_* calls, so if this * isn't WATCH we missed something */ assert(hdr.type == QDB_RESP_WATCH); ret = strdup(hdr.path); } return ret; } #ifdef WIN32 void qdb_free(void *p) { free(p); }
DataHandler::resource DataHandler::read_resource(std::string path, std::string cookies, DataHandler::resource * data) { // prepend cwd() to path if (!verify_path(path)) path = "/index.html"; std::string cwd = get_working_path(); path = cwd + path; this->logger->debug("Checking resource at: " + path); // first check if such a file even exists int fd = open(path.c_str(), O_RDONLY); if (fd < 0) { char * err = std::strerror(errno); throw DataHandler::FileNotFound("Error while reading file contents at " + path + ": " + std::string(err ? err : "unknown error")); } close(fd); // check mime type of resource DataHandler::Exec runner; std::string args[2] = { "/usr/bin/file", path }; DataHandler::resource file_mime = runner.run_command(args); char * mime = file_mime.data; std::string ext = path.substr(path.length()-3); for(char c : ext) c = std::toupper(c); DataHandler::resource output; // now check for known mime types if (is(mime, "executable")) { // run the script, pass the data std::string args[2] = { path, "" }; // TODO: Fix me too! DataHandler::resource script_output = runner.run_command(args, data, cookies); output.data = script_output.data; output.size = script_output.size; output.type = "executable"; } // TODO: Move this definition to some more reasonable place else if (is(mime, "HTML")) { output.type = "text/html; charset=UTF-8"; } else if (is(mime, "ASCII") && ext == "CSS") { output.type = "text/css"; } else if (is(mime, "ERROR") || is(mime, "ASCII")) { output.type = "text/plain; charset=UTF-8"; } else if (is(mime, "JPEG")) { output.type = "image/jpeg"; } else if (is(mime, "PNG")) { output.type = "image/png"; } else if (is(mime, "MS Windows icon")) { output.type = "image/vnd.microsoft.icon"; } if (output.type.length() > 0 && output.type != "executable") { DataHandler::Static getter; DataHandler::resource f = getter.get_file(path); output.data = f.data; output.size = f.size; } else if (output.type.length() == 0){ std::string error_str = "Unsupported mime type: " + std::string(mime); // drop 'local' part of path size_t pos = 0; while ((pos = error_str.find(cwd)) != std::string::npos ) error_str.erase(pos, cwd.length()); throw DataHandler::Unsupported(error_str); } return output; }