void include_start(char *file) { char *path; FILE *f; struct stat sb; if (*file == '\0') yyerror("invalid include file"); if ((f = fopen(file, "r")) == NULL) { xasprintf(&path, "%s/%s", xdirname(conf.conf_file), file); if ((f = fopen(path, "r")) == NULL) yyerror("%s: %s", path, strerror(errno)); xfree(file); } else path = file; if (fstat(fileno(f), &sb) != 0) yyerror("%s: %s", path, strerror(errno)); if (geteuid() != 0 && (sb.st_mode & (S_IROTH|S_IWOTH)) != 0) log_warnx("%s: world readable or writable", path); ARRAY_ADD(&parse_filestack, parse_file); parse_file = xmalloc(sizeof *parse_file); parse_file->f = f; parse_file->line = 1; parse_file->path = path; log_debug2("including file %s", parse_file->path); }
int pkg_dest_init(pkg_dest_t * dest, const char *name, const char *root_dir) { char *status_file_dir; dest->name = xstrdup(name); /* Guarantee that dest->root_dir ends with a '/' */ if (root_dir[strlen(root_dir) - 1] == '/') { dest->root_dir = xstrdup(root_dir); } else { sprintf_alloc(&dest->root_dir, "%s/", root_dir); } file_mkdir_hier(dest->root_dir, 0755); sprintf_alloc(&dest->info_dir, "%s/%s", dest->root_dir, opkg_config->info_dir); file_mkdir_hier(dest->info_dir, 0755); sprintf_alloc(&dest->status_file_name, "%s/%s", dest->root_dir, opkg_config->status_file); /* Ensure that the directory in which we will create the status file exists. */ status_file_dir = xdirname(dest->status_file_name); file_mkdir_hier(status_file_dir, 0755); free(status_file_dir); return 0; }
int file_mkdir_hier(const char *path, long mode) { struct stat st; int r; r = stat(path, &st); if (r < 0 && errno == ENOENT) { int status; char *parent; parent = xdirname(path); status = file_mkdir_hier(parent, mode | 0300); free(parent); if (status < 0) return -1; r = mkdir(path, 0777); if (r < 0) { opkg_perror(ERROR, "Cannot create directory `%s'", path); return -1; } if (mode != -1) { r = chmod(path, mode); if (r < 0) { opkg_perror(ERROR, "Cannot set permissions of directory `%s'", path); return -1; } } } return 0; }
static void rmfiles (char *prefix) { #ifdef _WIN32 /* Win32 doesn't have POSIX dirent functions. */ WIN32_FIND_DATA ffd; HANDLE hnd; int go_on; string temp = concat (prefix, "*"); string directory = xdirname (prefix); pushd (directory); hnd = FindFirstFile(temp, &ffd); go_on = (hnd != INVALID_HANDLE_VALUE); while (go_on) { /* FIXME: can this remove read-only files also, like rm -f does? */ DeleteFile(ffd.cFileName); go_on = (FindNextFile(hnd, &ffd) == TRUE); } FindClose(hnd); free(temp); popd (); #else /* not _WIN32 */ DIR *dp; struct dirent *de; int temp_len = strlen (prefix); string directory = "./"; const_string base = xbasename (prefix); /* Copy the directory part of PREFIX with the trailing slash, if any. */ if (base != prefix) { directory = (string) xmalloc (base - prefix + 1); directory[0] = '\0'; strncat (directory, prefix, base - prefix); } /* Find matching files and delete them. */ if ((dp = opendir (directory)) != 0) { while ((de = readdir (dp)) != 0) { string found = concat (directory, de->d_name); if (FILESTRNCASEEQ (found, prefix, temp_len)) /* On POSIX-compliant systems, including DJGPP, this will also remove read-only files and empty directories, like rm -f does. */ if (remove (found)) perror (found); free (found); } } #endif /* not _WIN32 */ }
// Compute the current prefix. void set_current_prefix() { char *pathextstr; curr_prefix = new char[path_name_max()]; // Obtain the full path of the current binary; // using GetModuleFileName on MS-Windows, // and searching along PATH on other systems. #ifdef _WIN32 int len = GetModuleFileName(0, curr_prefix, path_name_max()); if (len) len = GetShortPathName(curr_prefix, curr_prefix, path_name_max()); # if DEBUG fprintf(stderr, "curr_prefix: %s\n", curr_prefix); # endif /* DEBUG */ #else /* !_WIN32 */ curr_prefix = searchpath(program_name, getenv("PATH")); if (!curr_prefix && !strchr(program_name, '.')) { // try with extensions pathextstr = strsave(getenv("PATHEXT")); if (!pathextstr) pathextstr = strsave(PATH_EXT); curr_prefix = searchpathext(program_name, pathextstr, getenv("PATH")); a_delete pathextstr; } if (!curr_prefix) return; #endif /* !_WIN32 */ msw2posixpath(curr_prefix); #if DEBUG fprintf(stderr, "curr_prefix: %s\n", curr_prefix); #endif curr_prefix = xdirname(curr_prefix); // directory of executable curr_prefix = xdirname(curr_prefix); // parent directory of executable curr_prefix_len = strlen(curr_prefix); #if DEBUG fprintf(stderr, "curr_prefix: %s\n", curr_prefix); fprintf(stderr, "curr_prefix_len: %d\n", curr_prefix_len); #endif }
static void do_kanji (void) { const char **p; printf("\nAssuming CP %s 932\n", is_cp932_system ? "is" : "is not"); for (p = ktab; *p; p++) { char *q = to_kanji(*p); char *r = xdirname(q); printf("%s -> %s + %s\n", *p, from_kanji(r), *p + (xbasename(q)-q)); free (r); free (q); } }
/* * This function performs the details of file writing; writing the file * in buffer bp to file fn. Uses the file management routines in the * "fileio.c" package. Most of the grief is checking of some sort. * You may want to call fupdstat() after using this function. */ int writeout(FILE ** ffp, struct buffer *bp, char *fn) { struct stat statbuf; int s; char dp[NFILEN]; if (stat(fn, &statbuf) == -1 && errno == ENOENT) { errno = 0; (void)xdirname(dp, fn, sizeof(dp)); (void)strlcat(dp, "/", sizeof(dp)); if (access(dp, W_OK) && errno == EACCES) { dobeep(); ewprintf("Directory %s write-protected", dp); return (FIOERR); } else if (errno == ENOENT) { dobeep(); ewprintf("%s: no such directory", dp); return (FIOERR); } } /* open writes message */ if ((s = ffwopen(ffp, fn, bp)) != FIOSUC) return (FALSE); s = ffputbuf(*ffp, bp); if (s == FIOSUC) { /* no write error */ s = ffclose(*ffp, bp); if (s == FIOSUC) ewprintf("Wrote %s", fn); } else { /* print a message indicating write error */ (void)ffclose(*ffp, bp); dobeep(); ewprintf("Unable to write %s", fn); } return (s == FIOSUC); }
int rfs_op_unlink(char *path) { redisReply *rr; int ret = -ENOENT; char * _dirname; ret = rfs_op_exists(path); if(ret < 0) return ret; rr = redisCommand(dfs.redis.rc, "DEL %s:%s", dfs.redis.ns, path); if(rr) freeReplyObject(rr); ret = 0; _dirname = xdirname(path); if(_dirname) { rr = redisCommand(dfs.redis.rc, "HDEL %s:%s:%s", dfs.redis.ns, _dirname, path); if(rr) freeReplyObject(rr); } return ret; }
int main(int argc, char **argv) { const char **p; kpathsea kpse = kpathsea_new(); kpathsea_set_program_name (kpse, argv[0], NULL); printf("\n%s: name -> xdirname(name) + xbasename(name)\n\n", kpse->invocation_short_name); for (p = tab; *p; p++) { char *q = xdirname(*p); printf("%s -> %s + %s\n", *p, q, xbasename(*p)); free (q); } #if defined (WIN32) kanji_test(); #endif return 0; }
int rfs_op_create(char * name, mode_t mode, rfs_node_type type) { redisReply * rr; struct stat st; int ret = -EACCES; char * _dirname; rr = redisCommand(dfs.redis.rc, "EXISTS %s:%s", dfs.redis.ns, name); if(!rr) return ret; if(rr->type != REDIS_REPLY_INTEGER) { freeReplyObject(rr); return ret; } if(rr->integer == 1) { return -EEXIST; } freeReplyObject(rr); rr = redisCommand(dfs.redis.rc, "HINCRBY %s:state inode 1", dfs.redis.ns); if(!rr) return ret; if(rr->type != REDIS_REPLY_INTEGER) { xlog("rfs_mkdir", "type=%i", rr->type); freeReplyObject(rr); return ret; } memset(&st,0,sizeof(st)); st.st_ino = rr->integer; st.st_mode = mode; time(&st.st_atime); time(&st.st_mtime); time(&st.st_ctime); switch(type) { case RFS_DIR: st.st_mode |= S_IFDIR; break; case RFS_FILE: st.st_mode |= S_IFREG; break; case RFS_LINK: break; case RFS_DEV: break; default: break; } freeReplyObject(rr); /* rr = redisCommand(dfs.redis.rc, "HSET %s:%s _stat %b", dfs.redis.ns, name, &st, sizeof(st)); freeReplyObject(rr); */ ret = rfs_op_stat(name, &st, RFS_OP_STAT_SET); _dirname = xdirname(name); if(!_dirname) return 0; xlog("create", "%s %s\n", name, _dirname); if(!strcmp(name,_dirname)) return 0; switch(type) { case RFS_DIR: { rfs_op_add_directory_to_directory(name, _dirname); break; } case RFS_FILE: { rfs_op_add_file_to_directory(name, _dirname); break; } case RFS_LINK: break; case RFS_DEV: break; default: break; } return 0; }
/* Mail state. Find and read mail file. */ int fetch_mbox_state_mail(struct account *a, struct fetch_ctx *fctx) { struct fetch_mbox_data *data = a->data; struct mail *m = fctx->mail; struct fetch_mbox_mbox *fmbox; struct fetch_mbox_mail *aux; char *line, *ptr, *lptr; size_t llen; int flushing; /* Find current mbox and check for EOF. */ fmbox = ARRAY_ITEM(&data->fmboxes, data->index); if (data->off == fmbox->size) { fctx->state = fetch_mbox_state_next; return (FETCH_AGAIN); } /* Open the mail. */ if (mail_open(m, IO_BLOCKSIZE) != 0) { log_warn("%s: failed to create mail", a->name); mail_destroy(m); return (FETCH_ERROR); } /* Create aux data. */ aux = xmalloc(sizeof *aux); aux->off = data->off; aux->size = 0; aux->fmbox = fmbox; if (++fmbox->reference == 0) fatalx("reference count overflow"); m->auxdata = aux; m->auxfree = fetch_mbox_free; /* Tag mail. */ default_tags(&m->tags, NULL); add_tag(&m->tags, "mbox", "%s", xbasename(fmbox->path)); add_tag(&m->tags, "mbox_path", "%s", xdirname(fmbox->path)); add_tag(&m->tags, "mbox_file", "%s", fmbox->path); /* * We start at a "From " line and include it in the mail (it can be * trimmed later with minimal penalty). */ flushing = 0; for (;;) { /* Check for EOF. */ if (data->off == fmbox->size) { aux->size = data->off - aux->off; break; } /* Locate the EOL. */ line = fmbox->base + data->off; ptr = memchr(line, '\n', fmbox->size - data->off); if (ptr == NULL) { ptr = fmbox->base + fmbox->size; data->off = fmbox->size; } else data->off += ptr - line + 1; /* Check if the line is "From ". */ if (line > fmbox->base && ptr - line >= 5 && strncmp(line, "From ", 5) == 0) { /* End of mail. */ aux->size = (line - fmbox->base) - aux->off; break; } /* Trim >s from From. */ if (*line == '>') { lptr = line; llen = ptr - line; while (*lptr == '>' && llen > 0) { lptr++; llen--; } if (llen >= 5 && strncmp(lptr, "From ", 5) == 0) line++; } if (flushing) continue; if (append_line(m, line, ptr - line) != 0) { log_warn("%s: failed to resize mail", a->name); mail_destroy(m); return (FETCH_ERROR); } if (m->size > conf.max_size) flushing = 1; } fmbox->total++; /* * Check if there was a blank line between the mails and remove it if * so. */ if (aux->size >= 2 && fmbox->base[aux->off + aux->size - 1] == '\n' && fmbox->base[aux->off + aux->size - 2] == '\n') { aux->size -= 2; m->size -= 2; } return (FETCH_MAIL); }
static string remove_dots P1C(string, dir) { #ifdef AMIGA return dir; #else string c; unsigned len; string ret = (string) ""; /* We always reassign. */ for (c = kpse_filename_component (dir); c; c = kpse_filename_component (NULL)) { if (STREQ (c, ".")) { /* If leading ., replace with cwd. Else ignore. */ if (*ret == 0) { ret = xgetcwd (); } } else if (STREQ (c, "..")) { /* If leading .., start with xdirname (cwd). Else remove last component from ret, if any. */ if (*ret == 0) { string dot = xgetcwd (); ret = xdirname (dot); free (dot); } else { unsigned last; for (last = strlen (ret); last > (NAME_BEGINS_WITH_DEVICE (ret) ? 2 : 0); last--) { if (IS_DIR_SEP (ret[last - 1])) { /* If we have `/../', that's the same as `/'. */ if (last > 1) { ret[last - 1] = 0; } break; } } } } else { /* Not . or ..; just append. Include a directory separator unless our string already ends with one. This also changes all directory separators into the canonical DIR_SEP_STRING. */ string temp; len = strlen (ret); temp = concat3 (ret, ((len > 0 && ret[len - 1] == DIR_SEP) || (NAME_BEGINS_WITH_DEVICE (c) && *ret == 0)) ? "" : DIR_SEP_STRING, c); if (*ret) free (ret); ret = temp; } } /* Remove a trailing /, just in case it snuck in. */ len = strlen (ret); if (len > 0 && ret[len - 1] == DIR_SEP) { ret[len - 1] = 0; } return ret; #endif /* not AMIGA */ }
int insertfile(char *fname, char *newname, int replacebuf) { struct buffer *bp; struct line *lp1, *lp2; struct line *olp; /* line we started at */ struct mgwin *wp; int nbytes, s, nline = 0, siz, x, x2; int opos; /* offset we started at */ int oline; /* original line number */ char *dp; if (replacebuf == TRUE) x = undo_enable(FFRAND, 0); else x = undo_enabled(); lp1 = NULL; if (line == NULL) { line = malloc(NLINE); if (line == NULL) panic("out of memory"); linesize = NLINE; } /* cheap */ bp = curbp; if (newname != NULL) { (void)strlcpy(bp->b_fname, newname, sizeof(bp->b_fname)); dp = xdirname(newname); (void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd)); (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); free(dp); } /* hard file open */ if ((s = ffropen(fname, (replacebuf == TRUE) ? bp : NULL)) == FIOERR) goto out; if (s == FIOFNF) { /* file not found */ if (newname != NULL) ewprintf("(New file)"); else ewprintf("(File not found)"); goto out; } else if (s == FIODIR) { /* file was a directory */ if (replacebuf == FALSE) { ewprintf("Cannot insert: file is a directory, %s", fname); goto cleanup; } killbuffer(bp); if ((bp = dired_(fname)) == NULL) return (FALSE); undo_enable(FFRAND, x); curbp = bp; return (showbuffer(bp, curwp, WFFULL | WFMODE)); } else { dp = xdirname(fname); (void)strlcpy(bp->b_cwd, dp, sizeof(bp->b_cwd)); (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); free(dp); } opos = curwp->w_doto; oline = curwp->w_dotline; /* * Open a new line at dot and start inserting after it. * We will delete this newline after insertion. * Disable undo, as we create the undo record manually. */ x2 = undo_enable(FFRAND, 0); (void)lnewline(); olp = lback(curwp->w_dotp); undo_enable(FFRAND, x2); nline = 0; siz = 0; while ((s = ffgetline(line, linesize, &nbytes)) != FIOERR) { retry: siz += nbytes + 1; switch (s) { case FIOSUC: /* FALLTHRU */ case FIOEOF: ++nline; if ((lp1 = lalloc(nbytes)) == NULL) { /* keep message on the display */ s = FIOERR; undo_add_insert(olp, opos, siz - nbytes - 1 - 1); goto endoffile; } bcopy(line, <ext(lp1)[0], nbytes); lp2 = lback(curwp->w_dotp); lp2->l_fp = lp1; lp1->l_fp = curwp->w_dotp; lp1->l_bp = lp2; curwp->w_dotp->l_bp = lp1; if (s == FIOEOF) { undo_add_insert(olp, opos, siz - 1); goto endoffile; } break; case FIOLONG: { /* a line too long to fit in our buffer */ char *cp; int newsize; newsize = linesize * 2; if (newsize < 0 || (cp = malloc(newsize)) == NULL) { ewprintf("Could not allocate %d bytes", newsize); s = FIOERR; goto endoffile; } bcopy(line, cp, linesize); free(line); line = cp; s = ffgetline(line + linesize, linesize, &nbytes); nbytes += linesize; linesize = newsize; if (s == FIOERR) goto endoffile; goto retry; } default: ewprintf("Unknown code %d reading file", s); s = FIOERR; break; } } endoffile: /* ignore errors */ ffclose(NULL); /* don't zap an error */ if (s == FIOEOF) { if (nline == 1) ewprintf("(Read 1 line)"); else ewprintf("(Read %d lines)", nline); } /* set mark at the end of the text */ curwp->w_dotp = curwp->w_markp = lback(curwp->w_dotp); curwp->w_marko = llength(curwp->w_markp); curwp->w_markline = oline + nline + 1; /* * if we are at the end of the file, ldelnewline is a no-op, * but we still need to decrement the line and markline counts * as we've accounted for this fencepost in our arithmetic */ if (lforw(curwp->w_dotp) == curwp->w_bufp->b_headp) { curwp->w_bufp->b_lines--; curwp->w_markline--; } else (void)ldelnewline(); curwp->w_dotp = olp; curwp->w_doto = opos; curwp->w_dotline = oline; if (olp == curbp->b_headp) curwp->w_dotp = lforw(olp); if (newname != NULL) bp->b_flag |= BFCHG | BFBAK; /* Need a backup. */ else bp->b_flag |= BFCHG; /* * If the insert was at the end of buffer, set lp1 to the end of * buffer line, and lp2 to the beginning of the newly inserted text. * (Otherwise lp2 is set to NULL.) This is used below to set * pointers in other windows correctly if they are also at the end of * buffer. */ lp1 = bp->b_headp; if (curwp->w_markp == lp1) { lp2 = curwp->w_dotp; } else { /* delete extraneous newline */ (void)ldelnewline(); out: lp2 = NULL; } for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_flag |= WFMODE | WFEDIT; if (wp != curwp && lp2 != NULL) { if (wp->w_dotp == lp1) wp->w_dotp = lp2; if (wp->w_markp == lp1) wp->w_markp = lp2; if (wp->w_linep == lp1) wp->w_linep = lp2; } } } bp->b_lines += nline; cleanup: undo_enable(FFRAND, x); /* return FALSE if error */ return (s != FIOERR); }
/* * Read the file "fname" into the current buffer. Make all of the text * in the buffer go away, after checking for unsaved changes. This is * called by the "read" command, the "visit" command, and the mainline * (for "mg file"). */ int readin(char *fname) { struct mgwin *wp; struct stat statbuf; int status, ro = FALSE; char dp[NFILEN]; /* might be old */ if (bclear(curbp) != TRUE) return (TRUE); /* Clear readonly. May be set by autoexec path */ curbp->b_flag &= ~BFREADONLY; if ((status = insertfile(fname, fname, TRUE)) != TRUE) { dobeep(); ewprintf("File is not readable: %s", fname); return (FALSE); } for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_dotp = wp->w_linep = bfirstlp(curbp); wp->w_doto = 0; wp->w_markp = NULL; wp->w_marko = 0; } } /* no change */ curbp->b_flag &= ~BFCHG; /* * Set the buffer READONLY flag if any of following are true: * 1. file is a directory. * 2. file is read-only. * 3. file doesn't exist and directory is read-only. */ if (fisdir(fname) == TRUE) { ro = TRUE; } else if ((access(fname, W_OK) == -1)) { if (errno != ENOENT) { ro = TRUE; } else if (errno == ENOENT) { (void)xdirname(dp, fname, sizeof(dp)); (void)strlcat(dp, "/", sizeof(dp)); /* Missing directory; keep buffer rw, like emacs */ if (stat(dp, &statbuf) == -1 && errno == ENOENT) { if (eyorn("Missing directory, create") == TRUE) (void)do_makedir(dp); } else if (access(dp, W_OK) == -1 && errno == EACCES) { ewprintf("File not found and directory" " write-protected"); ro = TRUE; } } } if (ro == TRUE) curbp->b_flag |= BFREADONLY; if (startrow) { gotoline(FFARG, startrow); startrow = 0; } undo_add_modified(); return (status); }
static string selfdir P1C(const_string, argv0) { string ret = NULL; string self = NULL; if (kpse_absolute_p (argv0, true)) { self = xstrdup (argv0); } else { #ifdef AMIGA #include <dos.h> #include <proto/dos.h> #include <proto/exec.h> BPTR lock; struct DosLibrary *DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 0L); assert (DOSBase); self = xmalloc (BUFSIZ); lock = findpath (argv0); if (lock != ((BPTR) -1)) { if (getpath (lock, self) == -1) { *self = '\0'; } else { strcat (self,DIR_SEP_STRING); strcat (self,argv0); } UnLock (lock); } CloseLibrary((struct Library *) DOSBase); #else /* not AMIGA */ string elt; struct stat s; /* Have to check PATH. But don't call kpse_path_search since we don't want to search any ls-R's or do anything special with //'s. */ for (elt = kpse_path_element (getenv ("PATH")); !self && elt; elt = kpse_path_element (NULL)) { string name; /* UNIX tradition interprets the empty path element as "." */ if (*elt == 0) elt = "."; name = concat3 (elt, DIR_SEP_STRING, argv0); /* In order to do this perfectly, we'd have to check the owner bits only if we are the file owner, and the group bits only if we belong to the file group. That's a lot of work, though, and it's not likely that kpathsea will ever be used with a program that's only executable by some classes and not others. See the `file_status' function in execute_cmd.c in bash for what's necessary if we were to do it right. */ if (stat (name, &s) == 0 && s.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) { /* Do not stop at directories. */ if (!S_ISDIR(s.st_mode)) self = name; } } #endif /* not AMIGA */ } /* If argv0 is somehow dir/exename, `self' will still be NULL. */ if (!self) self = concat3 (".", DIR_SEP_STRING, argv0); ret = xdirname (remove_dots (expand_symlinks (self))); free (self); return ret; }
static void compile_dex_with_dexopt(const char* dex_file_name, const char* odex_file_name) { SCOPED_RESLIST(rl); int dex_file = xopen(dex_file_name, O_RDONLY, 0); const char* odex_temp_filename = xaprintf( "%s.tmp.%s", odex_file_name, gen_hex_random(ENOUGH_ENTROPY)); cleanup_commit(cleanup_allocate(), cleanup_tmpfile, odex_temp_filename); int odex_temp_file = xopen(odex_temp_filename, O_RDWR | O_CREAT | O_EXCL, 0644); allow_inherit(dex_file); allow_inherit(odex_temp_file); struct child_start_info csi = { .io[0] = CHILD_IO_DEV_NULL, .io[1] = CHILD_IO_PIPE, .io[2] = CHILD_IO_DUP_TO_STDOUT, .exename = "dexopt", .argv = ARGV( "dexopt", "--zip", xaprintf("%d", dex_file), xaprintf("%d", odex_temp_file), dex_file_name, "v=ao=fm=y"), }; struct child* dexopt = child_start(&csi); struct growable_buffer output = slurp_fd_buf(dexopt->fd[1]->fd); int status = child_status_to_exit_code(child_wait(dexopt)); if (status != 0) die(EINVAL, "dexopt failed: %s", massage_output_buf(output)); xrename(odex_temp_filename, odex_file_name); } static void compile_dex(const char* dex_file_name, const char* odex_file_name) { if (api_level() < 21) compile_dex_with_dexopt(dex_file_name, odex_file_name); } int rdex_main(const struct cmd_rdex_info* info) { const char* dex_file_name = info->dexfile; struct stat dex_stat = xstat(dex_file_name); const char* odex_file_name = make_odex_name(dex_file_name); bool need_recompile = true; struct stat odex_stat; if (stat(odex_file_name, &odex_stat) == 0 && dex_stat.st_mtime <= odex_stat.st_mtime) { need_recompile = false; } (void) need_recompile; (void) odex_file_name; (void) compile_dex; if (need_recompile) compile_dex(dex_file_name, odex_file_name); if (setenv("CLASSPATH", dex_file_name, 1) == -1) die_errno("setenv"); if (info->classname[0] == '-') die(EINVAL, "class name cannot begin with '-'"); execvp("app_process", (char* const*) ARGV_CONCAT( ARGV("app_process", xdirname(dex_file_name), info->classname), info->args ?: empty_argv)); die_errno("execvp(\"app_process\", ..."); }
int deliver_mbox_deliver(struct deliver_ctx *dctx, struct actitem *ti) { struct account *a = dctx->account; struct mail *m = dctx->mail; struct deliver_mbox_data *data = ti->data; char *path, *ptr, *lptr, *from = NULL; const char *msg; size_t len, llen; int fd, saved_errno; FILE *f; gzFile gzf; long long used; sigset_t set, oset; struct stat sb; f = gzf = NULL; fd = -1; path = replacepath(&data->path, m->tags, m, &m->rml, dctx->udata->home); if (path == NULL || *path == '\0') { log_warnx("%s: empty path", a->name); goto error; } if (data->compress) { len = strlen(path); if (len < 3 || strcmp(path + len - 3, ".gz") != 0) { path = xrealloc(path, 1, len + 4); strlcat(path, ".gz", len + 4); } } log_debug2("%s: saving to mbox %s", a->name, path); /* Save the mbox path. */ add_tag(&m->tags, "mbox_file", "%s", path); /* Check permissions and ownership. */ if (stat(path, &sb) != 0) { if (conf.no_create || errno != ENOENT) goto error_log; log_debug2("%s: creating %s", a->name, xdirname(path)); if (xmkpath(xdirname(path), -1, conf.file_group, DIRMODE) != 0) goto error_log; } else { if ((msg = checkmode(&sb, UMASK(FILEMODE))) != NULL) log_warnx("%s: %s: %s", a->name, path, msg); if ((msg = checkowner(&sb, -1)) != NULL) log_warnx("%s: %s: %s", a->name, path, msg); if ((msg = checkgroup(&sb, conf.file_group)) != NULL) log_warnx("%s: %s: %s", a->name, path, msg); } /* Create or open the mbox. */ used = 0; do { if (conf.no_create) fd = openlock(path, O_WRONLY|O_APPEND, conf.lock_types); else { fd = createlock(path, O_WRONLY|O_APPEND, -1, conf.file_group, FILEMODE, conf.lock_types); } if (fd == -1 && errno == EEXIST) fd = openlock(path, O_WRONLY|O_APPEND, conf.lock_types); if (fd == -1) { if (errno == EAGAIN) { if (locksleep(a->name, path, &used) != 0) goto error; continue; } goto error_log; } } while (fd < 0); /* Open gzFile or FILE * for writing. */ if (data->compress) { if ((gzf = gzdopen(fd, "a")) == NULL) { errno = ENOMEM; goto error_log; } } else { if ((f = fdopen(fd, "a")) == NULL) goto error_log; } /* * mboxes are a pain: if we are interrupted after this we risk * having written a partial mail. So, block SIGTERM until we're * done. */ sigemptyset(&set); sigaddset(&set, SIGTERM); if (sigprocmask(SIG_BLOCK, &set, &oset) < 0) fatal("sigprocmask failed"); /* Write the from line. */ from = make_from(m, dctx->udata->name); if (deliver_mbox_write(f, gzf, from, strlen(from)) < 0) { xfree(from); goto error_unblock; } if (deliver_mbox_write(f, gzf, "\n", 1) < 0) { xfree(from); goto error_unblock; } log_debug3("%s: using from line: %s", a->name, from); xfree(from); /* Write the mail, escaping from lines. */ line_init(m, &ptr, &len); while (ptr != NULL) { if (ptr != m->data) { /* Skip leading >s. */ lptr = ptr; llen = len; while (*lptr == '>' && llen > 0) { lptr++; llen--; } if (llen >= 5 && strncmp(lptr, "From ", 5) == 0) { log_debug2("%s: quoting from line: %.*s", a->name, (int) len - 1, ptr); if (deliver_mbox_write(f, gzf, ">", 1) < 0) goto error_unblock; } } if (deliver_mbox_write(f, gzf, ptr, len) < 0) goto error_unblock; line_next(m, &ptr, &len); } /* Append newlines. */ if (m->data[m->size - 1] == '\n') { if (deliver_mbox_write(f, gzf, "\n", 1) < 0) goto error_unblock; } else { if (deliver_mbox_write(f, gzf, "\n\n", 2) < 0) goto error_unblock; } /* Flush buffers and sync. */ if (gzf == NULL) { if (fflush(f) != 0) goto error_unblock; } else { if (gzflush(gzf, Z_FINISH) != Z_OK) { errno = EIO; goto error_unblock; } } if (fsync(fd) != 0) goto error_unblock; if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) fatal("sigprocmask failed"); if (gzf != NULL) gzclose(gzf); if (f != NULL) fclose(f); closelock(fd, path, conf.lock_types); xfree(path); return (DELIVER_SUCCESS); error_unblock: saved_errno = errno; if (sigprocmask(SIG_SETMASK, &oset, NULL) < 0) fatal("sigprocmask failed"); errno = saved_errno; error_log: log_warn("%s: %s", a->name, path); error: if (gzf != NULL) gzclose(gzf); if (f != NULL) fclose(f); if (fd != -1) closelock(fd, path, conf.lock_types); if (path != NULL) xfree(path); return (DELIVER_FAILURE); }
void browse(const char *ipath, const char *ifilter) { int r, fd; regex_t re; char *newpath; struct stat sb; char *name, *bin, *dir, *tmp, *run, *env; int nowtyping = 0; FILE *fp; oldpath = NULL; path = xstrdup(ipath); fltr = xstrdup(ifilter); begin: /* Path and filter should be malloc(3)-ed strings at all times */ r = populate(); if (r == -1) { if (!nowtyping) { printwarn(); goto nochange; } } for (;;) { redraw(); /* Handle filter-as-you-type mode */ if (nowtyping) goto moretyping; nochange: switch (nextsel(&run, &env)) { case SEL_QUIT: free(path); free(fltr); dentfree(dents, n); return; case SEL_BACK: /* There is no going back */ if (strcmp(path, "/") == 0 || strcmp(path, ".") == 0 || strchr(path, '/') == NULL) goto nochange; dir = xdirname(path); if (canopendir(dir) == 0) { free(dir); printwarn(); goto nochange; } /* Save history */ oldpath = path; path = dir; /* Reset filter */ free(fltr); fltr = xstrdup(ifilter); goto begin; case SEL_GOIN: /* Cannot descend in empty directories */ if (n == 0) goto nochange; name = dents[cur].name; newpath = mkpath(path, name); DPRINTF_S(newpath); /* Get path info */ fd = open(newpath, O_RDONLY | O_NONBLOCK); if (fd == -1) { printwarn(); free(newpath); goto nochange; } r = fstat(fd, &sb); if (r == -1) { printwarn(); close(fd); free(newpath); goto nochange; } close(fd); DPRINTF_U(sb.st_mode); switch (sb.st_mode & S_IFMT) { case S_IFDIR: if (canopendir(newpath) == 0) { printwarn(); free(newpath); goto nochange; } free(path); path = newpath; /* Reset filter */ free(fltr); fltr = xstrdup(ifilter); goto begin; case S_IFREG: bin = openwith(newpath); if (bin == NULL) { printmsg("No association"); free(newpath); goto nochange; } exitcurses(); spawn(bin, newpath, NULL); initcurses(); free(newpath); continue; default: printmsg("Unsupported file"); goto nochange; } case SEL_FLTR: /* Read filter */ printprompt("filter: "); tmp = readln(); if (tmp == NULL) tmp = xstrdup(ifilter); /* Check and report regex errors */ r = setfilter(&re, tmp); if (r != 0) { free(tmp); goto nochange; } free(fltr); fltr = tmp; DPRINTF_S(fltr); /* Save current */ if (n > 0) oldpath = mkpath(path, dents[cur].name); goto begin; case SEL_TYPE: nowtyping = 1; tmp = NULL; moretyping: printprompt("type: "); if (tmp != NULL) printw("%s", tmp); r = readmore(&tmp); DPRINTF_D(r); DPRINTF_S(tmp); if (r == 1) nowtyping = 0; /* Check regex errors */ if (tmp != NULL) { r = setfilter(&re, tmp); if (r != 0) if (nowtyping) { goto moretyping; } else { free(tmp); goto nochange; } } /* Copy or reset filter */ free(fltr); if (tmp != NULL) fltr = xstrdup(tmp); else fltr = xstrdup(ifilter); /* Save current */ if (n > 0) oldpath = mkpath(path, dents[cur].name); if (!nowtyping) free(tmp); goto begin; case SEL_NEXT: if (cur < n - 1) cur++; break; case SEL_PREV: if (cur > 0) cur--; break; case SEL_PGDN: if (cur < n - 1) cur += MIN((LINES - 4) / 2, n - 1 - cur); break; case SEL_PGUP: if (cur > 0) cur -= MIN((LINES - 4) / 2, cur); break; case SEL_HOME: cur = 0; break; case SEL_END: cur = n - 1; break; case SEL_CD: /* Read target dir */ printprompt("chdir: "); tmp = readln(); if (tmp == NULL) { clearprompt(); goto nochange; } newpath = mkpath(path, tmp); free(tmp); if (canopendir(newpath) == 0) { free(newpath); printwarn(); goto nochange; } free(path); path = newpath; free(fltr); fltr = xstrdup(ifilter); /* Reset filter */ DPRINTF_S(path); goto begin; case SEL_MTIME: mtimeorder = !mtimeorder; /* Save current */ if (n > 0) oldpath = mkpath(path, dents[cur].name); goto begin; case SEL_REDRAW: /* Save current */ if (n > 0) oldpath = mkpath(path, dents[cur].name); goto begin; case SEL_RUN: run = xgetenv(env, run); exitcurses(); spawn(run, NULL, path); initcurses(); break; case SEL_RUNARG: name = dents[cur].name; run = xgetenv(env, run); exitcurses(); spawn(run, name, path); initcurses(); break; case SEL_PRINT: name = dents[cur].name; fp = fopen("savelist.txt", "a"); fprintf(fp, "%s/%s\n", path, name); fclose(fp); break; } /* Screensaver */ if (idletimeout != 0 && idle == idletimeout) { idle = 0; exitcurses(); spawn(idlecmd, NULL, NULL); initcurses(); } } }
static void do_xfer_recv(const struct xfer_opts xfer_opts, const char* filename, const char* desired_basename, int from_peer) { struct xfer_msg statm = recv_xfer_msg(from_peer); if (statm.type != XFER_MSG_STAT) die(ECOMM, "expected stat msg"); struct cleanup* error_cl = cleanup_allocate(); struct stat st; const char* parent_directory = NULL; const char* rename_to = NULL; const char* write_mode = NULL; int dest_fd; if (stat(filename, &st) == 0) { if (S_ISDIR(st.st_mode)) { if (desired_basename == NULL) die(EISDIR, "\"%s\" is a directory", filename); parent_directory = filename; filename = xaprintf("%s/%s", parent_directory, desired_basename); } else if (S_ISREG(st.st_mode)) { if (st.st_nlink > 1) write_mode = "inplace"; } else { write_mode = "inplace"; } } if (parent_directory == NULL) parent_directory = xdirname(filename); if (write_mode == NULL) write_mode = xfer_opts.write_mode; bool atomic; bool automatic_mode = false; if (write_mode == NULL) { automatic_mode = true; atomic = true; } else if (strcmp(write_mode, "atomic") == 0) { atomic = true; } else if (strcmp(write_mode, "inplace") == 0) { atomic = false; } else { die(EINVAL, "unknown write mode \"%s\"", write_mode); } bool regular_file = true; bool preallocated = false; bool chmod_explicit = false; mode_t chmod_explicit_modes = 0; if (xfer_opts.preserve) { chmod_explicit = true; chmod_explicit_modes = statm.u.stat.ugo_bits; } if (xfer_opts.mode) { char* endptr = NULL; errno = 0; unsigned long omode = strtoul(xfer_opts.mode, &endptr, 8); if (errno != 0 || *endptr != '\0' || (omode &~ 0777) != 0) die(EINVAL, "invalid mode bits: %s", xfer_opts.mode); chmod_explicit = true; chmod_explicit_modes = (mode_t) omode; } mode_t creat_mode = (chmod_explicit_modes ? 0200 : 0666); if (atomic) { rename_to = filename; filename = xaprintf("%s.fb-adb-%s", filename, gen_hex_random(ENOUGH_ENTROPY)); dest_fd = try_xopen( filename, O_CREAT | O_WRONLY | O_EXCL, creat_mode); if (dest_fd == -1) { if (errno == EACCES && automatic_mode) { atomic = false; filename = rename_to; rename_to = NULL; } else { die_errno("open(\"%s\")", filename); } } } if (!atomic) { dest_fd = xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, creat_mode); if (!S_ISREG(xfstat(dest_fd).st_mode)) regular_file = false; } if (regular_file) cleanup_commit(error_cl, unlink_cleanup, filename); if (regular_file && statm.u.stat.size > 0) preallocated = fallocate_if_supported( dest_fd, statm.u.stat.size); uint64_t total_written = copy_loop_posix_recv(from_peer, dest_fd); if (preallocated && total_written < statm.u.stat.size) xftruncate(dest_fd, total_written); if (xfer_opts.preserve) { struct timeval times[2] = { { statm.u.stat.atime, statm.u.stat.atime_ns / 1000 }, { statm.u.stat.mtime, statm.u.stat.mtime_ns / 1000 }, }; #ifdef HAVE_FUTIMES if (futimes(dest_fd, times) == -1) die_errno("futimes"); #else if (utimes(filename, times) == -1) die_errno("times"); #endif } if (chmod_explicit) if (fchmod(dest_fd, chmod_explicit_modes) == -1) die_errno("fchmod"); if (xfer_opts.sync) xfsync(dest_fd); if (rename_to) xrename(filename, rename_to); if (xfer_opts.sync) xfsync(xopen(parent_directory, O_DIRECTORY|O_RDONLY, 0)); cleanup_forget(error_cl); }
void kpse_set_program_name P2C(const_string, argv0, const_string, progname) { string ext, sdir, sdir_parent, sdir_grandparent; string s = getenv ("KPATHSEA_DEBUG"); #ifdef WIN32 string debug_output = getenv("KPATHSEA_DEBUG_OUTPUT"); string append_debug_output = getenv("KPATHSEA_DEBUG_APPEND"); int err, olderr; #endif /* Set debugging stuff first, in case we end up doing debuggable stuff during this initialization. */ if (s) { kpathsea_debug |= atoi (s); } #ifndef HAVE_PROGRAM_INVOCATION_NAME #if defined(WIN32) /* Set various info about user. Among many things, ensure that HOME is set. If debug_paths is on, turn on some message if $HOME is not found. */ if (KPSE_DEBUG_P(KPSE_DEBUG_PATHS)) { set_home_warning(); } init_user_info(); /* redirect stderr to debug_output. Easier to send logfiles. */ if (debug_output) { int flags = _O_CREAT | _O_TRUNC | _O_RDWR; err = -1; if (_stricmp(debug_output, "con") == 0 || _stricmp(debug_output, "con:") == 0) { err = _fileno(stdout); } else { if (append_debug_output) { flags = _O_CREAT | _O_APPEND | _O_WRONLY; } else { flags = _O_CREAT | _O_TRUNC | _O_WRONLY; xputenv("KPATHSEA_DEBUG_APPEND", "yes"); } } if ((err < 0) && (err = _open(debug_output, flags, _S_IREAD | _S_IWRITE)) == -1) { WARNING1("Can't open %s for stderr redirection!\n", debug_output); perror(debug_output); } else if ((olderr = _dup(fileno(stderr))) == -1) { WARNING("Can't dup() stderr!\n"); close(err); } else if (_dup2(err, fileno(stderr)) == -1) { WARNING1("Can't redirect stderr to %s!\n", debug_output); close(olderr); close(err); } else { close(err); } } /* Win95 always gives the short filename for argv0, not the long one. There is only this way to catch it. It makes all the selfdir stuff useless for win32. */ { char short_path[PATH_MAX], path[PATH_MAX], *fp; /* SearchPath() always gives back an absolute directory */ if (SearchPath(NULL, argv0, ".exe", PATH_MAX, short_path, &fp) == 0) FATAL1("Can't determine where the executable %s is.\n", argv0); if (!win32_get_long_filename(short_path, path, sizeof(path))) { FATAL1("This path points to an invalid file : %s\n", short_path); } /* slashify the dirname */ for (fp = path; fp && *fp; fp++) if (IS_DIR_SEP(*fp)) *fp = DIR_SEP; /* sdir will be the directory of the executable, ie: c:/TeX/bin */ sdir = xdirname(path); program_invocation_name = xstrdup(xbasename(path)); } #elif defined(__DJGPP__) /* DJGPP programs support long filenames on Windows 95, but ARGV0 there is always made with the short 8+3 aliases of all the pathname elements. If long names are supported, we need to convert that to a long name. All we really need is to call `_truename', but most of the code below is required to deal with the special case of networked drives. */ if (pathconf (argv0, _PC_NAME_MAX) > 12) { char long_progname[PATH_MAX]; if (_truename (argv0, long_progname)) { char *fp; if (long_progname[1] != ':') { /* A complication: `_truename' returns network-specific string at the beginning of `long_progname' when the program resides on a networked drive, and DOS calls cannot grok such pathnames. We need to convert the filesystem name back to a drive letter. */ char rootname[PATH_MAX], rootdir[4]; if (argv0[0] && argv0[1] == ':') rootdir[0] = argv0[0]; /* explicit drive in `argv0' */ else rootdir[0] = getdisk () + 'A'; rootdir[1] = ':'; rootdir[2] = '\\'; rootdir[3] = '\0'; if (_truename (rootdir, rootname)) { /* Find out where `rootname' ends in `long_progname' and replace it with the drive letter. */ int root_len = strlen (rootname); if (IS_DIR_SEP (rootname[root_len - 1])) root_len--; /* keep the trailing slash */ long_progname[0] = rootdir[0]; long_progname[1] = ':'; memmove (long_progname + 2, long_progname + root_len, strlen (long_progname + root_len) + 1); } } /* Convert everything to canonical form. */ if (long_progname[0] >= 'A' && long_progname[0] <= 'Z') long_progname[0] += 'a' - 'A'; /* make drive lower case, for beauty */ for (fp = long_progname; *fp; fp++) if (IS_DIR_SEP (*fp)) *fp = DIR_SEP; program_invocation_name = xstrdup (long_progname); } else /* If `_truename' failed, God help them, because we won't... */ program_invocation_name = xstrdup (argv0); } else program_invocation_name = xstrdup (argv0); #else /* !WIN32 && !__DJGPP__ */ program_invocation_name = xstrdup (argv0); #endif #endif /* not HAVE_PROGRAM_INVOCATION_NAME */ /* We need to find SELFAUTOLOC *before* removing the ".exe" suffix from the program_name, otherwise the PATH search inside selfdir will fail, since `prog' doesn't exists as a file, there's `prog.exe' instead. */ #ifndef WIN32 sdir = selfdir (program_invocation_name); #endif /* SELFAUTODIR is actually the parent of the invocation directory, and SELFAUTOPARENT the grandparent. This is how teTeX did it. */ xputenv ("SELFAUTOLOC", sdir); sdir_parent = xdirname (sdir); xputenv ("SELFAUTODIR", sdir_parent); sdir_grandparent = xdirname (sdir_parent); xputenv ("SELFAUTOPARENT", sdir_grandparent); free (sdir); free (sdir_parent); free (sdir_grandparent); #ifndef HAVE_PROGRAM_INVOCATION_NAME program_invocation_short_name = (string)xbasename (program_invocation_name); #endif if (progname) { kpse_program_name = xstrdup (progname); } else { /* If configured --enable-shared and running from the build directory with the wrapper scripts (e.g., for make check), the binaries will be named foo.exe instead of foo. Or possibly if we're running on a DOSISH system. */ ext = find_suffix (program_invocation_short_name); if (ext && FILESTRCASEEQ (ext, "exe")) { kpse_program_name = remove_suffix (program_invocation_short_name); } else { kpse_program_name = xstrdup (program_invocation_short_name); } } xputenv("progname", kpse_program_name); }