int main(int argc, char *argv[]) { int opt; while ((opt = getopt(argc, argv, "i:D:U:I:o:bBcdeKklnsStV")) != -1) switch (opt) { case 'i': opt = *optarg++; if (opt == 'D') addsym(true, true, optarg); else if (opt == 'U') addsym(true, false, optarg); else usage(); break; case 'D': addsym(false, true, optarg); break; case 'U': addsym(false, false, optarg); break; case 'I': break; case 'b': case 'l': lnblank = true; break; case 'B': compblank = true; break; case 'c': complement = true; break; case 'd': debugging = true; break; case 'e': iocccok = true; break; case 'K': strictlogic = true; break; case 'k': killconsts = true; break; case 'n': lnnum = true; break; case 'o': ofilename = optarg; break; case 's': symlist = true; break; case 'S': symlist = symdepth = true; break; case 't': text = true; break; case 'V': version(); default: usage(); } argc -= optind; argv += optind; if (compblank && lnblank) errx(2, "-B and -b are mutually exclusive"); if (argc > 1) { errx(2, "can only do one file"); } else if (argc == 1 && strcmp(*argv, "-") != 0) { filename = *argv; input = fopen(filename, "rb"); if (input == NULL) err(2, "can't open %s", filename); } else { filename = "[stdin]"; input = stdin; } if (ofilename == NULL) { ofilename = "[stdout]"; output = stdout; } else { struct stat ist, ost; if (stat(ofilename, &ost) == 0 && fstat(fileno(input), &ist) == 0) overwriting = (ist.st_dev == ost.st_dev && ist.st_ino == ost.st_ino); if (overwriting) { const char *dirsep; int ofd; dirsep = strrchr(ofilename, '/'); if (dirsep != NULL) snprintf(tempname, sizeof(tempname), "%.*s/" TEMPLATE, (int)(dirsep - ofilename), ofilename); else snprintf(tempname, sizeof(tempname), TEMPLATE); ofd = mkstemp(tempname); if (ofd != -1) output = fdopen(ofd, "wb+"); if (output == NULL) err(2, "can't create temporary file"); fchmod(ofd, ist.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)); } else { output = fopen(ofilename, "wb"); if (output == NULL) err(2, "can't open %s", ofilename); } } process(); abort(); }
/* * Like fgets, but go through the list of files chaining them together. * Set len to the length of the line. */ int mf_fgets(SPACE *sp, enum e_spflag spflag) { struct stat sb; ssize_t len; char *dirbuf, *basebuf; static char *p = NULL; static size_t plen = 0; int c; static int firstfile; if (infile == NULL) { /* stdin? */ if (files->fname == NULL) { if (inplace != NULL) errx(1, "-I or -i may not be used with stdin"); infile = stdin; fname = "stdin"; outfile = stdout; outfname = "stdout"; } firstfile = 1; } for (;;) { if (infile != NULL && (c = getc(infile)) != EOF && !quit) { (void)ungetc(c, infile); break; } /* If we are here then either eof or no files are open yet */ if (infile == stdin) { sp->len = 0; return (0); } if (infile != NULL) { fclose(infile); if (*oldfname != '\0') { /* if there was a backup file, remove it */ unlink(oldfname); /* * Backup the original. Note that hard links * are not supported on all filesystems. */ if ((link(fname, oldfname) != 0) && (rename(fname, oldfname) != 0)) { warn("rename()"); if (*tmpfname) unlink(tmpfname); exit(1); } *oldfname = '\0'; } if (*tmpfname != '\0') { if (outfile != NULL && outfile != stdout) if (fclose(outfile) != 0) { warn("fclose()"); unlink(tmpfname); exit(1); } outfile = NULL; if (rename(tmpfname, fname) != 0) { /* this should not happen really! */ warn("rename()"); unlink(tmpfname); exit(1); } *tmpfname = '\0'; } outfname = NULL; } if (firstfile == 0) files = files->next; else firstfile = 0; if (files == NULL) { sp->len = 0; return (0); } fname = files->fname; if (inplace != NULL) { if (lstat(fname, &sb) != 0) err(1, "%s", fname); if (!S_ISREG(sb.st_mode)) errx(1, "%s: %s %s", fname, "in-place editing only", "works for regular files"); if (*inplace != '\0') { strlcpy(oldfname, fname, sizeof(oldfname)); len = strlcat(oldfname, inplace, sizeof(oldfname)); if (len > (ssize_t)sizeof(oldfname)) errx(1, "%s: name too long", fname); } if ((dirbuf = strdup(fname)) == NULL || (basebuf = strdup(fname)) == NULL) err(1, "strdup"); len = snprintf(tmpfname, sizeof(tmpfname), "%s/.!%ld!%s", dirname(dirbuf), (long)getpid(), basename(basebuf)); free(dirbuf); free(basebuf); if (len >= (ssize_t)sizeof(tmpfname)) errx(1, "%s: name too long", fname); unlink(tmpfname); if (outfile != NULL && outfile != stdout) fclose(outfile); if ((outfile = fopen(tmpfname, "w")) == NULL) err(1, "%s", fname); fchown(fileno(outfile), sb.st_uid, sb.st_gid); fchmod(fileno(outfile), sb.st_mode & ALLPERMS); outfname = tmpfname; if (!ispan) { linenum = 0; resetstate(); } } else { outfile = stdout; outfname = "stdout"; } if ((infile = fopen(fname, "r")) == NULL) { warn("%s", fname); rval = 1; continue; } } /* * We are here only when infile is open and we still have something * to read from it. * * Use getline() so that we can handle essentially infinite input * data. The p and plen are static so each invocation gives * getline() the same buffer which is expanded as needed. */ len = getline(&p, &plen, infile); if (len == -1) err(1, "%s", fname); if (len != 0 && p[len - 1] == '\n') { sp->append_newline = 1; len--; } else if (!lastline()) { sp->append_newline = 1; } else { sp->append_newline = 0; } cspace(sp, p, len, spflag); linenum++; return (1); }
void * /* O - Profile or NULL on error */ cupsdCreateProfile(int job_id) /* I - Job ID or 0 for none */ { #ifdef HAVE_SANDBOX_H cups_file_t *fp; /* File pointer */ char profile[1024], /* File containing the profile */ cache[1024], /* Quoted CacheDir */ request[1024], /* Quoted RequestRoot */ root[1024], /* Quoted ServerRoot */ temp[1024]; /* Quoted TempDir */ const char *nodebug; /* " (with no-log)" for no debug */ if (!UseProfiles) { /* * Only use sandbox profiles as root... */ cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL", job_id); return (NULL); } if ((fp = cupsTempFile2(profile, sizeof(profile))) == NULL) { cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL", job_id); cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create security profile: %s", strerror(errno)); return (NULL); } fchown(cupsFileNumber(fp), RunUser, Group); fchmod(cupsFileNumber(fp), 0640); cupsd_requote(cache, CacheDir, sizeof(cache)); cupsd_requote(request, RequestRoot, sizeof(request)); cupsd_requote(root, ServerRoot, sizeof(root)); cupsd_requote(temp, TempDir, sizeof(temp)); nodebug = LogLevel < CUPSD_LOG_DEBUG ? " (with no-log)" : ""; cupsFilePuts(fp, "(version 1)\n"); cupsFilePuts(fp, "(allow default)\n"); cupsFilePrintf(fp, "(deny file-write* file-read-data file-read-metadata\n" " (regex" " #\"^%s$\"" /* RequestRoot */ " #\"^%s/\"" /* RequestRoot/... */ ")%s)\n", request, request, nodebug); if (!RunUser) cupsFilePrintf(fp, "(deny file-write* file-read-data file-read-metadata\n" " (regex" " #\"^/Users$\"" " #\"^/Users/\"" ")%s)\n", nodebug); cupsFilePrintf(fp, "(deny file-write*\n" " (regex" " #\"^%s$\"" /* ServerRoot */ " #\"^%s/\"" /* ServerRoot/... */ " #\"^/private/etc$\"" " #\"^/private/etc/\"" " #\"^/usr/local/etc$\"" " #\"^/usr/local/etc/\"" " #\"^/Library$\"" " #\"^/Library/\"" " #\"^/System$\"" " #\"^/System/\"" ")%s)\n", root, root, nodebug); /* Specifically allow applications to stat RequestRoot */ cupsFilePrintf(fp, "(allow file-read-metadata\n" " (regex" " #\"^%s$\"" /* RequestRoot */ "))\n", request); cupsFilePrintf(fp, "(allow file-write* file-read-data file-read-metadata\n" " (regex" " #\"^%s$\"" /* TempDir */ " #\"^%s/\"" /* TempDir/... */ " #\"^%s$\"" /* CacheDir */ " #\"^%s/\"" /* CacheDir/... */ " #\"^%s/Library$\"" /* RequestRoot/Library */ " #\"^%s/Library/\"" /* RequestRoot/Library/... */ " #\"^/Library/Application Support/\"" " #\"^/Library/Caches/\"" " #\"^/Library/Preferences/\"" " #\"^/Library/Printers/.*/\"" " #\"^/Users/Shared/\"" "))\n", temp, temp, cache, cache, request, request); cupsFilePrintf(fp, "(deny file-write*\n" " (regex" " #\"^/Library/Printers/PPDs$\"" " #\"^/Library/Printers/PPDs/\"" " #\"^/Library/Printers/PPD Plugins$\"" " #\"^/Library/Printers/PPD Plugins/\"" ")%s)\n", nodebug); if (job_id) { /* * Allow job filters to read the spool file(s)... */ cupsFilePrintf(fp, "(allow file-read-data file-read-metadata\n" " (regex #\"^%s/([ac]%05d|d%05d-[0-9][0-9][0-9])$\"))\n", request, job_id, job_id); } else { /* * Allow email notifications from notifiers... */ cupsFilePuts(fp, "(allow process-exec\n" " (literal \"/usr/sbin/sendmail\")\n" " (with no-sandbox)\n" ")\n"); } cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = \"%s\"", job_id, profile); return ((void *)strdup(profile)); #else cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdCreateProfile(job_id=%d) = NULL", job_id); return (NULL); #endif /* HAVE_SANDBOX_H */ }
/* * install -- * build a path name and install the file */ void install(const char *from_name, const char *to_name, u_long fset, u_long fclr, u_int flags) { struct stat from_sb, temp_sb, to_sb; struct utimbuf utb; int devnull, files_match, from_fd, serrno, target; int tempcopy, temp_fd, to_fd; u_long nfset; char backup[MAXPATHLEN], *p, pathbuf[MAXPATHLEN], tempfile[MAXPATHLEN]; files_match = 0; from_fd = -1; /* If try to install NULL file to a directory, fails. */ if (flags & DIRECTORY || strcmp(from_name, _PATH_DEVNULL)) { if (stat(from_name, &from_sb)) err(EX_OSERR, "%s", from_name); if (!S_ISREG(from_sb.st_mode)) { errno = EFTYPE; err(EX_OSERR, "%s", from_name); } /* Build the target path. */ if (flags & DIRECTORY) { snprintf(pathbuf, sizeof(pathbuf), "%s/%s", to_name, (p = strrchr(from_name, '/')) ? ++p : from_name); to_name = pathbuf; } devnull = 0; } else { devnull = 1; } target = stat(to_name, &to_sb) == 0; /* Only install to regular files. */ if (target && !S_ISREG(to_sb.st_mode)) { errno = EFTYPE; warn("%s", to_name); return; } /* Only copy safe if the target exists. */ tempcopy = safecopy && target; if (!devnull && (from_fd = open(from_name, O_RDONLY, 0)) < 0) err(EX_OSERR, "%s", from_name); /* If we don't strip, we can compare first. */ if (docompare && !dostrip && target) { if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) err(EX_OSERR, "%s", to_name); if (devnull) files_match = to_sb.st_size == 0; else files_match = !(compare(from_fd, from_name, (size_t)from_sb.st_size, to_fd, to_name, (size_t)to_sb.st_size)); /* Close "to" file unless we match. */ if (!files_match) close(to_fd); } if (!files_match) { if (tempcopy) { to_fd = create_tempfile(to_name, tempfile, sizeof(tempfile)); if (to_fd < 0) err(EX_OSERR, "%s", tempfile); } else { if ((to_fd = create_newfile(to_name, target, &to_sb)) < 0) err(EX_OSERR, "%s", to_name); if (verbose) printf("install: %s -> %s\n", from_name, to_name); } if (!devnull) copy(from_fd, from_name, to_fd, tempcopy ? tempfile : to_name, from_sb.st_size); } if (dostrip) { strip(tempcopy ? tempfile : to_name); /* * Re-open our fd on the target, in case we used a strip * that does not work in-place -- like GNU binutils strip. */ close(to_fd); to_fd = open(tempcopy ? tempfile : to_name, O_RDONLY, 0); if (to_fd < 0) err(EX_OSERR, "stripping %s", to_name); } /* * Compare the stripped temp file with the target. */ if (docompare && dostrip && target) { temp_fd = to_fd; /* Re-open to_fd using the real target name. */ if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) err(EX_OSERR, "%s", to_name); if (fstat(temp_fd, &temp_sb)) { serrno = errno; unlink(tempfile); errno = serrno; err(EX_OSERR, "%s", tempfile); } if (compare(temp_fd, tempfile, (size_t)temp_sb.st_size, to_fd, to_name, (size_t)to_sb.st_size) == 0) { /* * If target has more than one link we need to * replace it in order to snap the extra links. * Need to preserve target file times, though. */ if (to_sb.st_nlink != 1) { utb.actime = to_sb.st_atime; utb.modtime = to_sb.st_mtime; utime(tempfile, &utb); } else { files_match = 1; unlink(tempfile); } close(temp_fd); } } /* * Move the new file into place if doing a safe copy * and the files are different (or just not compared). */ if (tempcopy && !files_match) { /* Try to turn off the immutable bits. */ if (to_sb.st_flags & NOCHANGEBITS) chflags(to_name, to_sb.st_flags & ~NOCHANGEBITS); if (dobackup) { if ((size_t)snprintf(backup, MAXPATHLEN, "%s%s", to_name, suffix) != strlen(to_name) + strlen(suffix)) { unlink(tempfile); errx(EX_OSERR, "%s: backup filename too long", to_name); } if (verbose) printf("install: %s -> %s\n", to_name, backup); if (rename(to_name, backup) < 0) { serrno = errno; unlink(tempfile); errno = serrno; err(EX_OSERR, "rename: %s to %s", to_name, backup); } } if (verbose) printf("install: %s -> %s\n", from_name, to_name); if (rename(tempfile, to_name) < 0) { serrno = errno; unlink(tempfile); errno = serrno; err(EX_OSERR, "rename: %s to %s", tempfile, to_name); } /* Re-open to_fd so we aren't hosed by the rename(2). */ close(to_fd); if ((to_fd = open(to_name, O_RDONLY, 0)) < 0) err(EX_OSERR, "%s", to_name); } /* * Preserve the timestamp of the source file if necessary. */ if (dopreserve && !files_match && !devnull) { utb.actime = from_sb.st_atime; utb.modtime = from_sb.st_mtime; utime(to_name, &utb); } if (fstat(to_fd, &to_sb) == -1) { serrno = errno; unlink(to_name); errno = serrno; err(EX_OSERR, "%s", to_name); } /* * Set owner, group, mode for target; do the chown first, * chown may lose the setuid bits. */ if ((gid != (gid_t)-1 && gid != to_sb.st_gid) || (uid != (uid_t)-1 && uid != to_sb.st_uid) || (mode != to_sb.st_mode)) { /* Try to turn off the immutable bits. */ if (to_sb.st_flags & NOCHANGEBITS) fchflags(to_fd, to_sb.st_flags & ~NOCHANGEBITS); } if ((gid != (gid_t)-1 && gid != to_sb.st_gid) || (uid != (uid_t)-1 && uid != to_sb.st_uid)) if (fchown(to_fd, uid, gid) == -1) { serrno = errno; unlink(to_name); errno = serrno; err(EX_OSERR,"%s: chown/chgrp", to_name); } if (mode != to_sb.st_mode) if (fchmod(to_fd, mode)) { serrno = errno; unlink(to_name); errno = serrno; err(EX_OSERR, "%s: chmod", to_name); } /* * If provided a set of flags, set them, otherwise, preserve the * flags, except for the dump and history flags. The dump flag * is left clear on the target while the history flag from when * the target was created (which is inherited from the target's * parent directory) is retained. */ if (flags & SETFLAGS) { nfset = (to_sb.st_flags | fset) & ~fclr; } else { nfset = (from_sb.st_flags & ~(UF_NODUMP | UF_NOHISTORY)) | (to_sb.st_flags & UF_NOHISTORY); } /* * NFS does not support flags. Ignore EOPNOTSUPP flags if we're just * trying to turn off UF_NODUMP. If we're trying to set real flags, * then warn if the the fs doesn't support it, otherwise fail. */ if (!devnull && fchflags(to_fd, nfset)) { if (flags & SETFLAGS) { if (errno == EOPNOTSUPP) warn("%s: chflags", to_name); else { serrno = errno; unlink(to_name); errno = serrno; err(EX_OSERR, "%s: chflags", to_name); } } } close(to_fd); if (!devnull) close(from_fd); }
int set_attr(const char *file, struct hostfs_iattr *attrs, int fd) { struct timeval times[2]; struct timespec atime_ts, mtime_ts; int err, ma; if (attrs->ia_valid & HOSTFS_ATTR_MODE) { if (fd >= 0) { if (fchmod(fd, attrs->ia_mode) != 0) return (-errno); } else if (chmod(file, attrs->ia_mode) != 0) { return -errno; } } if (attrs->ia_valid & HOSTFS_ATTR_UID) { if (fd >= 0) { if (fchown(fd, attrs->ia_uid, -1)) return -errno; } else if (chown(file, attrs->ia_uid, -1)) { return -errno; } } if (attrs->ia_valid & HOSTFS_ATTR_GID) { if (fd >= 0) { if (fchown(fd, -1, attrs->ia_gid)) return -errno; } else if (chown(file, -1, attrs->ia_gid)) { return -errno; } } if (attrs->ia_valid & HOSTFS_ATTR_SIZE) { if (fd >= 0) { if (ftruncate(fd, attrs->ia_size)) return -errno; } else if (truncate(file, attrs->ia_size)) { return -errno; } } /* * Update accessed and/or modified time, in two parts: first set * times according to the changes to perform, and then call futimes() * or utimes() to apply them. */ ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET); if (attrs->ia_valid & ma) { err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, &atime_ts, &mtime_ts, NULL, NULL, NULL, fd); if (err != 0) return err; times[0].tv_sec = atime_ts.tv_sec; times[0].tv_usec = atime_ts.tv_nsec / 1000; times[1].tv_sec = mtime_ts.tv_sec; times[1].tv_usec = mtime_ts.tv_nsec / 1000; if (attrs->ia_valid & HOSTFS_ATTR_ATIME_SET) { times[0].tv_sec = attrs->ia_atime.tv_sec; times[0].tv_usec = attrs->ia_atime.tv_nsec / 1000; } if (attrs->ia_valid & HOSTFS_ATTR_MTIME_SET) { times[1].tv_sec = attrs->ia_mtime.tv_sec; times[1].tv_usec = attrs->ia_mtime.tv_nsec / 1000; } if (fd >= 0) { if (futimes(fd, times) != 0) return -errno; } else if (utimes(file, times) != 0) { return -errno; } } /* Note: ctime is not handled */ if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) { err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, &attrs->ia_atime, &attrs->ia_mtime, NULL, NULL, NULL, fd); if (err != 0) return err; } return 0; }
int main(int ac, char **av) { struct stat stat_buf; /* stat(2) struct contents */ int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ int ind; /* counter variable for chmod(2) tests */ int mode; /* file mode permission */ TST_TOTAL = sizeof(Modes) / sizeof(int); /* Parse standard options given to run the test. */ msg = parse_opts(ac, av, (option_t *) NULL, NULL); if (msg != (char *) NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); tst_exit(); } /* Perform global setup for test */ setup(); /* Check looping state if -i option given */ for (lc = 0; TEST_LOOPING(lc); lc++) { /* Reset Tst_count in case we are looping. */ Tst_count = 0; for (ind = 0; ind < TST_TOTAL; ind++) { mode = Modes[ind]; /* * Call fchmod(2) with different mode permission * bits to set it for "testfile". */ TEST(fchmod(fd, mode)); /* check return code of fchmod(2) */ if (TEST_RETURN == -1) { tst_resm(TFAIL, "fchmod(%d, %#o) Failed, " "errno=%d : %s", fd, mode, TEST_ERRNO, strerror(TEST_ERRNO)); continue; } /* * Perform functional verification if test * executed without (-f) option. */ if (STD_FUNCTIONAL_TEST) { /* * Get the testfile information using * fstat(2). */ if (fstat(fd, &stat_buf) < 0) { tst_brkm(TFAIL, cleanup, "fstat(2) of " "%s failed, errno:%d", TESTFILE, TEST_ERRNO); } stat_buf.st_mode &= ~S_IFREG; /* * Check for expected mode permissions * on testfile. */ if (stat_buf.st_mode == mode) { tst_resm(TPASS, "Functionality of " "fchmod(%d, %#o) successful", fd, mode); } else { tst_resm(TFAIL, "%s: Incorrect modes " "0%03o, Expected 0%03o", TESTFILE, stat_buf.st_mode, mode); } } else { tst_resm(TPASS, "call succeeded"); } } } /* End for TEST_LOOPING */ /* Call cleanup() to undo setup done for the test. */ cleanup(); /*NOTREACHED*/ return(0); } /* End main */
/* write all status data to file */ int xsddefault_save_status_data(void) { char *tmp_log = NULL; customvariablesmember *temp_customvariablesmember = NULL; host *temp_host = NULL; service *temp_service = NULL; contact *temp_contact = NULL; comment *temp_comment = NULL; scheduled_downtime *temp_downtime = NULL; time_t current_time; int fd = 0; FILE *fp = NULL; int result = OK; log_debug_info(DEBUGL_FUNCTIONS, 0, "save_status_data()\n"); /* users may not want us to write status data */ if (!status_file || !strcmp(status_file, "/dev/null")) return OK; asprintf(&tmp_log, "%sXXXXXX", temp_file); if (tmp_log == NULL) return ERROR; log_debug_info(DEBUGL_STATUSDATA, 2, "Writing status data to temp file '%s'\n", tmp_log); if ((fd = mkstemp(tmp_log)) == -1) { /* log an error */ logit(NSLOG_RUNTIME_ERROR, "Error: Unable to create temp file '%s' for writing status data: %s\n", tmp_log, strerror(errno)); /* free memory */ my_free(tmp_log); return ERROR; } fp = (FILE *)fdopen(fd, "w"); if (fp == NULL) { close(fd); unlink(tmp_log); /* log an error */ logit(NSLOG_RUNTIME_ERROR, "Error: Unable to open temp file '%s' for writing status data: %s\n", tmp_log, strerror(errno)); /* free memory */ my_free(tmp_log); return ERROR; } /* generate check statistics */ generate_check_stats(); /* write version info to status file */ fprintf(fp, "########################################\n"); fprintf(fp, "# NAGIOS STATUS FILE\n"); fprintf(fp, "#\n"); fprintf(fp, "# THIS FILE IS AUTOMATICALLY GENERATED\n"); fprintf(fp, "# BY NAGIOS. DO NOT MODIFY THIS FILE!\n"); fprintf(fp, "########################################\n\n"); time(¤t_time); /* write file info */ fprintf(fp, "info {\n"); fprintf(fp, "\tcreated=%lu\n", current_time); fprintf(fp, "\tversion=%s\n", PROGRAM_VERSION); fprintf(fp, "\t}\n\n"); /* save program status data */ fprintf(fp, "programstatus {\n"); fprintf(fp, "\tmodified_host_attributes=%lu\n", modified_host_process_attributes); fprintf(fp, "\tmodified_service_attributes=%lu\n", modified_service_process_attributes); fprintf(fp, "\tnagios_pid=%d\n", nagios_pid); fprintf(fp, "\tdaemon_mode=%d\n", daemon_mode); fprintf(fp, "\tprogram_start=%lu\n", program_start); fprintf(fp, "\tlast_log_rotation=%lu\n", last_log_rotation); fprintf(fp, "\tenable_notifications=%d\n", enable_notifications); fprintf(fp, "\tactive_service_checks_enabled=%d\n", execute_service_checks); fprintf(fp, "\tpassive_service_checks_enabled=%d\n", accept_passive_service_checks); fprintf(fp, "\tactive_host_checks_enabled=%d\n", execute_host_checks); fprintf(fp, "\tpassive_host_checks_enabled=%d\n", accept_passive_host_checks); fprintf(fp, "\tenable_event_handlers=%d\n", enable_event_handlers); fprintf(fp, "\tobsess_over_services=%d\n", obsess_over_services); fprintf(fp, "\tobsess_over_hosts=%d\n", obsess_over_hosts); fprintf(fp, "\tcheck_service_freshness=%d\n", check_service_freshness); fprintf(fp, "\tcheck_host_freshness=%d\n", check_host_freshness); fprintf(fp, "\tenable_flap_detection=%d\n", enable_flap_detection); fprintf(fp, "\tprocess_performance_data=%d\n", process_performance_data); fprintf(fp, "\tglobal_host_event_handler=%s\n", (global_host_event_handler == NULL) ? "" : global_host_event_handler); fprintf(fp, "\tglobal_service_event_handler=%s\n", (global_service_event_handler == NULL) ? "" : global_service_event_handler); fprintf(fp, "\tnext_comment_id=%lu\n", next_comment_id); fprintf(fp, "\tnext_downtime_id=%lu\n", next_downtime_id); fprintf(fp, "\tnext_event_id=%lu\n", next_event_id); fprintf(fp, "\tnext_problem_id=%lu\n", next_problem_id); fprintf(fp, "\tnext_notification_id=%lu\n", next_notification_id); fprintf(fp, "\tactive_scheduled_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_SCHEDULED_HOST_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tactive_ondemand_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_ONDEMAND_HOST_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tpassive_host_check_stats=%d,%d,%d\n", check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[0], check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[1], check_statistics[PASSIVE_HOST_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tactive_scheduled_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_SCHEDULED_SERVICE_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tactive_ondemand_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_ONDEMAND_SERVICE_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tpassive_service_check_stats=%d,%d,%d\n", check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[PASSIVE_SERVICE_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tcached_host_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_CACHED_HOST_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tcached_service_check_stats=%d,%d,%d\n", check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[0], check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[1], check_statistics[ACTIVE_CACHED_SERVICE_CHECK_STATS].minute_stats[2]); fprintf(fp, "\texternal_command_stats=%d,%d,%d\n", check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[0], check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[1], check_statistics[EXTERNAL_COMMAND_STATS].minute_stats[2]); fprintf(fp, "\tparallel_host_check_stats=%d,%d,%d\n", check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[0], check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[1], check_statistics[PARALLEL_HOST_CHECK_STATS].minute_stats[2]); fprintf(fp, "\tserial_host_check_stats=%d,%d,%d\n", check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[0], check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[1], check_statistics[SERIAL_HOST_CHECK_STATS].minute_stats[2]); fprintf(fp, "\t}\n\n"); /* save host status data */ for (temp_host = host_list; temp_host != NULL; temp_host = temp_host->next) { fprintf(fp, "hoststatus {\n"); fprintf(fp, "\thost_name=%s\n", temp_host->name); fprintf(fp, "\tmodified_attributes=%lu\n", temp_host->modified_attributes); fprintf(fp, "\tcheck_command=%s\n", (temp_host->check_command == NULL) ? "" : temp_host->check_command); fprintf(fp, "\tcheck_period=%s\n", (temp_host->check_period == NULL) ? "" : temp_host->check_period); fprintf(fp, "\tnotification_period=%s\n", (temp_host->notification_period == NULL) ? "" : temp_host->notification_period); fprintf(fp, "\tcheck_interval=%f\n", temp_host->check_interval); fprintf(fp, "\tretry_interval=%f\n", temp_host->retry_interval); fprintf(fp, "\tevent_handler=%s\n", (temp_host->event_handler == NULL) ? "" : temp_host->event_handler); fprintf(fp, "\thas_been_checked=%d\n", temp_host->has_been_checked); fprintf(fp, "\tshould_be_scheduled=%d\n", temp_host->should_be_scheduled); fprintf(fp, "\tcheck_execution_time=%.3f\n", temp_host->execution_time); fprintf(fp, "\tcheck_latency=%.3f\n", temp_host->latency); fprintf(fp, "\tcheck_type=%d\n", temp_host->check_type); fprintf(fp, "\tcurrent_state=%d\n", temp_host->current_state); fprintf(fp, "\tlast_hard_state=%d\n", temp_host->last_hard_state); fprintf(fp, "\tlast_event_id=%lu\n", temp_host->last_event_id); fprintf(fp, "\tcurrent_event_id=%lu\n", temp_host->current_event_id); fprintf(fp, "\tcurrent_problem_id=%lu\n", temp_host->current_problem_id); fprintf(fp, "\tlast_problem_id=%lu\n", temp_host->last_problem_id); fprintf(fp, "\tplugin_output=%s\n", (temp_host->plugin_output == NULL) ? "" : temp_host->plugin_output); fprintf(fp, "\tlong_plugin_output=%s\n", (temp_host->long_plugin_output == NULL) ? "" : temp_host->long_plugin_output); fprintf(fp, "\tperformance_data=%s\n", (temp_host->perf_data == NULL) ? "" : temp_host->perf_data); fprintf(fp, "\tlast_check=%lu\n", temp_host->last_check); fprintf(fp, "\tnext_check=%lu\n", temp_host->next_check); fprintf(fp, "\tcheck_options=%d\n", temp_host->check_options); fprintf(fp, "\tcurrent_attempt=%d\n", temp_host->current_attempt); fprintf(fp, "\tmax_attempts=%d\n", temp_host->max_attempts); fprintf(fp, "\tstate_type=%d\n", temp_host->state_type); fprintf(fp, "\tlast_state_change=%lu\n", temp_host->last_state_change); fprintf(fp, "\tlast_hard_state_change=%lu\n", temp_host->last_hard_state_change); fprintf(fp, "\tlast_time_up=%lu\n", temp_host->last_time_up); fprintf(fp, "\tlast_time_down=%lu\n", temp_host->last_time_down); fprintf(fp, "\tlast_time_unreachable=%lu\n", temp_host->last_time_unreachable); fprintf(fp, "\tlast_notification=%lu\n", temp_host->last_notification); fprintf(fp, "\tnext_notification=%lu\n", temp_host->next_notification); fprintf(fp, "\tno_more_notifications=%d\n", temp_host->no_more_notifications); fprintf(fp, "\tcurrent_notification_number=%d\n", temp_host->current_notification_number); fprintf(fp, "\tcurrent_notification_id=%lu\n", temp_host->current_notification_id); fprintf(fp, "\tnotifications_enabled=%d\n", temp_host->notifications_enabled); fprintf(fp, "\tproblem_has_been_acknowledged=%d\n", temp_host->problem_has_been_acknowledged); fprintf(fp, "\tacknowledgement_type=%d\n", temp_host->acknowledgement_type); fprintf(fp, "\tactive_checks_enabled=%d\n", temp_host->checks_enabled); fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_host->accept_passive_checks); fprintf(fp, "\tevent_handler_enabled=%d\n", temp_host->event_handler_enabled); fprintf(fp, "\tflap_detection_enabled=%d\n", temp_host->flap_detection_enabled); fprintf(fp, "\tprocess_performance_data=%d\n", temp_host->process_performance_data); fprintf(fp, "\tobsess=%d\n", temp_host->obsess); fprintf(fp, "\tlast_update=%lu\n", current_time); fprintf(fp, "\tis_flapping=%d\n", temp_host->is_flapping); fprintf(fp, "\tpercent_state_change=%.2f\n", temp_host->percent_state_change); fprintf(fp, "\tscheduled_downtime_depth=%d\n", temp_host->scheduled_downtime_depth); /* custom variables */ for (temp_customvariablesmember = temp_host->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if (temp_customvariablesmember->variable_name) fprintf(fp, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); } fprintf(fp, "\t}\n\n"); } /* save service status data */ for (temp_service = service_list; temp_service != NULL; temp_service = temp_service->next) { fprintf(fp, "servicestatus {\n"); fprintf(fp, "\thost_name=%s\n", temp_service->host_name); fprintf(fp, "\tservice_description=%s\n", temp_service->description); fprintf(fp, "\tmodified_attributes=%lu\n", temp_service->modified_attributes); fprintf(fp, "\tcheck_command=%s\n", (temp_service->check_command == NULL) ? "" : temp_service->check_command); fprintf(fp, "\tcheck_period=%s\n", (temp_service->check_period == NULL) ? "" : temp_service->check_period); fprintf(fp, "\tnotification_period=%s\n", (temp_service->notification_period == NULL) ? "" : temp_service->notification_period); fprintf(fp, "\tcheck_interval=%f\n", temp_service->check_interval); fprintf(fp, "\tretry_interval=%f\n", temp_service->retry_interval); fprintf(fp, "\tevent_handler=%s\n", (temp_service->event_handler == NULL) ? "" : temp_service->event_handler); fprintf(fp, "\thas_been_checked=%d\n", temp_service->has_been_checked); fprintf(fp, "\tshould_be_scheduled=%d\n", temp_service->should_be_scheduled); fprintf(fp, "\tcheck_execution_time=%.3f\n", temp_service->execution_time); fprintf(fp, "\tcheck_latency=%.3f\n", temp_service->latency); fprintf(fp, "\tcheck_type=%d\n", temp_service->check_type); fprintf(fp, "\tcurrent_state=%d\n", temp_service->current_state); fprintf(fp, "\tlast_hard_state=%d\n", temp_service->last_hard_state); fprintf(fp, "\tlast_event_id=%lu\n", temp_service->last_event_id); fprintf(fp, "\tcurrent_event_id=%lu\n", temp_service->current_event_id); fprintf(fp, "\tcurrent_problem_id=%lu\n", temp_service->current_problem_id); fprintf(fp, "\tlast_problem_id=%lu\n", temp_service->last_problem_id); fprintf(fp, "\tcurrent_attempt=%d\n", temp_service->current_attempt); fprintf(fp, "\tmax_attempts=%d\n", temp_service->max_attempts); fprintf(fp, "\tstate_type=%d\n", temp_service->state_type); fprintf(fp, "\tlast_state_change=%lu\n", temp_service->last_state_change); fprintf(fp, "\tlast_hard_state_change=%lu\n", temp_service->last_hard_state_change); fprintf(fp, "\tlast_time_ok=%lu\n", temp_service->last_time_ok); fprintf(fp, "\tlast_time_warning=%lu\n", temp_service->last_time_warning); fprintf(fp, "\tlast_time_unknown=%lu\n", temp_service->last_time_unknown); fprintf(fp, "\tlast_time_critical=%lu\n", temp_service->last_time_critical); fprintf(fp, "\tplugin_output=%s\n", (temp_service->plugin_output == NULL) ? "" : temp_service->plugin_output); fprintf(fp, "\tlong_plugin_output=%s\n", (temp_service->long_plugin_output == NULL) ? "" : temp_service->long_plugin_output); fprintf(fp, "\tperformance_data=%s\n", (temp_service->perf_data == NULL) ? "" : temp_service->perf_data); fprintf(fp, "\tlast_check=%lu\n", temp_service->last_check); fprintf(fp, "\tnext_check=%lu\n", temp_service->next_check); fprintf(fp, "\tcheck_options=%d\n", temp_service->check_options); fprintf(fp, "\tcurrent_notification_number=%d\n", temp_service->current_notification_number); fprintf(fp, "\tcurrent_notification_id=%lu\n", temp_service->current_notification_id); fprintf(fp, "\tlast_notification=%lu\n", temp_service->last_notification); fprintf(fp, "\tnext_notification=%lu\n", temp_service->next_notification); fprintf(fp, "\tno_more_notifications=%d\n", temp_service->no_more_notifications); fprintf(fp, "\tnotifications_enabled=%d\n", temp_service->notifications_enabled); fprintf(fp, "\tactive_checks_enabled=%d\n", temp_service->checks_enabled); fprintf(fp, "\tpassive_checks_enabled=%d\n", temp_service->accept_passive_checks); fprintf(fp, "\tevent_handler_enabled=%d\n", temp_service->event_handler_enabled); fprintf(fp, "\tproblem_has_been_acknowledged=%d\n", temp_service->problem_has_been_acknowledged); fprintf(fp, "\tacknowledgement_type=%d\n", temp_service->acknowledgement_type); fprintf(fp, "\tflap_detection_enabled=%d\n", temp_service->flap_detection_enabled); fprintf(fp, "\tprocess_performance_data=%d\n", temp_service->process_performance_data); fprintf(fp, "\tobsess=%d\n", temp_service->obsess); fprintf(fp, "\tlast_update=%lu\n", current_time); fprintf(fp, "\tis_flapping=%d\n", temp_service->is_flapping); fprintf(fp, "\tpercent_state_change=%.2f\n", temp_service->percent_state_change); fprintf(fp, "\tscheduled_downtime_depth=%d\n", temp_service->scheduled_downtime_depth); /* custom variables */ for (temp_customvariablesmember = temp_service->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if (temp_customvariablesmember->variable_name) fprintf(fp, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); } fprintf(fp, "\t}\n\n"); } /* save contact status data */ for (temp_contact = contact_list; temp_contact != NULL; temp_contact = temp_contact->next) { fprintf(fp, "contactstatus {\n"); fprintf(fp, "\tcontact_name=%s\n", temp_contact->name); fprintf(fp, "\tmodified_attributes=%lu\n", temp_contact->modified_attributes); fprintf(fp, "\tmodified_host_attributes=%lu\n", temp_contact->modified_host_attributes); fprintf(fp, "\tmodified_service_attributes=%lu\n", temp_contact->modified_service_attributes); fprintf(fp, "\thost_notification_period=%s\n", (temp_contact->host_notification_period == NULL) ? "" : temp_contact->host_notification_period); fprintf(fp, "\tservice_notification_period=%s\n", (temp_contact->service_notification_period == NULL) ? "" : temp_contact->service_notification_period); fprintf(fp, "\tlast_host_notification=%lu\n", temp_contact->last_host_notification); fprintf(fp, "\tlast_service_notification=%lu\n", temp_contact->last_service_notification); fprintf(fp, "\thost_notifications_enabled=%d\n", temp_contact->host_notifications_enabled); fprintf(fp, "\tservice_notifications_enabled=%d\n", temp_contact->service_notifications_enabled); /* custom variables */ for (temp_customvariablesmember = temp_contact->custom_variables; temp_customvariablesmember != NULL; temp_customvariablesmember = temp_customvariablesmember->next) { if (temp_customvariablesmember->variable_name) fprintf(fp, "\t_%s=%d;%s\n", temp_customvariablesmember->variable_name, temp_customvariablesmember->has_been_modified, (temp_customvariablesmember->variable_value == NULL) ? "" : temp_customvariablesmember->variable_value); } fprintf(fp, "\t}\n\n"); } /* save all comments */ for (temp_comment = comment_list; temp_comment != NULL; temp_comment = temp_comment->next) { if (temp_comment->comment_type == HOST_COMMENT) fprintf(fp, "hostcomment {\n"); else fprintf(fp, "servicecomment {\n"); fprintf(fp, "\thost_name=%s\n", temp_comment->host_name); if (temp_comment->comment_type == SERVICE_COMMENT) fprintf(fp, "\tservice_description=%s\n", temp_comment->service_description); fprintf(fp, "\tentry_type=%d\n", temp_comment->entry_type); fprintf(fp, "\tcomment_id=%lu\n", temp_comment->comment_id); fprintf(fp, "\tsource=%d\n", temp_comment->source); fprintf(fp, "\tpersistent=%d\n", temp_comment->persistent); fprintf(fp, "\tentry_time=%lu\n", temp_comment->entry_time); fprintf(fp, "\texpires=%d\n", temp_comment->expires); fprintf(fp, "\texpire_time=%lu\n", temp_comment->expire_time); fprintf(fp, "\tauthor=%s\n", temp_comment->author); fprintf(fp, "\tcomment_data=%s\n", temp_comment->comment_data); fprintf(fp, "\t}\n\n"); } /* save all downtime */ for (temp_downtime = scheduled_downtime_list; temp_downtime != NULL; temp_downtime = temp_downtime->next) { if (temp_downtime->type == HOST_DOWNTIME) fprintf(fp, "hostdowntime {\n"); else fprintf(fp, "servicedowntime {\n"); fprintf(fp, "\thost_name=%s\n", temp_downtime->host_name); if (temp_downtime->type == SERVICE_DOWNTIME) fprintf(fp, "\tservice_description=%s\n", temp_downtime->service_description); fprintf(fp, "\tdowntime_id=%lu\n", temp_downtime->downtime_id); fprintf(fp, "\tcomment_id=%lu\n", temp_downtime->comment_id); fprintf(fp, "\tentry_time=%lu\n", temp_downtime->entry_time); fprintf(fp, "\tstart_time=%lu\n", temp_downtime->start_time); fprintf(fp, "\tflex_downtime_start=%lu\n", temp_downtime->flex_downtime_start); fprintf(fp, "\tend_time=%lu\n", temp_downtime->end_time); fprintf(fp, "\ttriggered_by=%lu\n", temp_downtime->triggered_by); fprintf(fp, "\tfixed=%d\n", temp_downtime->fixed); fprintf(fp, "\tduration=%lu\n", temp_downtime->duration); fprintf(fp, "\tis_in_effect=%d\n", temp_downtime->is_in_effect); fprintf(fp, "\tstart_notification_sent=%d\n", temp_downtime->start_notification_sent); fprintf(fp, "\tauthor=%s\n", temp_downtime->author); fprintf(fp, "\tcomment=%s\n", temp_downtime->comment); fprintf(fp, "\t}\n\n"); } /* reset file permissions */ fchmod(fd, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH); /* flush the file to disk */ fflush(fp); /* fsync the file so that it is completely written out before moving it */ fsync(fd); /* close the temp file */ result = fclose(fp); /* save/close was successful */ if (result == 0) { result = OK; /* move the temp file to the status log (overwrite the old status log) */ if (my_rename(tmp_log, status_file)) { unlink(tmp_log); logit(NSLOG_RUNTIME_ERROR, "Error: Unable to update status data file '%s': %s", status_file, strerror(errno)); result = ERROR; } } /* a problem occurred saving the file */ else { result = ERROR; /* remove temp file and log an error */ unlink(tmp_log); logit(NSLOG_RUNTIME_ERROR, "Error: Unable to save status file: %s", strerror(errno)); } /* free memory */ my_free(tmp_log); return result; }
LIBSTDCL_API CONTEXT* clcontext_create( const char* platform_name, int devtyp, size_t ndevmax, cl_context_properties* ctxprop_ext, int lock_key ) { int n; int err = 0; int i; size_t devlist_sz; CONTEXT* cp = 0; cl_platform_id* platforms = 0; cl_uint nplatforms; char info[1024]; cl_platform_id platformid; int nctxprop = 0; cl_context_properties* ctxprop; size_t sz; cl_uint ndev = 0; cl_command_queue_properties prop = 0; DEBUG(__FILE__,__LINE__,"clcontext_create() called"); // if (ndevmax) // WARN(__FILE__,__LINE__,"__clcontext_create(): ndevmax argument ignored"); /*** *** allocate CONTEXT struct ***/ DEBUG(__FILE__,__LINE__, "clcontext_create: sizeof CONTEXT %d",sizeof(CONTEXT)); // cp = (CONTEXT*)malloc(sizeof(CONTEXT)); assert(sizeof(CONTEXT)<getpagesize()); #ifdef _WIN64 cp = (CONTEXT*)_aligned_malloc(sizeof(CONTEXT),getpagesize()); if (!cp) { WARN(__FILE__,__LINE__,"memalign failed"); } #else if (posix_memalign((void**)&cp,getpagesize(),sizeof(CONTEXT))) { WARN(__FILE__,__LINE__,"posix_memalign failed"); } #endif DEBUG(__FILE__,__LINE__,"clcontext_create: context_ptr=%p",cp); if ((intptr_t)cp & (getpagesize()-1)) { ERROR(__FILE__,__LINE__, "clcontext_create: fatal error: unaligned context_ptr"); exit(-1); } if (!cp) { errno=ENOMEM; return(0); } /*** *** get platform id ***/ clGetPlatformIDs(0,0,&nplatforms); // printf("XXX %d\n",nplatforms); if (nplatforms) { platforms = (cl_platform_id*)malloc(nplatforms*sizeof(cl_platform_id)); clGetPlatformIDs(nplatforms,platforms,0); for(i=0;i<nplatforms;i++) { char info[1024]; DEBUG(__FILE__,__LINE__,"_libstdcl_init: available platform:"); clGetPlatformInfo(platforms[i],CL_PLATFORM_PROFILE,1024,info,0); DEBUG(__FILE__,__LINE__, "_libstdcl_init: [%p]CL_PLATFORM_PROFILE=%s",platforms[i],info); clGetPlatformInfo(platforms[i],CL_PLATFORM_VERSION,1024,info,0); DEBUG(__FILE__,__LINE__, "_libstdcl_init: [%p]CL_PLATFORM_VERSION=%s",platforms[i],info); clGetPlatformInfo(platforms[i],CL_PLATFORM_NAME,1024,info,0); DEBUG(__FILE__,__LINE__, "_libstdcl_init: [%p]CL_PLATFORM_NAME=%s",platforms[i],info); clGetPlatformInfo(platforms[i],CL_PLATFORM_VENDOR,1024,info,0); DEBUG(__FILE__,__LINE__, "_libstdcl_init: [%p]CL_PLATFORM_VENDOR=%s",platforms[i],info); clGetPlatformInfo(platforms[i],CL_PLATFORM_EXTENSIONS,1024,info,0); DEBUG(__FILE__,__LINE__, "_libstdcl_init: [%p]CL_PLATFORM_EXTENSIONS=%s",platforms[i],info); } } else { WARN(__FILE__,__LINE__, "_libstdcl_init: no platforms found, continue and hope for the best"); } platformid = __get_platformid(nplatforms, platforms, platform_name); DEBUG(__FILE__,__LINE__,"clcontext_create: platformid=%p",platformid); /*** *** create context ***/ while (ctxprop_ext != 0 && ctxprop_ext[nctxprop] != 0) ++nctxprop; // cl_context_properties ctxprop[3] = { // (cl_context_properties)CL_CONTEXT_PLATFORM, // (cl_context_properties)platformid, // (cl_context_properties)0 // }; nctxprop += 3; ctxprop = (cl_context_properties*)malloc(nctxprop*sizeof(cl_context_properties)); ctxprop[0] = (cl_context_properties)CL_CONTEXT_PLATFORM; ctxprop[1] = (cl_context_properties)platformid; for(i=0;i<nctxprop-3;i++) ctxprop[2+i] = ctxprop_ext[i]; ctxprop[nctxprop-1] = (cl_context_properties)0; clGetPlatformInfo(platformid,CL_PLATFORM_PROFILE,0,0,&sz); cp->platform_profile = (char*)malloc(sz); clGetPlatformInfo(platformid,CL_PLATFORM_PROFILE,sz,cp->platform_profile,0); clGetPlatformInfo(platformid,CL_PLATFORM_VERSION,0,0,&sz); cp->platform_version = (char*)malloc(sz); clGetPlatformInfo(platformid,CL_PLATFORM_VERSION,sz,cp->platform_version,0); clGetPlatformInfo(platformid,CL_PLATFORM_NAME,0,0,&sz); cp->platform_name = (char*)malloc(sz); clGetPlatformInfo(platformid,CL_PLATFORM_NAME,sz,cp->platform_name,0); clGetPlatformInfo(platformid,CL_PLATFORM_VENDOR,0,0,&sz); cp->platform_vendor = (char*)malloc(sz); clGetPlatformInfo(platformid,CL_PLATFORM_VENDOR,sz,cp->platform_vendor,0); clGetPlatformInfo(platformid,CL_PLATFORM_EXTENSIONS,0,0,&sz); cp->platform_extensions = (char*)malloc(sz); clGetPlatformInfo(platformid,CL_PLATFORM_EXTENSIONS,sz, cp->platform_extensions,0); #ifdef _WIN64 cp->ctx = clCreateContextFromType(ctxprop,devtyp,0,0,&err); #else if (lock_key > 0) { if (ndevmax == 0) ndevmax = 1; cl_uint platform_ndev; err = clGetDeviceIDs(platformid,devtyp,0,0,&platform_ndev); // cl_uint platform_vndev = 2*platform_ndev; cl_uint platform_vndev = platform_ndev; //DEBUG(__FILE__,__LINE__,"%d %d",platform_ndev,platform_vndev); cl_device_id* platform_dev = (cl_device_id*)malloc(platform_ndev*sizeof(cl_device_id)); err = clGetDeviceIDs(platformid,devtyp,platform_ndev,platform_dev,0); DEBUG(__FILE__,__LINE__,"clcontext_create: lock_key=%d",lock_key); pid_t pid = getpid(); size_t sz_page = getpagesize(); // system("ls /dev/shm"); char shmobj[64]; snprintf(shmobj,64,"/stdcl_ctx_lock%d.%d",devtyp,lock_key); DEBUG(__FILE__,__LINE__, "clcontext_create: attempt master shm_open %s from %d",shmobj,pid); int fd = shm_open(shmobj,O_RDWR|O_CREAT|O_EXCL,0); void* p0; struct timeval t0,t1; int timeout = 0; int noff = 0; if (fd < 0) { DEBUG(__FILE__,__LINE__, "clcontext_create: master shm_open failed from %d (%d)",pid,fd); DEBUG(__FILE__,__LINE__, "clcontext_create: attempt slave shm_open from %d",pid); timeout = 0; gettimeofday(&t0,0); t0.tv_sec += 10; do { fd = shm_open(shmobj,O_RDWR,0); gettimeofday(&t1,0); if (t1.tv_sec > t0.tv_sec && t1.tv_usec > t0.tv_usec) timeout = 1; } while (fd < 0 && !timeout); if (timeout) { ERROR(__FILE__,__LINE__,"clcontext_create: shm_open timeout"); } ftruncate(fd,sz_page); p0 = mmap(0,sz_page,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (!p0) return(0); __ctx_lock = (struct __ctx_lock_struct*)p0; pthread_mutex_lock(&__ctx_lock->mtx); // if (__ctx_lock->refc < platform_ndev) { if (__ctx_lock->refc < platform_vndev) { noff = __ctx_lock->refc; // ndev = min(ndevmax,platform_ndev-noff); ndev = min(ndevmax,platform_vndev-noff); __ctx_lock->refc += ndev; } pthread_mutex_unlock(&__ctx_lock->mtx); close(fd); } else { DEBUG(__FILE__,__LINE__, "clcontext_create: master shm_open succeeded from %d",pid); ftruncate(fd,sz_page); p0 = mmap(0,sz_page,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0); if (!p0) return(0); __ctx_lock = (struct __ctx_lock_struct*)p0; __ctx_lock->magic = 20110415; __ctx_lock->key = lock_key; pthread_mutex_init(&__ctx_lock->mtx,0); // ndev = min(ndevmax,platform_ndev); ndev = min(ndevmax,platform_vndev); DEBUG(__FILE__,__LINE__,"ndev=%d %d %d",ndev,ndevmax,platform_vndev); __ctx_lock->refc = ndev; fchmod(fd,S_IRUSR|S_IWUSR); close(fd); } DEBUG(__FILE__,__LINE__,"ndev=%d",ndev); // if (noff < platform_ndev) { if (noff < platform_vndev) { // cp->ctx = clCreateContext(ctxprop,ndev,platform_dev + noff,0,0,&err); cp->ctx = clCreateContext(ctxprop,ndev,platform_dev + noff%platform_ndev,0,0,&err); DEBUG(__FILE__,__LINE__, "clcontext_create: platform_ndev=%d ndev=%d noffset=%d", platform_ndev,ndev,noff); if (platform_dev) free(platform_dev); } else { cp->ctx = 0; } } else { cp->ctx = clCreateContextFromType(ctxprop,devtyp,0,0,&err); } #endif if (cp->ctx) { cp->devtyp = devtyp; err = clGetContextInfo(cp->ctx,CL_CONTEXT_DEVICES,0,0,&devlist_sz); cp->ndev = devlist_sz/sizeof(cl_device_id); cp->dev = (cl_device_id*)malloc(10*devlist_sz); err=clGetContextInfo(cp->ctx,CL_CONTEXT_DEVICES,devlist_sz,cp->dev,0); // cp->devtyp = devtyp; // err = clGetDeviceIDs(platformid,devtyp,0,0,&(cp->ndev)); // DEBUG(__FILE__,__LINE__,"xxx %d",err); // DEBUG(__FILE__,__LINE__,"number of devices %d",cp->ndev); // cp->dev = (cl_device_id*)malloc(cp->ndev * sizeof(cl_device_id) ); // err = clGetDeviceIDs(platformid,devtyp,cp->ndev,cp->dev,&(cp->ndev)); // DEBUG(__FILE__,__LINE__,"xxx %d",err); // DEBUG(__FILE__,__LINE__," %p device[0]",cp->dev[0]); } else { WARN(__FILE__,__LINE__,"clcontext_create: failed"); #ifndef _WIN64 if (lock_key > 0 && ndev > 0) { pthread_mutex_lock(&__ctx_lock->mtx); __ctx_lock->refc -= ndev; pthread_mutex_unlock(&__ctx_lock->mtx); } free(cp); #else _aligned_free(cp); #endif return((CONTEXT*)0); } DEBUG(__FILE__,__LINE__,"number of devices %d",cp->ndev); /* XXX XXX TESTING ONLY!!!! */ //_aligned_free(cp); //DEBUG(__FILE__,__LINE__,"MADE IT"); return (CONTEXT*)0; /*** *** create command queues ***/ cp->cmdq = (cl_command_queue*)malloc(sizeof(cl_command_queue)*cp->ndev); DEBUG(__FILE__,__LINE__,"will try to create cmdq"); // XXX something is broken in clCreateCommandQueue, using lazy creation // XXX as a workaround -DAR // { //cl_command_queue_properties prop = 00; //prop |= CL_QUEUE_PROFILING_ENABLE; /* XXX this should be choice -DAR */ for(i=0;i<cp->ndev;i++) { //DEBUG(__FILE__,__LINE__,"%d calling clCreateCommandQueue(%p,%p,%x,%p)",i,cp->ctx,cp->dev[i],prop,&err); #ifdef _WIN64 cp->cmdq[i] = 0; /* have to defer, dllmain limitations */ #else cp->cmdq[i] = clCreateCommandQueue(cp->ctx,cp->dev[i],prop,&err); //cp->cmdq[i] = clCreateCommandQueue(cp->ctx,cp->dev[i],0,&err); //cl_command_queue cmdq = clCreateCommandQueue(cp->ctx,cp->dev[0],0,&err); DEBUG(__FILE__,__LINE__,"clcontext_create: error from create cmdq %d (%p)\n", err,cp->cmdq[i]); #endif //DEBUG(__FILE__,__LINE__,"MADE IT"); return (CONTEXT*)0; } // } // printf("WARNING CMDQs NOT CREATED\n"); // for(i=0;i<cp->ndev;i++) cp->cmdq[i] = (cl_command_queue)0; /*** *** init context resources ***/ LIST_INIT(&cp->prgs_listhead); LIST_INIT(&cp->txt_listhead); LIST_INIT(&cp->memd_listhead); // struct _prgs_struct* prgs // = (struct _prgs_struct*)malloc(sizeof(struct _prgs_struct)); // prgs->len=-1; // LIST_INSERT_HEAD(&cp->prgs_listhead, prgs, prgs_list); // // prgs = (struct _prgs_struct*)malloc(sizeof(struct _prgs_struct)); // prgs->len=-2; // LIST_INSERT_HEAD(&cp->prgs_listhead, prgs, prgs_list); /* printf("%p searching _proc_cl for prgs...\n",_proc_cl.clstrtab); printf("%s\n",&_proc_cl.clstrtab[1]); struct clprgs_entry* sp; for(n=0,sp=_proc_cl.clprgs;n<_proc_cl.clprgs_n;n++,sp++) { printf("found %s (%d bytes)\n",&_proc_cl.clstrtab[sp->e_name],sp->e_size); struct _prgs_struct* prgs = (struct _prgs_struct*) clload(cp,_proc_cl.cltexts+sp->e_offset,sp->e_size,0); } */ /*** *** initialize event lists ***/ // cp->nkev = cp->kev_first = cp->kev_free = 0; cp->kev = (struct _event_list_struct*) malloc(cp->ndev*sizeof(struct _event_list_struct)); for(i=0;i<cp->ndev;i++) { cp->kev[i].nev = cp->kev[i].ev_first = cp->kev[i].ev_free = 0; } // cp->nmev = cp->mev_first = cp->mev_free = 0; cp->mev = (struct _event_list_struct*) malloc(cp->ndev*sizeof(struct _event_list_struct)); for(i=0;i<cp->ndev;i++) { cp->mev[i].nev = cp->mev[i].ev_first = cp->mev[i].ev_free = 0; } //#ifdef ENABLE_CLEXPORT // cp->ndev_v = 0; // cp->extd = 0; // cp->imtd = 0; //#endif if (platforms) free(platforms); return(cp); }
int VolumeManager::createAsec(const char *id, unsigned int numSectors, const char *fstype, const char *key, const int ownerUid, bool isExternal) { struct asec_superblock sb; memset(&sb, 0, sizeof(sb)); const bool wantFilesystem = strcmp(fstype, "none"); bool usingExt4 = false; if (wantFilesystem) { usingExt4 = !strcmp(fstype, "ext4"); if (usingExt4) { sb.c_opts |= ASEC_SB_C_OPTS_EXT4; } else if (strcmp(fstype, "fat")) { SLOGE("Invalid filesystem type %s", fstype); errno = EINVAL; return -1; } } sb.magic = ASEC_SB_MAGIC; sb.ver = ASEC_SB_VER; if (numSectors < ((1024*1024)/512)) { SLOGE("Invalid container size specified (%d sectors)", numSectors); errno = EINVAL; return -1; } if (lookupVolume(id)) { SLOGE("ASEC id '%s' currently exists", id); errno = EADDRINUSE; return -1; } char asecFileName[255]; if (!findAsec(id, asecFileName, sizeof(asecFileName))) { SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)", asecFileName, strerror(errno)); errno = EADDRINUSE; return -1; } const char *asecDir = isExternal ? Volume::SEC_ASECDIR_EXT : Volume::SEC_ASECDIR_INT; int written = snprintf(asecFileName, sizeof(asecFileName), "%s/%s.asec", asecDir, id); if ((written < 0) || (size_t(written) >= sizeof(asecFileName))) { errno = EINVAL; return -1; } if (!access(asecFileName, F_OK)) { SLOGE("ASEC file '%s' currently exists - destroy it first! (%s)", asecFileName, strerror(errno)); errno = EADDRINUSE; return -1; } /* * Add some headroom */ unsigned fatSize = (((numSectors * 4) / 512) + 1) * 2; unsigned numImgSectors = numSectors + fatSize + 2; if (numImgSectors % 63) { numImgSectors += (63 - (numImgSectors % 63)); } // Add +1 for our superblock which is at the end if (Loop::createImageFile(asecFileName, numImgSectors + 1)) { SLOGE("ASEC image file creation failed (%s)", strerror(errno)); return -1; } char idHash[33]; if (!asecHash(id, idHash, sizeof(idHash))) { SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); unlink(asecFileName); return -1; } char loopDevice[255]; if (Loop::create(idHash, asecFileName, loopDevice, sizeof(loopDevice))) { SLOGE("ASEC loop device creation failed (%s)", strerror(errno)); unlink(asecFileName); return -1; } char dmDevice[255]; bool cleanupDm = false; if (strcmp(key, "none")) { // XXX: This is all we support for now sb.c_cipher = ASEC_SB_C_CIPHER_TWOFISH; if (Devmapper::create(idHash, loopDevice, key, numImgSectors, dmDevice, sizeof(dmDevice))) { SLOGE("ASEC device mapping failed (%s)", strerror(errno)); Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } cleanupDm = true; } else { sb.c_cipher = ASEC_SB_C_CIPHER_NONE; strcpy(dmDevice, loopDevice); } /* * Drop down the superblock at the end of the file */ int sbfd = open(loopDevice, O_RDWR); if (sbfd < 0) { SLOGE("Failed to open new DM device for superblock write (%s)", strerror(errno)); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } if (lseek(sbfd, (numImgSectors * 512), SEEK_SET) < 0) { close(sbfd); SLOGE("Failed to lseek for superblock (%s)", strerror(errno)); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } if (write(sbfd, &sb, sizeof(sb)) != sizeof(sb)) { close(sbfd); SLOGE("Failed to write superblock (%s)", strerror(errno)); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } close(sbfd); if (wantFilesystem) { int formatStatus; char mountPoint[255]; int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) { SLOGE("ASEC fs format failed: couldn't construct mountPoint"); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } if (usingExt4) { formatStatus = Ext4::format(dmDevice, mountPoint); } else { formatStatus = Fat::format(dmDevice, numImgSectors, 0); } if (formatStatus < 0) { SLOGE("ASEC fs format failed (%s)", strerror(errno)); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } if (mkdir(mountPoint, 0000)) { if (errno != EEXIST) { SLOGE("Mountpoint creation failed (%s)", strerror(errno)); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } } int mountStatus; if (usingExt4) { mountStatus = Ext4::doMount(dmDevice, mountPoint, false, false, false, false); } else { mountStatus = Fat::doMount(dmDevice, mountPoint, false, false, false, ownerUid, 0, 0000, false); } if (mountStatus) { SLOGE("ASEC FAT mount failed (%s)", strerror(errno)); if (cleanupDm) { Devmapper::destroy(idHash); } Loop::destroyByDevice(loopDevice); unlink(asecFileName); return -1; } if (usingExt4) { int dirfd = open(mountPoint, O_DIRECTORY); if (dirfd >= 0) { if (fchown(dirfd, ownerUid, AID_SYSTEM) || fchmod(dirfd, S_IRUSR | S_IWUSR | S_IXUSR | S_ISGID | S_IRGRP | S_IXGRP)) { SLOGI("Cannot chown/chmod new ASEC mount point %s", mountPoint); } close(dirfd); } } } else { SLOGI("Created raw secure container %s (no filesystem)", id); } mActiveContainers->push_back(new ContainerData(strdup(id), ASEC)); return 0; }
int main(int argc, char *argv[]) { int fd; char* mount_point; struct mntent *mnt; FILE* mtab; FILE* new_mtab; progname = argv[0]; if (argc != 2) { usage(); exit(1); } if (geteuid() != 0) { fprintf(stderr, "%s must be installed suid root\n", progname); exit(1); } mount_point = canonicalize(argv[1]); if (mount_point == NULL) { exit(1); } if (umount_ok(mount_point) != 0) { exit(1); } if (umount(mount_point) != 0) { fprintf(stderr, "Could not umount %s: %s\n", mount_point, strerror(errno)); exit(1); } #ifndef EMBED if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1) { fprintf(stderr, "Can't get "MOUNTED"~ lock file"); return 1; } close(fd); if ((mtab = setmntent(MOUNTED, "r")) == NULL) { fprintf(stderr, "Can't open " MOUNTED ": %s\n", strerror(errno)); return 1; } #define MOUNTED_TMP MOUNTED".tmp" if ((new_mtab = setmntent(MOUNTED_TMP, "w")) == NULL) { fprintf(stderr, "Can't open " MOUNTED_TMP ": %s\n", strerror(errno)); endmntent(mtab); return 1; } while ((mnt = getmntent(mtab)) != NULL) { if (strcmp(mnt->mnt_dir, mount_point) != 0) { addmntent(new_mtab, mnt); } } endmntent(mtab); if (fchmod (fileno (new_mtab), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { fprintf(stderr, "Error changing mode of %s: %s\n", MOUNTED_TMP, strerror(errno)); exit(1); } endmntent(new_mtab); if (rename(MOUNTED_TMP, MOUNTED) < 0) { fprintf(stderr, "Cannot rename %s to %s: %s\n", MOUNTED, MOUNTED_TMP, strerror(errno)); exit(1); } if (unlink(MOUNTED"~") == -1) { fprintf(stderr, "Can't remove "MOUNTED"~"); return 1; } #endif /* EMBED */ return 0; }
/* * klog_rotate() - roate a log file if we have specified rotation * parameters in krb5.conf. */ static void klog_rotate(struct log_entry *le) { time_t t; int i; char *name_buf1; char *name_buf2; char *old_name; char *new_name; char *tmp; FILE *fp; int num_vers; /* * By default we don't rotate. */ if (le->lfu_rotate_period == K_LOG_DEF_FILE_ROTATE_PERIOD) return; t = time(0); if (t >= le->lfu_last_rotated + le->lfu_rotate_period) { /* * The N log file versions will be renamed X.N-1 X.N-2, ... X.0. * So the allocate file name buffers that can the version * number extensions. * 32 extra bytes is plenty. */ name_buf1 = malloc(strlen(le->lfu_fname) + 32); if (name_buf1 == NULL) return; name_buf2 = malloc(strlen(le->lfu_fname) + 32); if (name_buf2 == NULL) { free(name_buf1); return; } old_name = name_buf1; new_name = name_buf2; /* * If there N versions, then the first one has file extension * of N-1. */ (void) sprintf(new_name, "%s.%d", le->lfu_fname, le->lfu_rotate_versions - 1); /* * Rename file.N-2 to file.N-1, file.N-3 to file.N-2, ... * file.0 to file.1 */ for (i = le->lfu_rotate_versions - 1; i > 0; i--) { (void) sprintf(old_name, "%s.%d", le->lfu_fname, i - 1); (void) rename(old_name, new_name); /* * swap old name and new name. This way, * on the next iteration, new_name.X * becomes new_name.X-1. */ tmp = old_name; old_name = new_name; new_name = tmp; } old_name = le->lfu_fname; (void) rename(old_name, new_name); /* * Even though we don't know yet if the fopen() * of the log file will succeed, we mark the log * as rotated. This is so we don't repeatably * rotate file.N-2 to file.N-1 ... etc without * waiting for the rotate period to elapse. */ le->lfu_last_rotated = t; fp = fopen(old_name, le->lfu_fopen_mode); if (fp != NULL) { /* Set the permissions to 644 */ if (fchmod(fileno(fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1) { fprintf(stderr, gettext("During rotate, couldn't set permissions for log file %s: %s\n"), old_name, error_message(errno)); } (void) fclose(le->lfu_filep); le->lfu_filep = fp; /* * If the version parameter in krb5.conf was * 0, then we take this to mean that rotating the * log file will cause us to dispose of the * old one, and created a new one. We have just * renamed the old one to file.-1, so remove it. */ if (le->lfu_rotate_versions <= 0) (void) unlink(new_name); } else { fprintf(stderr, gettext("During rotate, couldn't open log file %s: %s\n"), old_name, error_message(errno)); /* * Put it back. */ (void) rename(new_name, old_name); } free(name_buf1); free(name_buf2); } }
/* callback: net_connect() finished for DCC GET */ void sig_dccget_connected(GET_DCC_REC *dcc) { struct stat statbuf; char *fname, *tempfname, *str; int ret, ret_errno, temphandle, old_umask; if (!dcc->from_dccserver) { if (net_geterror(dcc->handle) != 0) { /* error connecting */ signal_emit("dcc error connect", 1, dcc); dcc_destroy(DCC(dcc)); return; } g_source_remove(dcc->tagconn); dcc->tagconn = -1; } g_free_not_null(dcc->file); dcc->file = dcc_get_download_path(dcc->arg); /* if some plugin wants to change the file name/path here.. */ signal_emit("dcc get receive", 1, dcc); if (stat(dcc->file, &statbuf) == 0 && dcc->get_type == DCC_GET_RENAME) { /* file exists, rename.. */ fname = dcc_get_rename_file(dcc->file); g_free(dcc->file); dcc->file = fname; } if (dcc->get_type != DCC_GET_RESUME) { int dcc_file_create_mode = octal2dec(settings_get_int("dcc_file_create_mode")); /* we want to overwrite the file, remove it here. if it gets created after this, we'll fail. */ unlink(dcc->file); /* just to make sure we won't run into race conditions if download_path is in some global temp directory */ tempfname = g_strconcat(dcc->file, ".XXXXXX", NULL); old_umask = umask(0077); temphandle = mkstemp(tempfname); umask(old_umask); if (temphandle == -1) ret = -1; else ret = fchmod(temphandle, dcc_file_create_mode); if (ret != -1) { ret = link(tempfname, dcc->file); if (ret == -1 && /* Linux */ (errno == EPERM || /* FUSE */ errno == ENOSYS || /* BSD */ errno == EOPNOTSUPP)) { /* hard links aren't supported - some people want to download stuff to FAT/NTFS/etc partitions, so fallback to rename() */ ret = rename(tempfname, dcc->file); } } /* if ret = 0, we're the file owner now */ dcc->fhandle = ret == -1 ? -1 : open(dcc->file, O_WRONLY | O_TRUNC); /* close/remove the temp file */ ret_errno = errno; close(temphandle); unlink(tempfname); g_free(tempfname); if (dcc->fhandle == -1) { signal_emit("dcc error file create", 3, dcc, dcc->file, g_strerror(ret_errno)); dcc_destroy(DCC(dcc)); return; } } dcc->starttime = time(NULL); if (dcc->size == 0) { dcc_close(DCC(dcc)); return; } dcc->tagread = g_input_add(dcc->handle, G_INPUT_READ, (GInputFunction) sig_dccget_receive, dcc); signal_emit("dcc connected", 1, dcc); if (dcc->from_dccserver) { str = g_strdup_printf("121 %s %d\n", dcc->server ? dcc->server->nick : "??", 0); net_transmit(dcc->handle, str, strlen(str)); } }
int setfile(struct stat *fs, int fd) { static struct timeval tv[2]; struct stat ts; int rval, gotstat, islink, fdval; rval = 0; fdval = fd != -1; islink = !fdval && S_ISLNK(fs->st_mode); fs->st_mode &= S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO; TIMESPEC_TO_TIMEVAL(&tv[0], &fs->st_atimespec); TIMESPEC_TO_TIMEVAL(&tv[1], &fs->st_mtimespec); if (islink ? lutimes(to.p_path, tv) : utimes(to.p_path, tv)) { warn("%sutimes: %s", islink ? "l" : "", to.p_path); rval = 1; } if (fdval ? fstat(fd, &ts) : (islink ? lstat(to.p_path, &ts) : stat(to.p_path, &ts))) gotstat = 0; else { gotstat = 1; ts.st_mode &= S_ISUID | S_ISGID | S_ISVTX | S_IRWXU | S_IRWXG | S_IRWXO; } /* * Changing the ownership probably won't succeed, unless we're root * or POSIX_CHOWN_RESTRICTED is not set. Set uid/gid before setting * the mode; current BSD behavior is to remove all setuid bits on * chown. If chown fails, lose setuid/setgid bits. */ if (!gotstat || fs->st_uid != ts.st_uid || fs->st_gid != ts.st_gid) if (fdval ? fchown(fd, fs->st_uid, fs->st_gid) : (islink ? lchown(to.p_path, fs->st_uid, fs->st_gid) : chown(to.p_path, fs->st_uid, fs->st_gid))) { if (errno != EPERM) { warn("chown: %s", to.p_path); rval = 1; } fs->st_mode &= ~(S_ISUID | S_ISGID); } if (!gotstat || fs->st_mode != ts.st_mode) if (fdval ? fchmod(fd, fs->st_mode) : (islink ? lchmod(to.p_path, fs->st_mode) : chmod(to.p_path, fs->st_mode))) { warn("chmod: %s", to.p_path); rval = 1; } if (!gotstat || fs->st_flags != ts.st_flags) if (fdval ? fchflags(fd, fs->st_flags) : (islink ? lchflags(to.p_path, fs->st_flags) : chflags(to.p_path, fs->st_flags))) { warn("chflags: %s", to.p_path); rval = 1; } return (rval); }
XP_File XP_FileOpen( const char* name, XP_FileType type, const XP_FilePerm permissions ) { char* newName = WH_FileName(name, type); XP_File result; #ifdef XP_UNIX XP_StatStruct st; XP_Bool make_private_p = FALSE; #endif /* One should never open newsrc for output directly. */ XP_ASSERT (type != xpNewsRC || type != xpSNewsRC || !strchr (permissions, 'w')); if (newName == NULL) return NULL; #ifdef XP_UNIX switch (type) { /* These files are always private: if the user chmods them, we make them -rw------ again the next time we use them, because it's really important. */ case xpHTTPCookie: case xpKeyChain: case xpSignedAppletDB: case xpSARCache: case xpSARCacheIndex: case xpCertDB: case xpCertDBNameIDX: case xpKeyDB: case xpSecModuleDB: /* Always make tmp files private, because of their short lifetime. */ case xpTemporary: case xpTemporaryNewsRC: case xpFileToPost: case xpPKCS12File: if (strchr (permissions, 'w')) /* opening for output */ make_private_p = TRUE; break; /* These files are created private, but if the user then goes and chmods them, we let their changes stick, because it's reasonable for a user to decide to give away read permission on these (though by default, it makes sense for them to be more private than the user's other files.) */ case xpCacheFAT: case xpCache: case xpRegistry: case xpGlobalHistory: case xpHotlist: case xpBookmarks: case xpMailFolder: if (strchr (permissions, 'w') && /* opening for output */ XP_Stat (newName, &st, type)) /* and it doesn't exist yet */ make_private_p = TRUE; break; case xpProxyConfig: case xpSocksConfig: case xpNewsRC: case xpSNewsRC: case xpNewsgroups: case xpSNewsgroups: case xpURL: case xpMimeTypes: case xpSignature: case xpMailFolderSummary: case xpFolderCache: case xpJSMailFilters: case xpJSHTMLFilters: case xpMailSort: case xpNewsSort: case xpMailPopState: case xpMailFilterLog: case xpNewsFilterLog: case xpExtCache: case xpExtCacheIndex: case xpXoverCache: case xpMailSubdirectory: case xpVCardFile: case xpLDIFFile: case xpAddrBook: case xpAddrBookNew: case xpJSCookieFilters: /* These files need not be more private than any other, so we always create them with the default umask. */ break; default: XP_ASSERT(0); } #endif /* XP_UNIX */ #ifndef MCC_PROXY /* At this point, we'd better have an absolute path, because passing a relative path to fopen() is undefined. (For the client, at least - I gather the proxy is different?) */ #endif/* !MCC_PROXY */ result = fopen(newName, permissions); #ifdef XP_MAC if (result != 0) { int err; err = setvbuf( result, /* file to buffer */ NULL, /* allocate the buffer for us */ _IOFBF, /* fully buffer */ 8 * 1024); /* 8k buffer */ XP_ASSERT(err == 0); } #endif #ifdef XP_UNIX if (make_private_p && result) #ifdef SCO_SV chmod (newName, S_IRUSR | S_IWUSR); /* rw only by owner */ #else fchmod (fileno (result), S_IRUSR | S_IWUSR); /* rw only by owner */ #endif #endif /* XP_UNIX */ XP_FREE(newName); return result; }
/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */ const char *dump_traces() { const char* result = NULL; char traces_path[PROPERTY_VALUE_MAX] = ""; property_get("dalvik.vm.stack-trace-file", traces_path, ""); if (!traces_path[0]) return NULL; /* move the old traces.txt (if any) out of the way temporarily */ char anr_traces_path[PATH_MAX]; strlcpy(anr_traces_path, traces_path, sizeof(anr_traces_path)); strlcat(anr_traces_path, ".anr", sizeof(anr_traces_path)); if (rename(traces_path, anr_traces_path) && errno != ENOENT) { fprintf(stderr, "rename(%s, %s): %s\n", traces_path, anr_traces_path, strerror(errno)); return NULL; // Can't rename old traces.txt -- no permission? -- leave it alone instead } /* make the directory if necessary */ char anr_traces_dir[PATH_MAX]; strlcpy(anr_traces_dir, traces_path, sizeof(anr_traces_dir)); char *slash = strrchr(anr_traces_dir, '/'); if (slash != NULL) { *slash = '\0'; if (!mkdir(anr_traces_dir, 0775)) { chown(anr_traces_dir, AID_SYSTEM, AID_SYSTEM); chmod(anr_traces_dir, 0775); } else if (errno != EEXIST) { fprintf(stderr, "mkdir(%s): %s\n", anr_traces_dir, strerror(errno)); return NULL; } } /* create a new, empty traces.txt file to receive stack dumps */ int fd = open(traces_path, O_CREAT | O_WRONLY | O_TRUNC | O_NOFOLLOW, 0666); /* -rw-rw-rw- */ if (fd < 0) { fprintf(stderr, "%s: %s\n", traces_path, strerror(errno)); return NULL; } int chmod_ret = fchmod(fd, 0666); if (chmod_ret < 0) { fprintf(stderr, "fchmod on %s failed: %s\n", traces_path, strerror(errno)); close(fd); return NULL; } /* walk /proc and kill -QUIT all Dalvik processes */ DIR *proc = opendir("/proc"); if (proc == NULL) { fprintf(stderr, "/proc: %s\n", strerror(errno)); goto error_close_fd; } /* use inotify to find when processes are done dumping */ int ifd = inotify_init(); if (ifd < 0) { fprintf(stderr, "inotify_init: %s\n", strerror(errno)); goto error_close_fd; } int wfd = inotify_add_watch(ifd, traces_path, IN_CLOSE_WRITE); if (wfd < 0) { fprintf(stderr, "inotify_add_watch(%s): %s\n", traces_path, strerror(errno)); goto error_close_ifd; } struct dirent *d; int dalvik_found = 0; while ((d = readdir(proc))) { int pid = atoi(d->d_name); if (pid <= 0) continue; char path[PATH_MAX]; char data[PATH_MAX]; snprintf(path, sizeof(path), "/proc/%d/exe", pid); ssize_t len = readlink(path, data, sizeof(data) - 1); if (len <= 0) { continue; } data[len] = '\0'; if (!strcmp(data, "/system/bin/app_process")) { /* skip zygote -- it won't dump its stack anyway */ snprintf(path, sizeof(path), "/proc/%d/cmdline", pid); int fd = open(path, O_RDONLY); len = read(fd, data, sizeof(data) - 1); close(fd); if (len <= 0) { continue; } data[len] = '\0'; if (!strcmp(data, "zygote")) { continue; } ++dalvik_found; if (kill(pid, SIGQUIT)) { fprintf(stderr, "kill(%d, SIGQUIT): %s\n", pid, strerror(errno)); continue; } /* wait for the writable-close notification from inotify */ struct pollfd pfd = { ifd, POLLIN, 0 }; int ret = poll(&pfd, 1, 200); /* 200 msec timeout */ if (ret < 0) { fprintf(stderr, "poll: %s\n", strerror(errno)); } else if (ret == 0) { fprintf(stderr, "warning: timed out dumping pid %d\n", pid); } else { struct inotify_event ie; read(ifd, &ie, sizeof(ie)); } } else if (should_dump_native_traces(data)) { /* dump native process if appropriate */ if (lseek(fd, 0, SEEK_END) < 0) { fprintf(stderr, "lseek: %s\n", strerror(errno)); } else { dump_backtrace_to_file(pid, fd); } } } if (dalvik_found == 0) { fprintf(stderr, "Warning: no Dalvik processes found to dump stacks\n"); } static char dump_traces_path[PATH_MAX]; strlcpy(dump_traces_path, traces_path, sizeof(dump_traces_path)); strlcat(dump_traces_path, ".bugreport", sizeof(dump_traces_path)); if (rename(traces_path, dump_traces_path)) { fprintf(stderr, "rename(%s, %s): %s\n", traces_path, dump_traces_path, strerror(errno)); goto error_close_ifd; } result = dump_traces_path; /* replace the saved [ANR] traces.txt file */ rename(anr_traces_path, traces_path); error_close_ifd: close(ifd); error_close_fd: close(fd); return result; }
int VolumeManager::fixupAsecPermissions(const char *id, gid_t gid, const char* filename) { char asecFileName[255]; char loopDevice[255]; char mountPoint[255]; if (gid < AID_APP) { SLOGE("Group ID is not in application range"); return -1; } if (findAsec(id, asecFileName, sizeof(asecFileName))) { SLOGE("Couldn't find ASEC %s", id); return -1; } char idHash[33]; if (!asecHash(id, idHash, sizeof(idHash))) { SLOGE("Hash of '%s' failed (%s)", id, strerror(errno)); return -1; } if (Loop::lookupActive(idHash, loopDevice, sizeof(loopDevice))) { SLOGE("Unable fix permissions during lookup on %s (%s)", id, strerror(errno)); return -1; } unsigned int nr_sec = 0; struct asec_superblock sb; if (Loop::lookupInfo(loopDevice, &sb, &nr_sec)) { return -1; } int written = snprintf(mountPoint, sizeof(mountPoint), "%s/%s", Volume::ASECDIR, id); if ((written < 0) || (size_t(written) >= sizeof(mountPoint))) { SLOGE("Unable remount to fix permissions for %s: couldn't construct mountpoint", id); return -1; } int result = 0; if ((sb.c_opts & ASEC_SB_C_OPTS_EXT4) == 0) { return 0; } int ret = Ext4::doMount(loopDevice, mountPoint, false /* read-only */, true /* remount */, false /* executable */, false /* sdcard */); if (ret) { SLOGE("Unable remount to fix permissions for %s (%s)", id, strerror(errno)); return -1; } char *paths[] = { mountPoint, NULL }; FTS *fts = fts_open(paths, FTS_PHYSICAL | FTS_NOCHDIR | FTS_XDEV, NULL); if (fts) { // Traverse the entire hierarchy and chown to system UID. for (FTSENT *ftsent = fts_read(fts); ftsent != NULL; ftsent = fts_read(fts)) { // We don't care about the lost+found directory. if (!strcmp(ftsent->fts_name, "lost+found")) { continue; } /* * There can only be one file marked as private right now. * This should be more robust, but it satisfies the requirements * we have for right now. */ const bool privateFile = !strcmp(ftsent->fts_name, filename); int fd = open(ftsent->fts_accpath, O_NOFOLLOW); if (fd < 0) { SLOGE("Couldn't open file %s: %s", ftsent->fts_accpath, strerror(errno)); result = -1; continue; } result |= fchown(fd, AID_SYSTEM, privateFile? gid : AID_SYSTEM); if (ftsent->fts_info & FTS_D) { result |= fchmod(fd, 0755); } else if (ftsent->fts_info & FTS_F) { result |= fchmod(fd, privateFile ? 0640 : 0644); } close(fd); } fts_close(fts); // Finally make the directory readable by everyone. int dirfd = open(mountPoint, O_DIRECTORY); if (dirfd < 0 || fchmod(dirfd, 0755)) { SLOGE("Couldn't change owner of existing directory %s: %s", mountPoint, strerror(errno)); result |= -1; } close(dirfd); } else { result |= -1; } result |= Ext4::doMount(loopDevice, mountPoint, true /* read-only */, true /* remount */, true /* execute */, false /* sdcard */); if (result) { SLOGE("ASEC fix permissions failed (%s)", strerror(errno)); return -1; } if (mDebug) { SLOGD("ASEC %s permissions fixed", id); } return 0; }
int main(int argc, char *argv[]) { int i, n, fdflags; struct sigaction sa; FILE *iffile; char *p; struct passwd *pw; struct timeval timo; sigset_t mask; struct protent *protp; struct stat statbuf; int connect_attempts = 0; char numbuf[16]; phase = PHASE_INITIALIZE; p = ttyname(0); if (p) strcpy(devnam, p); strcpy(default_devnam, devnam); script_env = NULL; /* Initialize syslog facilities */ #ifdef ULTRIX openlog("pppd", LOG_PID); #else openlog("pppd", LOG_PID | LOG_NDELAY, LOG_PPP); setlogmask(LOG_UPTO(LOG_INFO)); #endif if (gethostname(hostname, MAXNAMELEN) < 0 ) { option_error("Couldn't get hostname: %m"); die(1); } hostname[MAXNAMELEN-1] = 0; uid = getuid(); privileged = uid == 0; sprintf(numbuf, "%d", uid); script_setenv("UID", numbuf); /* * Initialize to the standard option set, then parse, in order, * the system options file, the user's options file, * the tty's options file, and the command line arguments. */ for (i = 0; (protp = protocols[i]) != NULL; ++i) (*protp->init)(0); progname = *argv; if (!options_from_file(_PATH_SYSOPTIONS, !privileged, 0, 1) || !options_from_user()) exit(1); scan_args(argc-1, argv+1); /* look for tty name on command line */ if (!options_for_tty() || !parse_args(argc-1, argv+1)) exit(1); /* * Check that we are running as root. */ if (geteuid() != 0) { option_error("must be root to run %s, since it is not setuid-root", argv[0]); die(1); } if (!ppp_available()) { option_error(no_ppp_msg); exit(1); } /* * Check that the options given are valid and consistent. */ sys_check_options(); auth_check_options(); for (i = 0; (protp = protocols[i]) != NULL; ++i) if (protp->check_options != NULL) (*protp->check_options)(); if (demand && connector == 0) { option_error("connect script required for demand-dialling\n"); exit(1); } script_setenv("DEVICE", devnam); sprintf(numbuf, "%d", baud_rate); script_setenv("SPEED", numbuf); /* * If the user has specified the default device name explicitly, * pretend they hadn't. */ if (!default_device && strcmp(devnam, default_devnam) == 0) default_device = 1; if (default_device) nodetach = 1; /* * Initialize system-dependent stuff and magic number package. */ sys_init(); magic_init(); if (debug) setlogmask(LOG_UPTO(LOG_DEBUG)); /* * Detach ourselves from the terminal, if required, * and identify who is running us. */ if (nodetach == 0) detach(); pid = getpid(); p = getlogin(); stime = time(NULL); if (p == NULL) { pw = getpwuid(uid); if (pw != NULL && pw->pw_name != NULL) p = pw->pw_name; else p = "(unknown)"; } syslog(LOG_NOTICE, "pppd %s.%d%s started by %s, uid %d", VERSION, PATCHLEVEL, IMPLEMENTATION, p, uid); /* * Compute mask of all interesting signals and install signal handlers * for each. Only one signal handler may be active at a time. Therefore, * all other signals should be masked when any handler is executing. */ sigemptyset(&mask); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); sigaddset(&mask, SIGCHLD); #define SIGNAL(s, handler) { \ sa.sa_handler = handler; \ if (sigaction(s, &sa, NULL) < 0) { \ syslog(LOG_ERR, "Couldn't establish signal handler (%d): %m", s); \ die(1); \ } \ } sa.sa_mask = mask; sa.sa_flags = 0; SIGNAL(SIGHUP, hup); /* Hangup */ SIGNAL(SIGINT, term); /* Interrupt */ SIGNAL(SIGTERM, term); /* Terminate */ SIGNAL(SIGCHLD, chld); SIGNAL(SIGUSR1, toggle_debug); /* Toggle debug flag */ SIGNAL(SIGUSR2, open_ccp); /* Reopen CCP */ /* * Install a handler for other signals which would otherwise * cause pppd to exit without cleaning up. */ SIGNAL(SIGABRT, bad_signal); SIGNAL(SIGALRM, bad_signal); SIGNAL(SIGFPE, bad_signal); SIGNAL(SIGILL, bad_signal); SIGNAL(SIGPIPE, bad_signal); SIGNAL(SIGQUIT, bad_signal); SIGNAL(SIGSEGV, bad_signal); #ifdef SIGBUS SIGNAL(SIGBUS, bad_signal); #endif #ifdef SIGEMT SIGNAL(SIGEMT, bad_signal); #endif #ifdef SIGPOLL SIGNAL(SIGPOLL, bad_signal); #endif #ifdef SIGPROF SIGNAL(SIGPROF, bad_signal); #endif #ifdef SIGSYS SIGNAL(SIGSYS, bad_signal); #endif #ifdef SIGTRAP SIGNAL(SIGTRAP, bad_signal); #endif #ifdef SIGVTALRM SIGNAL(SIGVTALRM, bad_signal); #endif #ifdef SIGXCPU SIGNAL(SIGXCPU, bad_signal); #endif #ifdef SIGXFSZ SIGNAL(SIGXFSZ, bad_signal); #endif /* * Apparently we can get a SIGPIPE when we call syslog, if * syslogd has died and been restarted. Ignoring it seems * be sufficient. */ signal(SIGPIPE, SIG_IGN); /* * If we're doing dial-on-demand, set up the interface now. */ if (demand) { /* * Open the loopback channel and set it up to be the ppp interface. */ open_ppp_loopback(); syslog(LOG_INFO, "Using interface ppp%d", ifunit); sprintf(ifname, "ppp%d", ifunit); script_setenv("IFNAME", ifname); create_pidfile(); /* write pid to file */ /* * Configure the interface and mark it up, etc. */ demand_conf(); } for (;;) { need_holdoff = 1; if (demand) { /* * Don't do anything until we see some activity. */ phase = PHASE_DORMANT; kill_link = 0; demand_unblock(); for (;;) { wait_loop_output(timeleft(&timo)); calltimeout(); if (kill_link) { if (!persist) die(0); kill_link = 0; } if (get_loop_output()) break; reap_kids(); } /* * Now we want to bring up the link. */ demand_block(); syslog(LOG_INFO, "Starting link"); } /* * Lock the device if we've been asked to. */ if (lockflag && !default_device) { if (lock(devnam) < 0) goto fail; locked = 1; } /* * Open the serial device and set it up to be the ppp interface. * First we open it in non-blocking mode so we can set the * various termios flags appropriately. If we aren't dialling * out and we want to use the modem lines, we reopen it later * in order to wait for the carrier detect signal from the modem. */ while ((ttyfd = open(devnam, O_NONBLOCK | O_RDWR, 0)) < 0) { if (errno != EINTR) syslog(LOG_ERR, "Failed to open %s: %m", devnam); if (!persist || errno != EINTR) goto fail; } if ((fdflags = fcntl(ttyfd, F_GETFL)) == -1 || fcntl(ttyfd, F_SETFL, fdflags & ~O_NONBLOCK) < 0) syslog(LOG_WARNING, "Couldn't reset non-blocking mode on device: %m"); hungup = 0; kill_link = 0; /* * Do the equivalent of `mesg n' to stop broadcast messages. */ if (fstat(ttyfd, &statbuf) < 0 || fchmod(ttyfd, statbuf.st_mode & ~(S_IWGRP | S_IWOTH)) < 0) { syslog(LOG_WARNING, "Couldn't restrict write permissions to %s: %m", devnam); } else tty_mode = statbuf.st_mode; /* run connection script */ if (connector && connector[0]) { MAINDEBUG((LOG_INFO, "Connecting with <%s>", connector)); /* * Set line speed, flow control, etc. * On most systems we set CLOCAL for now so that we can talk * to the modem before carrier comes up. But this has the * side effect that we might miss it if CD drops before we * get to clear CLOCAL below. On systems where we can talk * successfully to the modem with CLOCAL clear and CD down, * we can clear CLOCAL at this point. */ set_up_tty(ttyfd, 1); /* drop dtr to hang up in case modem is off hook */ if (!default_device && modem) { setdtr(ttyfd, FALSE); sleep(1); setdtr(ttyfd, TRUE); } if (device_script(connector, ttyfd, ttyfd) < 0) { syslog(LOG_ERR, "Connect script failed"); setdtr(ttyfd, FALSE); connect_attempts++; goto fail; } syslog(LOG_INFO, "Serial connection established."); sleep(1); /* give it time to set up its terminal */ } connect_attempts = 0; /* we made it through ok */ /* set line speed, flow control, etc.; clear CLOCAL if modem option */ set_up_tty(ttyfd, 0); /* reopen tty if necessary to wait for carrier */ if (connector == NULL && modem) { while ((i = open(devnam, O_RDWR)) < 0) { if (errno != EINTR) syslog(LOG_ERR, "Failed to reopen %s: %m", devnam); if (!persist || errno != EINTR || hungup || kill_link) goto fail; } close(i); } /* run welcome script, if any */ if (welcomer && welcomer[0]) { if (device_script(welcomer, ttyfd, ttyfd) < 0) syslog(LOG_WARNING, "Welcome script failed"); } /* set up the serial device as a ppp interface */ establish_ppp(ttyfd); if (!demand) { syslog(LOG_INFO, "Using interface ppp%d", ifunit); sprintf(ifname, "ppp%d", ifunit); create_pidfile(); /* write pid to file */ /* write interface unit number to file */ for (n = strlen(devnam); n > 0 ; n--) if (devnam[n] == '/') { n++; break; } sprintf(iffilename, "%s%s.if", _PATH_VARRUN, &devnam[n]); if ((iffile = fopen(iffilename, "w")) != NULL) { fprintf(iffile, "ppp%d\n", ifunit); fclose(iffile); } else { syslog(LOG_ERR, "Failed to create if file %s: %m", iffilename); iffilename[0] = 0; } script_setenv("IFNAME", ifname); } /* * Start opening the connection and wait for * incoming events (reply, timeout, etc.). */ syslog(LOG_NOTICE, "Connect: %s <--> %s", ifname, devnam); stime = time(NULL); lcp_lowerup(0); lcp_open(0); /* Start protocol */ for (phase = PHASE_ESTABLISH; phase != PHASE_DEAD; ) { wait_input(timeleft(&timo)); calltimeout(); get_input(); if (kill_link) { lcp_close(0, "User request"); kill_link = 0; } if (open_ccp_flag) { if (phase == PHASE_NETWORK) { ccp_fsm[0].flags = OPT_RESTART; /* clears OPT_SILENT */ (*ccp_protent.open)(0); } open_ccp_flag = 0; } reap_kids(); /* Don't leave dead kids lying around */ } /* * If we may want to bring the link up again, transfer * the ppp unit back to the loopback. Set the * real serial device back to its normal mode of operation. */ clean_check(); if (demand) restore_loop(); disestablish_ppp(ttyfd); /* * Run disconnector script, if requested. * XXX we may not be able to do this if the line has hung up! */ if (disconnector && !hungup) { set_up_tty(ttyfd, 1); if (device_script(disconnector, ttyfd, ttyfd) < 0) { syslog(LOG_WARNING, "disconnect script failed"); } else { syslog(LOG_INFO, "Serial link disconnected."); } } fail: if (ttyfd >= 0) close_tty(); if (locked) { unlock(); locked = 0; } if (!demand) { if (pidfilename[0] != 0 && unlink(pidfilename) < 0 && errno != ENOENT) syslog(LOG_WARNING, "unable to delete pid file: %m"); pidfilename[0] = 0; if (iffile) if (unlink(iffilename) < 0 && errno != ENOENT) syslog(LOG_WARNING, "unable to delete if file: %m"); iffilename[0] = 0; } /* limit to retries? */ if (max_con_attempts) if (connect_attempts >= max_con_attempts) break; if (!persist) die(1); if (demand) demand_discard(); if (holdoff > 0 && need_holdoff) { phase = PHASE_HOLDOFF; TIMEOUT(holdoff_end, NULL, holdoff); do { wait_time(timeleft(&timo)); calltimeout(); if (kill_link) { if (!persist) die(0); kill_link = 0; phase = PHASE_DORMANT; /* allow signal to end holdoff */ } reap_kids(); } while (phase == PHASE_HOLDOFF); } } die(0); return 0; }
/* * This is seriously ugly code following. Written very fast! * [And subsequently made even worse.. Sigh! This code was just born * to be hacked, I guess.. :) -jkh] */ static int pkg_do(char *pkg) { Package Plist; char pkg_fullname[FILENAME_MAX]; char playpen[FILENAME_MAX]; char extract_contents[FILENAME_MAX]; char *extract; const char *where_to; FILE *cfile; int code; PackingList p; struct stat sb; int inPlace, conflictsfound, errcode; /* support for separate pre/post install scripts */ int new_m = 0; char pre_script[FILENAME_MAX] = INSTALL_FNAME; char post_script[FILENAME_MAX]; char pre_arg[FILENAME_MAX], post_arg[FILENAME_MAX]; char *conflict[2]; char **matched; int fd; conflictsfound = 0; code = 0; zapLogDir = 0; LogDir[0] = '\0'; strcpy(playpen, FirstPen); inPlace = 0; memset(&Plist, '\0', sizeof(Plist)); /* Are we coming in for a second pass, everything already extracted? */ if (!pkg) { fgets(playpen, FILENAME_MAX, stdin); playpen[strlen(playpen) - 1] = '\0'; /* pesky newline! */ if (chdir(playpen) == FAIL) { warnx("pkg_add in SLAVE mode can't chdir to %s", playpen); return 1; } read_plist(&Plist, stdin); where_to = playpen; } /* Nope - do it now */ else { /* Is it an ftp://foo.bar.baz/file.t[bg]z specification? */ if (isURL(pkg)) { if (!(where_to = fileGetURL(NULL, pkg, KeepPackage))) { warnx("unable to fetch '%s' by URL", pkg); return 1; } strcpy(pkg_fullname, pkg); cfile = fopen(CONTENTS_FNAME, "r"); if (!cfile) { warnx( "unable to open table of contents file '%s' - not a package?", CONTENTS_FNAME); goto bomb; } read_plist(&Plist, cfile); fclose(cfile); } else { strcpy(pkg_fullname, pkg); /* * Copy for sanity's sake, * could remove pkg_fullname */ if (strcmp(pkg, "-")) { if (stat(pkg_fullname, &sb) == FAIL) { warnx("can't stat package file '%s'", pkg_fullname); goto bomb; } sprintf(extract_contents, "--fast-read %s", CONTENTS_FNAME); extract = extract_contents; } else { extract = NULL; sb.st_size = 100000; /* Make up a plausible average size */ } if (!(where_to = make_playpen(playpen, sb.st_size * 4))) errx(1, "unable to make playpen for %lld bytes", (long long)sb.st_size * 4); /* Since we can call ourselves recursively, keep notes on where we came from */ if (!getenv("_TOP")) setenv("_TOP", where_to, 1); if (unpack(pkg_fullname, extract)) { warnx( "unable to extract table of contents file from '%s' - not a package?", pkg_fullname); goto bomb; } cfile = fopen(CONTENTS_FNAME, "r"); if (!cfile) { warnx( "unable to open table of contents file '%s' - not a package?", CONTENTS_FNAME); goto bomb; } read_plist(&Plist, cfile); fclose(cfile); /* Extract directly rather than moving? Oh goodie! */ if (find_plist_option(&Plist, "extract-in-place")) { if (Verbose) printf("Doing in-place extraction for %s\n", pkg_fullname); p = find_plist(&Plist, PLIST_CWD); if (p) { if (!isdir(p->name) && !Fake) { if (Verbose) printf("Desired prefix of %s does not exist, creating..\n", p->name); vsystem("/bin/mkdir -p %s", p->name); if (chdir(p->name) == -1) { warn("unable to change directory to '%s'", p->name); goto bomb; } } where_to = p->name; inPlace = 1; } else { warnx( "no prefix specified in '%s' - this is a bad package!", pkg_fullname); goto bomb; } } /* * Apply a crude heuristic to see how much space the package will * take up once it's unpacked. I've noticed that most packages * compress an average of 75%, so multiply by 4 for good measure. */ if (!extract && !inPlace && min_free(playpen) < sb.st_size * 4) { warnx("projected size of %lld exceeds available free space.\n" "Please set your PKG_TMPDIR variable to point to a location with more\n" "free space and try again", (long long)sb.st_size * 4); warnx("not extracting %s\ninto %s, sorry!", pkg_fullname, where_to); goto bomb; } /* If this is a direct extract and we didn't want it, stop now */ if (inPlace && Fake) goto success; /* Finally unpack the whole mess. If extract is null we already + did so so don't bother doing it again. */ if (extract && unpack(pkg_fullname, NULL)) { warnx("unable to extract '%s'!", pkg_fullname); goto bomb; } } /* Check for sanity and dependencies */ if (sanity_check(pkg)) goto bomb; /* If we're running in MASTER mode, just output the plist and return */ if (AddMode == MASTER) { printf("%s\n", where_playpen()); write_plist(&Plist, stdout); return 0; } } /* * If we have a prefix, delete the first one we see and add this * one in place of it. */ if (Prefix) { delete_plist(&Plist, FALSE, PLIST_CWD, NULL); add_plist_top(&Plist, PLIST_CWD, Prefix); } setenv(PKG_PREFIX_VNAME, (p = find_plist(&Plist, PLIST_CWD)) ? p->name : ".", 1); /* Protect against old packages with bogus @name and origin fields */ if (Plist.name == NULL) Plist.name = "anonymous"; if (Plist.origin == NULL) Plist.origin = "anonymous/anonymous"; /* * See if we're already registered either with the same name (the same * version) or some other version with the same origin. */ if ((isinstalledpkg(Plist.name) > 0 || matchbyorigin(Plist.origin, NULL) != NULL) && !Force) { warnx("package '%s' or its older version already installed%s", Plist.name, FailOnAlreadyInstalled ? "" : " (ignored)"); code = FailOnAlreadyInstalled != FALSE; goto success; /* close enough for government work */ } /* Now check the packing list for conflicts */ if (!IgnoreDeps){ for (p = Plist.head; p != NULL; p = p->next) { if (p->type == PLIST_CONFLICTS) { int i; conflict[0] = strdup(p->name); conflict[1] = NULL; matched = matchinstalled(MATCH_GLOB, conflict, &errcode); free(conflict[0]); if (errcode == 0 && matched != NULL) for (i = 0; matched[i] != NULL; i++) if (isinstalledpkg(matched[i]) > 0) { warnx("package '%s' conflicts with %s", Plist.name, matched[i]); conflictsfound = 1; } continue; } } if(conflictsfound) { if(!Force) { warnx("please use pkg_delete first to remove conflicting package(s) or -f to force installation"); code = 1; goto bomb; } else warnx("-f specified; proceeding anyway"); } #if ENSURE_THAT_ALL_REQUIREMENTS_ARE_MET /* * Before attempting to do the slave mode bit, ensure that we've * downloaded & processed everything we need. * It's possible that we haven't already installed all of our * dependencies if the dependency list was misgenerated due to * other dynamic dependencies or if a dependency was added to a * package without all REQUIRED_BY packages being regenerated. */ for (p = pkg ? Plist.head : NULL; p; p = p->next) { const char *ext; char *deporigin; if (p->type != PLIST_PKGDEP) continue; deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL; if (isinstalledpkg(p->name) <= 0 && !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) { char subpkg[FILENAME_MAX], *sep; strlcpy(subpkg, pkg, sizeof subpkg); if ((sep = strrchr(subpkg, '/')) != NULL) { *sep = '\0'; if ((sep = strrchr(subpkg, '/')) != NULL) { *sep = '\0'; strlcat(subpkg, "/All/", sizeof subpkg); strlcat(subpkg, p->name, sizeof subpkg); if ((ext = strrchr(pkg, '.')) == NULL) ext = ".tbz"; strlcat(subpkg, ext, sizeof subpkg); pkg_do(subpkg); } } } } #endif /* Now check the packing list for dependencies */ for (p = Plist.head; p ; p = p->next) { char *deporigin; if (p->type != PLIST_PKGDEP) continue; deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL; if (Verbose) { printf("Package '%s' depends on '%s'", Plist.name, p->name); if (deporigin != NULL) printf(" with '%s' origin", deporigin); printf(".\n"); } if (isinstalledpkg(p->name) <= 0 && !(deporigin != NULL && matchbyorigin(deporigin, NULL) != NULL)) { char path[FILENAME_MAX]; const char *cp = NULL; if (!Fake) { char prefixArg[2 + MAXPATHLEN]; /* "-P" + Prefix */ if (PrefixRecursive) { strlcpy(prefixArg, "-P", sizeof(prefixArg)); strlcat(prefixArg, Prefix, sizeof(prefixArg)); } if (!isURL(pkg) && !getenv("PKG_ADD_BASE")) { const char *ext; ext = strrchr(pkg_fullname, '.'); if (ext == NULL) ext = ".tbz"; snprintf(path, FILENAME_MAX, "%s/%s%s", getenv("_TOP"), p->name, ext); if (fexists(path)) cp = path; else cp = fileFindByPath(pkg, p->name); if (cp) { if (Verbose) printf("Loading it from %s.\n", cp); if (vsystem("%s %s %s '%s'", PkgAddCmd, Verbose ? "-v " : "", PrefixRecursive ? prefixArg : "", cp)) { warnx("autoload of dependency '%s' failed%s", cp, Force ? " (proceeding anyway)" : "!"); if (!Force) ++code; } } else { warnx("could not find package %s %s", p->name, Force ? " (proceeding anyway)" : "!"); if (!Force) ++code; } } else if ((cp = fileGetURL(pkg, p->name, KeepPackage)) != NULL) { if (Verbose) printf("Finished loading %s via a URL\n", p->name); if (!fexists("+CONTENTS")) { warnx("autoloaded package %s has no +CONTENTS file?", p->name); if (!Force) ++code; } else if (vsystem("(pwd; /bin/cat +CONTENTS) | %s %s %s %s -S", PkgAddCmd, Verbose ? "-v" : "", PrefixRecursive ? prefixArg : "", KeepPackage ? "-K" : "")) { warnx("pkg_add of dependency '%s' failed%s", p->name, Force ? " (proceeding anyway)" : "!"); if (!Force) ++code; } else if (Verbose) printf("\t'%s' loaded successfully.\n", p->name); /* Nuke the temporary playpen */ leave_playpen(); } } else { if (Verbose) printf("and was not found%s.\n", Force ? " (proceeding anyway)" : ""); else printf("Package dependency %s for %s not found%s\n", p->name, pkg, Force ? " (proceeding anyway)" : "!"); if (!Force) ++code; } } else if (Verbose) printf(" - already installed.\n"); } } /* if (!IgnoreDeps) */ if (code != 0) goto bomb; /* Look for the requirements file */ if ((fd = open(REQUIRE_FNAME, O_RDWR)) != -1) { fstat(fd, &sb); fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */ close(fd); if (Verbose) printf("Running requirements file first for %s..\n", Plist.name); if (!Fake && vsystem("./%s %s INSTALL", REQUIRE_FNAME, Plist.name)) { warnx("package %s fails requirements %s", pkg_fullname, Force ? "installing anyway" : "- not installed"); if (!Force) { code = 1; goto success; /* close enough for government work */ } } } /* * Test whether to use the old method of passing tokens to installation * scripts, and set appropriate variables.. */ if (fexists(POST_INSTALL_FNAME)) { new_m = 1; sprintf(post_script, "%s", POST_INSTALL_FNAME); pre_arg[0] = '\0'; post_arg[0] = '\0'; } else { if (fexists(INSTALL_FNAME)) { sprintf(post_script, "%s", INSTALL_FNAME); sprintf(pre_arg, "PRE-INSTALL"); sprintf(post_arg, "POST-INSTALL"); } } /* If we're really installing, and have an installation file, run it */ if (!NoInstall && (fd = open(pre_script, O_RDWR)) != -1) { fstat(fd, &sb); fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */ close(fd); if (Verbose) printf("Running pre-install for %s..\n", Plist.name); if (!Fake && vsystem("./%s %s %s", pre_script, Plist.name, pre_arg)) { warnx("install script returned error status"); unlink(pre_script); code = 1; goto success; /* nothing to uninstall yet */ } } /* Now finally extract the entire show if we're not going direct */ if (!inPlace && !Fake) extract_plist(".", &Plist); if (!Fake && fexists(MTREE_FNAME)) { if (Verbose) printf("Running mtree for %s..\n", Plist.name); p = find_plist(&Plist, PLIST_CWD); if (Verbose) printf("mtree -U -f %s -d -e -p %s >%s\n", MTREE_FNAME, p ? p->name : "/", _PATH_DEVNULL); if (!Fake) { if (vsystem("/usr/sbin/mtree -U -f %s -d -e -p %s >%s", MTREE_FNAME, p ? p->name : "/", _PATH_DEVNULL)) warnx("mtree returned a non-zero status - continuing"); } } /* Run the installation script one last time? */ if (!NoInstall && (fd = open(post_script, O_RDWR)) != -1) { fstat(fd, &sb); fchmod(fd, sb.st_mode | S_IXALL); /* be sure, chmod a+x */ close(fd); if (Verbose) printf("Running post-install for %s..\n", Plist.name); if (!Fake && vsystem("./%s %s %s", post_script, Plist.name, post_arg)) { warnx("install script returned error status"); unlink(post_script); code = 1; goto fail; } } /* Time to record the deed? */ if (!NoRecord && !Fake) { char contents[FILENAME_MAX]; char **depnames = NULL, **deporigins = NULL, ***depmatches; int i, dep_count = 0; FILE *contfile; if (getuid() != 0) warnx("not running as root - trying to record install anyway"); sprintf(LogDir, "%s/%s", LOG_DIR, Plist.name); zapLogDir = 1; if (Verbose) printf("Attempting to record package into %s..\n", LogDir); if (make_hierarchy(LogDir)) { warnx("can't record package into '%s', you're on your own!", LogDir); bzero(LogDir, FILENAME_MAX); code = 1; goto success; /* close enough for government work */ } /* Make sure pkg_info can read the entry */ fd = open(LogDir, O_RDWR); fstat(fd, &sb); fchmod(fd, sb.st_mode | S_IRALL | S_IXALL); /* be sure, chmod a+rx */ close(fd); move_file(".", DESC_FNAME, LogDir); move_file(".", COMMENT_FNAME, LogDir); if (fexists(INSTALL_FNAME)) move_file(".", INSTALL_FNAME, LogDir); if (fexists(POST_INSTALL_FNAME)) move_file(".", POST_INSTALL_FNAME, LogDir); if (fexists(DEINSTALL_FNAME)) move_file(".", DEINSTALL_FNAME, LogDir); if (fexists(POST_DEINSTALL_FNAME)) move_file(".", POST_DEINSTALL_FNAME, LogDir); if (fexists(REQUIRE_FNAME)) move_file(".", REQUIRE_FNAME, LogDir); if (fexists(DISPLAY_FNAME)) move_file(".", DISPLAY_FNAME, LogDir); if (fexists(MTREE_FNAME)) move_file(".", MTREE_FNAME, LogDir); sprintf(contents, "%s/%s", LogDir, CONTENTS_FNAME); contfile = fopen(contents, "w"); if (!contfile) { warnx("can't open new contents file '%s'! can't register pkg", contents); goto success; /* can't log, but still keep pkg */ } write_plist(&Plist, contfile); fclose(contfile); for (p = Plist.head; p ; p = p->next) { char *deporigin; if (p->type != PLIST_PKGDEP) continue; deporigin = (p->next->type == PLIST_DEPORIGIN) ? p->next->name : NULL; if (Verbose) { printf("Trying to record dependency on package '%s'", p->name); if (deporigin != NULL) printf(" with '%s' origin", deporigin); printf(".\n"); } if (deporigin) { /* Defer to origin lookup */ depnames = realloc(depnames, (dep_count + 1) * sizeof(*depnames)); depnames[dep_count] = p->name; deporigins = realloc(deporigins, (dep_count + 2) * sizeof(*deporigins)); deporigins[dep_count] = deporigin; deporigins[dep_count + 1] = NULL; dep_count++; } else { /* No origin recorded, try to register on literal package name */ sprintf(contents, "%s/%s/%s", LOG_DIR, p->name, REQUIRED_BY_FNAME); contfile = fopen(contents, "a"); if (!contfile) { warnx("can't open dependency file '%s'!\n" "dependency registration is incomplete", contents); } else { fprintf(contfile, "%s\n", Plist.name); if (fclose(contfile) == EOF) { warnx("cannot properly close file %s", contents); } } } } if (dep_count > 0) { depmatches = matchallbyorigin((const char **)deporigins, NULL); free(deporigins); if (!IgnoreDeps && depmatches) { for (i = 0; i < dep_count; i++) { if (depmatches[i]) { int j; char **tmp = depmatches[i]; for (j = 0; tmp[j] != NULL; j++) { /* Origin looked up */ sprintf(contents, "%s/%s/%s", LOG_DIR, tmp[j], REQUIRED_BY_FNAME); if (depnames[i] && strcmp(depnames[i], tmp[j]) != 0) warnx("warning: package '%s' requires '%s', but '%s' " "is installed", Plist.name, depnames[i], tmp[j]); contfile = fopen(contents, "a"); if (!contfile) { warnx("can't open dependency file '%s'!\n" "dependency registration is incomplete", contents); } else { fprintf(contfile, "%s\n", Plist.name); if (fclose(contfile) == EOF) warnx("cannot properly close file %s", contents); } } } else if (depnames[i]) { /* No package present with this origin, try literal package name */ sprintf(contents, "%s/%s/%s", LOG_DIR, depnames[i], REQUIRED_BY_FNAME); contfile = fopen(contents, "a"); if (!contfile) { warnx("can't open dependency file '%s'!\n" "dependency registration is incomplete", contents); } else { fprintf(contfile, "%s\n", Plist.name); if (fclose(contfile) == EOF) { warnx("cannot properly close file %s", contents); } } } } } } if (Verbose) printf("Package %s registered in %s\n", Plist.name, LogDir); } if ((p = find_plist(&Plist, PLIST_DISPLAY)) != NULL) { FILE *fp; char buf[BUFSIZ]; snprintf(buf, sizeof buf, "%s/%s", LogDir, p->name); fp = fopen(buf, "r"); if (fp) { putc('\n', stdout); while (fgets(buf, sizeof(buf), fp)) fputs(buf, stdout); putc('\n', stdout); (void) fclose(fp); } else { if (!Fake) { warnx("cannot open %s as display file", buf); } } } goto success; bomb: code = 1; goto success; fail: /* Nuke the whole (installed) show, XXX but don't clean directories */ if (!Fake) delete_package(FALSE, FALSE, &Plist); success: /* delete the packing list contents */ free_plist(&Plist); leave_playpen(); return code; }
/* * Given a file descriptor, create a capability with specific rights and * make sure only those rights work. */ static int try_file_ops(int fd, cap_rights_t rights) { struct stat sb; struct statfs sf; int fd_cap, fd_capcap; ssize_t ssize, ssize2; off_t off; void *p; char ch; int ret, is_nfs; struct pollfd pollfd; int success = PASSED; REQUIRE(fstatfs(fd, &sf)); is_nfs = (strncmp("nfs", sf.f_fstypename, sizeof(sf.f_fstypename)) == 0); REQUIRE(fd_cap = cap_new(fd, rights)); REQUIRE(fd_capcap = cap_new(fd_cap, rights)); CHECK(fd_capcap != fd_cap); pollfd.fd = fd_cap; pollfd.events = POLLIN | POLLERR | POLLHUP; pollfd.revents = 0; ssize = read(fd_cap, &ch, sizeof(ch)); CHECK_RESULT(read, CAP_READ | CAP_SEEK, ssize >= 0); ssize = pread(fd_cap, &ch, sizeof(ch), 0); ssize2 = pread(fd_cap, &ch, sizeof(ch), 0); CHECK_RESULT(pread, CAP_READ, ssize >= 0); CHECK(ssize == ssize2); ssize = write(fd_cap, &ch, sizeof(ch)); CHECK_RESULT(write, CAP_WRITE | CAP_SEEK, ssize >= 0); ssize = pwrite(fd_cap, &ch, sizeof(ch), 0); CHECK_RESULT(pwrite, CAP_WRITE, ssize >= 0); off = lseek(fd_cap, 0, SEEK_SET); CHECK_RESULT(lseek, CAP_SEEK, off >= 0); /* * Note: this is not expected to work over NFS. */ ret = fchflags(fd_cap, UF_NODUMP); CHECK_RESULT(fchflags, CAP_FCHFLAGS, (ret == 0) || (is_nfs && (errno == EOPNOTSUPP))); ret = fstat(fd_cap, &sb); CHECK_RESULT(fstat, CAP_FSTAT, ret == 0); p = mmap(NULL, getpagesize(), PROT_READ, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_READ); p = mmap(NULL, getpagesize(), PROT_WRITE, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_WRITE); p = mmap(NULL, getpagesize(), PROT_EXEC, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_MAPEXEC); p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_READ | CAP_WRITE); p = mmap(NULL, getpagesize(), PROT_READ | PROT_EXEC, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_READ | CAP_MAPEXEC); p = mmap(NULL, getpagesize(), PROT_EXEC | PROT_WRITE, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_MAPEXEC | CAP_WRITE); p = mmap(NULL, getpagesize(), PROT_READ | PROT_WRITE | PROT_EXEC, MAP_SHARED, fd_cap, 0); CHECK_MMAP_RESULT(CAP_MMAP | CAP_READ | CAP_WRITE | CAP_MAPEXEC); ret = fsync(fd_cap); CHECK_RESULT(fsync, CAP_FSYNC, ret == 0); ret = fchown(fd_cap, -1, -1); CHECK_RESULT(fchown, CAP_FCHOWN, ret == 0); ret = fchmod(fd_cap, 0644); CHECK_RESULT(fchmod, CAP_FCHMOD, ret == 0); /* XXX flock */ ret = ftruncate(fd_cap, 0); CHECK_RESULT(ftruncate, CAP_FTRUNCATE, ret == 0); ret = fstatfs(fd_cap, &sf); CHECK_RESULT(fstatfs, CAP_FSTATFS, ret == 0); ret = fpathconf(fd_cap, _PC_NAME_MAX); CHECK_RESULT(fpathconf, CAP_FPATHCONF, ret >= 0); ret = futimes(fd_cap, NULL); CHECK_RESULT(futimes, CAP_FUTIMES, ret == 0); ret = poll(&pollfd, 1, 0); if (rights & CAP_POLL_EVENT) CHECK((pollfd.revents & POLLNVAL) == 0); else CHECK((pollfd.revents & POLLNVAL) != 0); /* XXX: select, kqueue */ close (fd_cap); return (success); }
int main(int argc, char **argv) { char errmsg[255], path[PATH_MAX]; char *cp, *snapname; struct statfs stfsbuf; struct group *grp; struct stat stbuf; struct iovec *iov; int fd, iovlen; if (argc == 2) snapname = argv[1]; else if (argc == 3) snapname = argv[2]; /* Old usage. */ else usage(); /* * Check that the user running this program has permission * to create and remove a snapshot file from the directory * in which they have requested to have it made. If the * directory is sticky and not owned by the user, then they * will not be able to remove the snapshot when they are * done with it. */ if (strlen(snapname) >= PATH_MAX) errx(1, "pathname too long %s", snapname); cp = strrchr(snapname, '/'); if (cp == NULL) { strlcpy(path, ".", PATH_MAX); } else if (cp == snapname) { strlcpy(path, "/", PATH_MAX); } else { strlcpy(path, snapname, cp - snapname + 1); } if (statfs(path, &stfsbuf) < 0) err(1, "%s", path); if (stat(path, &stbuf) < 0) err(1, "%s", path); if (!S_ISDIR(stbuf.st_mode)) errx(1, "%s: Not a directory", path); if (access(path, W_OK) < 0) err(1, "Lack write permission in %s", path); if ((stbuf.st_mode & S_ISTXT) && stbuf.st_uid != getuid()) errx(1, "Lack write permission in %s: Sticky bit set", path); /* * Having verified access to the directory in which the * snapshot is to be built, proceed with creating it. */ if ((grp = getgrnam("operator")) == NULL) errx(1, "Cannot retrieve operator gid"); iov = NULL; iovlen = 0; build_iovec(&iov, &iovlen, "fstype", "ffs", 4); build_iovec(&iov, &iovlen, "from", snapname, (size_t)-1); build_iovec(&iov, &iovlen, "fspath", stfsbuf.f_mntonname, (size_t)-1); build_iovec(&iov, &iovlen, "errmsg", errmsg, sizeof(errmsg)); build_iovec(&iov, &iovlen, "update", NULL, 0); build_iovec(&iov, &iovlen, "snapshot", NULL, 0); *errmsg = '\0'; if (nmount(iov, iovlen, stfsbuf.f_flags) < 0) { errmsg[sizeof(errmsg) - 1] = '\0'; err(1, "Cannot create snapshot %s%s%s", snapname, *errmsg != '\0' ? ": " : "", errmsg); } if ((fd = open(snapname, O_RDONLY)) < 0) err(1, "Cannot open %s", snapname); if (fstat(fd, &stbuf) != 0) err(1, "Cannot stat %s", snapname); if ((stbuf.st_flags & SF_SNAPSHOT) == 0) errx(1, "File %s is not a snapshot", snapname); if (fchown(fd, -1, grp->gr_gid) != 0) err(1, "Cannot chown %s", snapname); if (fchmod(fd, S_IRUSR | S_IRGRP) != 0) err(1, "Cannot chmod %s", snapname); exit(EXIT_SUCCESS); }
int patch_main(int argc UNUSED_PARAM, char **argv) { int opts; int reverse, state = 0; char *oldname = NULL, *newname = NULL; char *opt_p, *opt_i; long oldlen = oldlen; /* for compiler */ long newlen = newlen; /* for compiler */ INIT_TT(); opts = getopt32(argv, FLAG_STR, &opt_p, &opt_i); argv += optind; reverse = opts & FLAG_REVERSE; TT.prefix = (opts & FLAG_PATHLEN) ? xatoi(opt_p) : 0; // can be negative! TT.filein = TT.fileout = -1; if (opts & FLAG_INPUT) { xmove_fd(xopen_stdin(opt_i), STDIN_FILENO); } else { if (argv[0] && argv[1]) { xmove_fd(xopen_stdin(argv[1]), STDIN_FILENO); } } if (argv[0]) { oldname = xstrdup(argv[0]); newname = xstrdup(argv[0]); } // Loop through the lines in the patch for(;;) { char *patchline; patchline = xmalloc_fgetline(stdin); if (!patchline) break; // Other versions of patch accept damaged patches, // so we need to also. if (!*patchline) { free(patchline); patchline = xstrdup(" "); } // Are we assembling a hunk? if (state >= 2) { if (*patchline==' ' || *patchline=='+' || *patchline=='-') { dlist_add(&TT.current_hunk, patchline); if (*patchline != '+') oldlen--; if (*patchline != '-') newlen--; // Context line? if (*patchline==' ' && state==2) TT.context++; else state=3; // If we've consumed all expected hunk lines, apply the hunk. if (!oldlen && !newlen) state = apply_one_hunk(); continue; } fail_hunk(); state = 0; continue; } // Open a new file? if (!strncmp("--- ", patchline, 4) || !strncmp("+++ ", patchline, 4)) { char *s, **name = reverse ? &newname : &oldname; int i; if (*patchline == '+') { name = reverse ? &oldname : &newname; state = 1; } finish_oldfile(); if (!argv[0]) { free(*name); // Trim date from end of filename (if any). We don't care. for (s = patchline+4; *s && *s!='\t'; s++) if (*s=='\\' && s[1]) s++; i = atoi(s); if (i>1900 && i<=1970) *name = xstrdup("/dev/null"); else { *s = 0; *name = xstrdup(patchline+4); } } // We defer actually opening the file because svn produces broken // patches that don't signal they want to create a new file the // way the patch man page says, so you have to read the first hunk // and _guess_. // Start a new hunk? Usually @@ -oldline,oldlen +newline,newlen @@ // but a missing ,value means the value is 1. } else if (state == 1 && !strncmp("@@ -", patchline, 4)) { int i; char *s = patchline+4; // Read oldline[,oldlen] +newline[,newlen] TT.oldlen = oldlen = TT.newlen = newlen = 1; TT.oldline = strtol(s, &s, 10); if (*s == ',') TT.oldlen = oldlen = strtol(s+1, &s, 10); TT.newline = strtol(s+2, &s, 10); if (*s == ',') TT.newlen = newlen = strtol(s+1, &s, 10); if (oldlen < 1 && newlen < 1) bb_error_msg_and_die("Really? %s", patchline); TT.context = 0; state = 2; // If this is the first hunk, open the file. if (TT.filein == -1) { int oldsum, newsum, empty = 0; char *name; oldsum = TT.oldline + oldlen; newsum = TT.newline + newlen; name = reverse ? oldname : newname; // We're deleting oldname if new file is /dev/null (before -p) // or if new hunk is empty (zero context) after patching if (!strcmp(name, "/dev/null") || !(reverse ? oldsum : newsum)) { name = reverse ? newname : oldname; empty++; } // handle -p path truncation. for (i=0, s = name; *s;) { if ((option_mask32 & FLAG_PATHLEN) && TT.prefix == i) break; if (*(s++)=='/') { name = s; i++; } } if (empty) { // File is empty after the patches have been applied state = 0; if (option_mask32 & FLAG_RMEMPTY) { // If flag -E or --remove-empty-files is set printf("removing %s\n", name); xunlink(name); } else { printf("patching file %s\n", name); xclose(xopen(name, O_WRONLY | O_TRUNC)); } // If we've got a file to open, do so. } else if (!(option_mask32 & FLAG_PATHLEN) || i <= TT.prefix) { struct stat statbuf; // If the old file was null, we're creating a new one. if (!strcmp(oldname, "/dev/null") || !oldsum) { printf("creating %s\n", name); s = strrchr(name, '/'); if (s) { *s = 0; bb_make_directory(name, -1, FILEUTILS_RECUR); *s = '/'; } TT.filein = xopen(name, O_CREAT|O_EXCL|O_RDWR); } else { printf("patching file %s\n", name); TT.filein = xopen(name, O_RDONLY); } TT.tempname = xasprintf("%sXXXXXX", name); TT.fileout = xmkstemp(TT.tempname); // Set permissions of output file fstat(TT.filein, &statbuf); fchmod(TT.fileout, statbuf.st_mode); TT.linenum = 0; TT.hunknum = 0; } } TT.hunknum++; continue; } // If we didn't continue above, discard this line. free(patchline); } finish_oldfile(); if (ENABLE_FEATURE_CLEAN_UP) { free(oldname); free(newname); } return TT.exitval; }
void update_mtab (const char *dir, struct my_mntent *instead) { mntFILE *mfp, *mftmp; const char *fnam = MOUNTED; struct mntentchn mtabhead; /* dummy */ struct mntentchn *mc, *mc0, *absent = NULL; if (mtab_does_not_exist() || mtab_is_a_symlink()) return; lock_mtab(); /* having locked mtab, read it again */ mc0 = mc = &mtabhead; mc->nxt = mc->prev = NULL; mfp = my_setmntent(fnam, "r"); if (mfp == NULL || mfp->mntent_fp == NULL) { int errsv = errno; error (_("cannot open %s (%s) - mtab not updated"), fnam, strerror (errsv)); goto leave; } read_mntentchn(mfp, fnam, mc); /* find last occurrence of dir */ for (mc = mc0->prev; mc && mc != mc0; mc = mc->prev) if (streq(mc->m.mnt_dir, dir)) break; if (mc && mc != mc0) { if (instead == NULL) { /* An umount - remove entry */ if (mc && mc != mc0) { mc->prev->nxt = mc->nxt; mc->nxt->prev = mc->prev; free(mc); } } else { /* A remount */ mc->m.mnt_opts = instead->mnt_opts; } } else if (instead) { /* not found, add a new entry */ absent = xmalloc(sizeof(*absent)); absent->m = *instead; absent->nxt = mc0; absent->prev = mc0->prev; mc0->prev = absent; if (mc0->nxt == NULL) mc0->nxt = absent; } /* write chain to mtemp */ mftmp = my_setmntent (MOUNTED_TEMP, "w"); if (mftmp == NULL || mftmp->mntent_fp == NULL) { int errsv = errno; error (_("cannot open %s (%s) - mtab not updated"), MOUNTED_TEMP, strerror (errsv)); goto leave; } for (mc = mc0->nxt; mc && mc != mc0; mc = mc->nxt) { if (my_addmntent(mftmp, &(mc->m)) == 1) { int errsv = errno; die (EX_FILEIO, _("error writing %s: %s"), MOUNTED_TEMP, strerror (errsv)); } } discard_mntentchn(mc0); if (fchmod (fileno (mftmp->mntent_fp), S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { int errsv = errno; fprintf(stderr, _("error changing mode of %s: %s\n"), MOUNTED_TEMP, strerror (errsv)); } my_endmntent (mftmp); { /* * If mount is setuid and some non-root user mounts sth, * then mtab.tmp might get the group of this user. Copy uid/gid * from the present mtab before renaming. */ struct stat sbuf; if (stat (MOUNTED, &sbuf) == 0) chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid); } /* rename mtemp to mtab */ if (rename (MOUNTED_TEMP, MOUNTED) < 0) { int errsv = errno; fprintf(stderr, _("can't rename %s to %s: %s\n"), MOUNTED_TEMP, MOUNTED, strerror(errsv)); } leave: unlock_mtab(); }
int extractfile(char *name) { int flags; uid_t uid; gid_t gid; mode_t mode; int extsize; struct timeval mtimep[2], ctimep[2]; struct entry *ep; char *buf; curfile.name = name; curfile.action = USING; mtimep[0].tv_sec = curfile.atime_sec; mtimep[0].tv_usec = curfile.atime_nsec / 1000; mtimep[1].tv_sec = curfile.mtime_sec; mtimep[1].tv_usec = curfile.mtime_nsec / 1000; ctimep[0].tv_sec = curfile.atime_sec; ctimep[0].tv_usec = curfile.atime_nsec / 1000; ctimep[1].tv_sec = curfile.birthtime_sec; ctimep[1].tv_usec = curfile.birthtime_nsec / 1000; extsize = curfile.extsize; uid = getuid(); if (uid == 0) uid = curfile.uid; gid = curfile.gid; mode = curfile.mode; flags = curfile.file_flags; switch (mode & IFMT) { default: fprintf(stderr, "%s: unknown file mode 0%o\n", name, mode); skipfile(); return (FAIL); case IFSOCK: vprintf(stdout, "skipped socket %s\n", name); skipfile(); return (GOOD); case IFDIR: if (mflag) { ep = lookupname(name); if (ep == NULL || ep->e_flags & EXTRACT) panic("unextracted directory %s\n", name); skipfile(); return (GOOD); } vprintf(stdout, "extract file %s\n", name); return (genliteraldir(name, curfile.ino)); case IFLNK: lnkbuf[0] = '\0'; pathlen = 0; buf = setupextattr(extsize); getfile(xtrlnkfile, xtrattr, xtrlnkskip); if (pathlen == 0) { vprintf(stdout, "%s: zero length symbolic link (ignored)\n", name); return (GOOD); } if (linkit(lnkbuf, name, SYMLINK) == GOOD) { if (extsize > 0) set_extattr_link(name, buf, extsize); (void) lchown(name, uid, gid); (void) lchmod(name, mode); (void) lutimes(name, ctimep); (void) lutimes(name, mtimep); (void) lchflags(name, flags); return (GOOD); } return (FAIL); case IFIFO: vprintf(stdout, "extract fifo %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) (void) unlink(name); if (mkfifo(name, 0600) < 0) { fprintf(stderr, "%s: cannot create fifo: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } if (extsize == 0) { skipfile(); } else { buf = setupextattr(extsize); getfile(xtrnull, xtrattr, xtrnull); set_extattr_file(name, buf, extsize); } (void) chown(name, uid, gid); (void) chmod(name, mode); (void) utimes(name, ctimep); (void) utimes(name, mtimep); (void) chflags(name, flags); return (GOOD); case IFCHR: case IFBLK: vprintf(stdout, "extract special file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) (void) unlink(name); if (mknod(name, (mode & (IFCHR | IFBLK)) | 0600, (int)curfile.rdev) < 0) { fprintf(stderr, "%s: cannot create special file: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } if (extsize == 0) { skipfile(); } else { buf = setupextattr(extsize); getfile(xtrnull, xtrattr, xtrnull); set_extattr_file(name, buf, extsize); } (void) chown(name, uid, gid); (void) chmod(name, mode); (void) utimes(name, ctimep); (void) utimes(name, mtimep); (void) chflags(name, flags); return (GOOD); case IFREG: vprintf(stdout, "extract file %s\n", name); if (Nflag) { skipfile(); return (GOOD); } if (uflag) (void) unlink(name); if ((ofile = open(name, O_WRONLY | O_CREAT | O_TRUNC, 0600)) < 0) { fprintf(stderr, "%s: cannot create file: %s\n", name, strerror(errno)); skipfile(); return (FAIL); } buf = setupextattr(extsize); getfile(xtrfile, xtrattr, xtrskip); if (extsize > 0) set_extattr_fd(ofile, name, buf, extsize); (void) fchown(ofile, uid, gid); (void) fchmod(ofile, mode); (void) futimes(ofile, ctimep); (void) futimes(ofile, mtimep); (void) fchflags(ofile, flags); (void) close(ofile); return (GOOD); } /* NOTREACHED */ }
int main(int ac, char **av) { struct stat stat_buf; /* stat struct */ int lc; /* loop counter */ char *msg; /* message returned from parse_opts */ mode_t dir_mode; /* mode permissions set on test directory */ /* Parse standard options given to run the test. */ msg = parse_opts(ac, av, NULL, NULL); if (msg != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { Tst_count = 0; /* * Call fchmod(2) with mode argument * to set setgid bit on TESTDIR. */ TEST(fchmod(fd, PERMS)); if (TEST_RETURN == -1) { tst_resm(TFAIL, "fchmod(%d, %#o) Failed, errno=%d : %s", fd, PERMS, TEST_ERRNO, strerror(TEST_ERRNO)); continue; } /* * Perform functional verification if test * executed without (-f) option. */ if (STD_FUNCTIONAL_TEST) { /* * Get the directory information using * fstat(2). */ if (fstat(fd, &stat_buf) < 0) { tst_brkm(TFAIL, cleanup, "fstat(2) of %s failed, errno:%d", TESTDIR, TEST_ERRNO); } dir_mode = stat_buf.st_mode; if ((PERMS & ~S_ISGID) != dir_mode) { tst_resm(TFAIL, "%s: Incorrect modes 0%03o, " "Expected 0%03o", TESTDIR, dir_mode, PERMS & ~S_ISGID); } else { tst_resm(TPASS, "Functionality of fchmod(%d, " "%#o) successful", fd, PERMS & ~S_ISGID); } } else { tst_resm(TPASS, "call succeeded"); } } cleanup(); tst_exit(); }
static int copy_reg(const char *source, const char *dest) { SMB_STRUCT_STAT source_stats; int saved_errno; int ifd = -1; int ofd = -1; if (sys_lstat(source, &source_stats, false) == -1) return -1; if (!S_ISREG (source_stats.st_ex_mode)) return -1; if (source_stats.st_ex_size > module_sizelimit) { DEBUG(5, ("%s: size of %s larger than sizelimit (%lld > %lld), rename prohititted\n", MODULE, source, (long long)source_stats.st_ex_size, (long long)module_sizelimit)); return -1; } if((ifd = open (source, O_RDONLY, 0)) < 0) return -1; if (unlink (dest) && errno != ENOENT) { close(ifd); return -1; } #ifdef O_NOFOLLOW if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC | O_NOFOLLOW, 0600)) < 0 ) #else if((ofd = open (dest, O_WRONLY | O_CREAT | O_TRUNC , 0600)) < 0 ) #endif goto err; if (transfer_file(ifd, ofd, source_stats.st_ex_size) == -1) goto err; /* * Try to preserve ownership. For non-root it might fail, but that's ok. * But root probably wants to know, e.g. if NFS disallows it. */ #ifdef HAVE_FCHOWN if ((fchown(ofd, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM)) #else if ((chown(dest, source_stats.st_ex_uid, source_stats.st_ex_gid) == -1) && (errno != EPERM)) #endif goto err; /* * fchown turns off set[ug]id bits for non-root, * so do the chmod last. */ #if defined(HAVE_FCHMOD) if ((fchmod (ofd, source_stats.st_ex_mode & 07777) == -1) && (errno != EPERM)) #else if ((chmod (dest, source_stats.st_ex_mode & 07777) == -1) && (errno != EPERM)) #endif goto err; if (close (ifd) == -1) goto err; if (close (ofd) == -1) return -1; /* Try to copy the old file's modtime and access time. */ #if defined(HAVE_UTIMENSAT) { struct timespec ts[2]; ts[0] = source_stats.st_ex_atime; ts[1] = source_stats.st_ex_mtime; utimensat(AT_FDCWD, dest, ts, AT_SYMLINK_NOFOLLOW); } #elif defined(HAVE_UTIMES) { struct timeval tv[2]; tv[0] = convert_timespec_to_timeval(source_stats.st_ex_atime); tv[1] = convert_timespec_to_timeval(source_stats.st_ex_mtime); #ifdef HAVE_LUTIMES lutimes(dest, tv); #else utimes(dest, tv); #endif } #elif defined(HAVE_UTIME) { struct utimbuf tv; tv.actime = convert_timespec_to_time_t(source_stats.st_ex_atime); tv.modtime = convert_timespec_to_time_t(source_stats.st_ex_mtime); utime(dest, &tv); } #endif if (unlink (source) == -1) return -1; return 0; err: saved_errno = errno; if (ifd != -1) close(ifd); if (ofd != -1) close(ofd); errno = saved_errno; return -1; }
static gboolean write_regular_file_content (OstreeRepo *self, OstreeRepoCheckoutOptions *options, GOutputStream *output, GFileInfo *file_info, GVariant *xattrs, GInputStream *input, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; const OstreeRepoCheckoutMode mode = options->mode; int fd; int res; if (g_output_stream_splice (output, input, 0, cancellable, error) < 0) goto out; if (!g_output_stream_flush (output, cancellable, error)) goto out; fd = g_file_descriptor_based_get_fd ((GFileDescriptorBased*)output); if (mode != OSTREE_REPO_CHECKOUT_MODE_USER) { do res = fchown (fd, g_file_info_get_attribute_uint32 (file_info, "unix::uid"), g_file_info_get_attribute_uint32 (file_info, "unix::gid")); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } do res = fchmod (fd, g_file_info_get_attribute_uint32 (file_info, "unix::mode")); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } if (xattrs) { if (!glnx_fd_set_all_xattrs (fd, xattrs, cancellable, error)) goto out; } } if (fsync_is_enabled (self, options)) { if (fsync (fd) == -1) { glnx_set_error_from_errno (error); goto out; } } if (!g_output_stream_close (output, cancellable, error)) goto out; ret = TRUE; out: return ret; }
int x11_write_data(Context *c) { _cleanup_fclose_ FILE *f = NULL; _cleanup_free_ char *temp_path = NULL; struct stat st; int r; if (isempty(c->x11_layout) && isempty(c->x11_model) && isempty(c->x11_variant) && isempty(c->x11_options)) { if (unlink("/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) return errno == ENOENT ? 0 : -errno; c->vc_mtime = USEC_INFINITY; return 0; } mkdir_p_label("/etc/X11/xorg.conf.d", 0755); r = fopen_temporary("/etc/X11/xorg.conf.d/00-keyboard.conf", &f, &temp_path); if (r < 0) return r; (void) __fsetlocking(f, FSETLOCKING_BYCALLER); (void) fchmod(fileno(f), 0644); fputs("# Written by systemd-localed(8), read by systemd-localed and Xorg. It's\n" "# probably wise not to edit this file manually. Use localectl(1) to\n" "# instruct systemd-localed to update it.\n" "Section \"InputClass\"\n" " Identifier \"system-keyboard\"\n" " MatchIsKeyboard \"on\"\n", f); if (!isempty(c->x11_layout)) fprintf(f, " Option \"XkbLayout\" \"%s\"\n", c->x11_layout); if (!isempty(c->x11_model)) fprintf(f, " Option \"XkbModel\" \"%s\"\n", c->x11_model); if (!isempty(c->x11_variant)) fprintf(f, " Option \"XkbVariant\" \"%s\"\n", c->x11_variant); if (!isempty(c->x11_options)) fprintf(f, " Option \"XkbOptions\" \"%s\"\n", c->x11_options); fputs("EndSection\n", f); r = fflush_sync_and_check(f); if (r < 0) goto fail; if (rename(temp_path, "/etc/X11/xorg.conf.d/00-keyboard.conf") < 0) { r = -errno; goto fail; } if (stat("/etc/X11/xorg.conf.d/00-keyboard.conf", &st) >= 0) c->x11_mtime = timespec_load(&st.st_mtim); return 0; fail: if (temp_path) (void) unlink(temp_path); return r; }
/* * checkout_tree_at: * @self: Repo * @mode: Options controlling all files * @overwrite_mode: Whether or not to overwrite files * @destination_parent_fd: Place tree here * @destination_name: Use this name for tree * @source: Source tree * @source_info: Source info * @cancellable: Cancellable * @error: Error * * Like ostree_repo_checkout_tree(), but check out @source into the * relative @destination_name, located by @destination_parent_fd. */ static gboolean checkout_tree_at (OstreeRepo *self, OstreeRepoCheckoutOptions *options, int destination_parent_fd, const char *destination_name, OstreeRepoFile *source, GFileInfo *source_info, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; gboolean did_exist = FALSE; int destination_dfd = -1; int res; g_autoptr(GVariant) xattrs = NULL; g_autoptr(GFileEnumerator) dir_enum = NULL; /* Create initially with mode 0700, then chown/chmod only when we're * done. This avoids anyone else being able to operate on partially * constructed dirs. */ do res = mkdirat (destination_parent_fd, destination_name, 0700); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (res == -1) { if (errno == EEXIST && options->overwrite_mode == OSTREE_REPO_CHECKOUT_OVERWRITE_UNION_FILES) did_exist = TRUE; else { glnx_set_error_from_errno (error); goto out; } } if (!glnx_opendirat (destination_parent_fd, destination_name, TRUE, &destination_dfd, error)) goto out; /* Set the xattrs now, so any derived labeling works */ if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) { if (!ostree_repo_file_get_xattrs (source, &xattrs, NULL, error)) goto out; if (xattrs) { if (!glnx_fd_set_all_xattrs (destination_dfd, xattrs, cancellable, error)) goto out; } } if (g_file_info_get_file_type (source_info) != G_FILE_TYPE_DIRECTORY) { ret = checkout_one_file_at (self, options, (GFile *) source, source_info, destination_dfd, g_file_info_get_name (source_info), cancellable, error); goto out; } dir_enum = g_file_enumerate_children ((GFile*)source, OSTREE_GIO_FAST_QUERYINFO, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!dir_enum) goto out; while (TRUE) { GFileInfo *file_info; GFile *src_child; const char *name; if (!gs_file_enumerator_iterate (dir_enum, &file_info, &src_child, cancellable, error)) goto out; if (file_info == NULL) break; name = g_file_info_get_name (file_info); if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { if (!checkout_tree_at (self, options, destination_dfd, name, (OstreeRepoFile*)src_child, file_info, cancellable, error)) goto out; } else { if (!checkout_one_file_at (self, options, src_child, file_info, destination_dfd, name, cancellable, error)) goto out; } } /* We do fchmod/fchown last so that no one else could access the * partially created directory and change content we're laying out. */ if (!did_exist) { do res = fchmod (destination_dfd, g_file_info_get_attribute_uint32 (source_info, "unix::mode")); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } if (!did_exist && options->mode != OSTREE_REPO_CHECKOUT_MODE_USER) { do res = fchown (destination_dfd, g_file_info_get_attribute_uint32 (source_info, "unix::uid"), g_file_info_get_attribute_uint32 (source_info, "unix::gid")); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } /* Set directory mtime to 0, so that it is constant for all checkouts. * Must be done after setting permissions and creating all children. */ if (!did_exist) { const struct timespec times[2] = { { 0, UTIME_OMIT }, { 0, } }; do res = futimens (destination_dfd, times); while (G_UNLIKELY (res == -1 && errno == EINTR)); if (G_UNLIKELY (res == -1)) { glnx_set_error_from_errno (error); goto out; } } if (fsync_is_enabled (self, options)) { if (fsync (destination_dfd) == -1) { glnx_set_error_from_errno (error); goto out; } } ret = TRUE; out: if (destination_dfd != -1) (void) close (destination_dfd); return ret; }
bool hostupdate_h(connection_t *c) { /* FIXME: Whoah! Even more!! */ char rawfile[MAX_STRING_SIZE]; char rawhost[MAX_STRING_SIZE], b64host[MAX_STRING_SIZE]; char rawdgst[MAX_STRING_SIZE], b64dgst[MAX_STRING_SIZE]; char updname[MAX_STRING_SIZE], hosttoupd[MAX_STRING_SIZE]; char *fname; FILE *fp; size_t slen, dlen, rlen; RSA *updkey; /* We ignore host files updates, maybe for reason */ if (ignorenetupdates() || ignorehostsupdates()) return true; /* handle received host data, check sign, (over)write on disk */ if (sscanf(c->buffer, "%*d " MAX_STRING " " MAX_STRING " " MAX_STRING " %zd %zd " MAX_STRING, updname, hosttoupd, b64host, &slen, &dlen, b64dgst) != 6) { logger(LOG_ERR, "Got bad %s from %s (%s)", "HOSTUPDATE", c->name, c->hostname); return false; } /* verify the originating node is permitted to send updates */ if (dontverifyupdatepermission()) goto _next; if(!getconf_bool_node_offline(updname, "HostsFilesMaster")) { ifdebug(PROTOCOL) logger(LOG_WARNING, "Ignoring hosts update request originating from %s [which came from %s (%s)]", updname, c->name, c->hostname); return true; } /* some other sanity checks */ _next: if (!isvalidfname(updname)) { logger(LOG_ERR, "Got bogus updater name \"%s\" from %s (%s) (from: %s)", updname, c->name, c->hostname, updname); return false; } if (!isvalidfname(hosttoupd)) { logger(LOG_ERR, "Got bogus update name \"%s\" from %s (%s) (from: %s)", hosttoupd, c->name, c->hostname, updname); return false; } if (slen >= MAX_STRING_SIZE || dlen >= MAX_STRING_SIZE) { logger(LOG_ERR, "HOSTUPDATE string sizes for %s are bigger than buffer can fit (%zd, %zd)", hosttoupd, slen, dlen); return false; } /* verify it */ if (dontverifyupdatesignature()) goto _out; if (!read_rsa_public_key_offline(updname, &updkey)) { logger(LOG_ERR, "Could not find public key for %s", updname); return true; } base64_decode(b64dgst, rawdgst, sizeof(rawdgst)-1); snprintf(rawhost, sizeof(rawhost), "%s %s %s %zd %zd", updname, hosttoupd, b64host, slen, dlen); rlen = strlen(rawhost); if (!EVP_verify(updkey, rawdgst, dlen, rawhost, rlen)) { logger(LOG_WARNING, "Ignoring hosts update request with bad signature from %s for %s" " [which came from %s (%s)]", updname, hosttoupd, c->name, c->hostname); RSA_free(updkey); return true; } RSA_free(updkey); /* neighbours return us our own packets */ _out: if (!strcmp(updname, myself->name)) return true; /* All right, let's start updating */ xasprintf(&fname, "%s/hosts/%s", confbase, hosttoupd); /* Tell others if needed */ if (!dontforwardhostsupdates()) { exceptmasters = true; forward_request(c); } /* Check if it's a START marker */ if (!strcmp(updname, hosttoupd) && !strcmp(b64host, "START")) { /* Run pre-update script (embedded devices do remount,rw fs for example) We really need to run this once, so that's why there are START and END markers */ run_script("hostsupdate-before"); /* That's it folks! Waiting for files to arrive */ free(fname); return true; } /* Check if it's a END marker */ else if (!strcmp(updname, hosttoupd) && !strcmp(b64host, "END")) { /* Run post-update script (embedded devices do remount,ro fs for example) */ run_script("hostsupdate-after"); /* Schedule config/host reload */ schedulereload(); /* That's it folks! */ free(fname); return true; } /* Remove unneeded hosts */ else if (!strcmp(b64host, "DEAD")) { unlink(fname); /* That's it, waiting for other next request */ free(fname); return true; } /* We need this early for next test */ base64_decode(b64host, rawhost, sizeof(rawhost)-1); /* * Via broadcasting host files one hosts file master can become config file master. * Reject such a claims even if they're authentic. */ if (dontverifyupdatepermission()) goto _write; if(!getconf_bool_node_offline(updname, "ConfFileMaster") && strcasestr_local(rawhost, "ConfFileMaster")) { logger(LOG_WARNING, "Ignoring %s which tried to raise privileges for %s to ConfFileMaster!", updname, hosttoupd); goto _end; } /* Finally write it to disk */ _write: fp = fopen(fname, "w"); if (!fp) { logger(LOG_ERR, "Unable to write new host file: %s (%s)", fname, strerror(errno)); free(fname); return true; } #ifdef HAVE_FCHMOD fchmod(fileno(fp), 0640); #endif fwrite(rawhost, slen, 1, fp); fclose(fp); _end: free(fname); return true; }
static gboolean cp_internal (GFile *src, GFile *dest, GsCpMode mode, GCancellable *cancellable, GError **error) { gboolean ret = FALSE; GFileEnumerator *enumerator = NULL; GFileInfo *src_info = NULL; GFile *dest_child = NULL; int dest_dfd = -1; int r; enumerator = g_file_enumerate_children (src, "standard::type,standard::name,unix::uid,unix::gid,unix::mode", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!enumerator) goto out; src_info = g_file_query_info (src, "standard::name,unix::mode,unix::uid,unix::gid," \ "time::modified,time::modified-usec,time::access,time::access-usec", G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, cancellable, error); if (!src_info) goto out; do r = mkdir (gs_file_get_path_cached (dest), 0755); while (G_UNLIKELY (r == -1 && errno == EINTR)); if (r == -1) { gs_set_error_from_errno (error, errno); goto out; } if (mode != GS_CP_MODE_NONE) { if (!gs_file_open_dir_fd (dest, &dest_dfd, cancellable, error)) goto out; do r = fchown (dest_dfd, g_file_info_get_attribute_uint32 (src_info, "unix::uid"), g_file_info_get_attribute_uint32 (src_info, "unix::gid")); while (G_UNLIKELY (r == -1 && errno == EINTR)); if (r == -1) { gs_set_error_from_errno (error, errno); goto out; } do r = fchmod (dest_dfd, g_file_info_get_attribute_uint32 (src_info, "unix::mode")); while (G_UNLIKELY (r == -1 && errno == EINTR)); { GError *temp_error = NULL; if (!copy_xattrs_from_file_to_fd (src, dest_dfd, cancellable, &temp_error)) { if (g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED) || g_error_matches (temp_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED)) { g_clear_error (&temp_error); } else { g_propagate_error (error, temp_error); goto out; } } } if (dest_dfd != -1) { (void) close (dest_dfd); dest_dfd = -1; } } while (TRUE) { GFileInfo *file_info = NULL; GFile *src_child = NULL; if (!gs_file_enumerator_iterate (enumerator, &file_info, &src_child, cancellable, error)) goto out; if (!file_info) break; if (dest_child) g_object_unref (dest_child); dest_child = g_file_get_child (dest, g_file_info_get_name (file_info)); if (g_file_info_get_file_type (file_info) == G_FILE_TYPE_DIRECTORY) { if (!cp_internal (src_child, dest_child, mode, cancellable, error)) goto out; } else { gboolean did_link = FALSE; (void) unlink (gs_file_get_path_cached (dest_child)); if (mode == GS_CP_MODE_HARDLINK) { if (link (gs_file_get_path_cached (src_child), gs_file_get_path_cached (dest_child)) == -1) { if (!(errno == EMLINK || errno == EXDEV || errno == EPERM)) { gs_set_error_from_errno (error, errno); goto out; } /* We failed to hardlink; fall back to copying all; this will * affect subsequent directory copies too. */ mode = GS_CP_MODE_COPY_ALL; } else did_link = TRUE; } if (!did_link) { GFileCopyFlags copyflags = G_FILE_COPY_OVERWRITE | G_FILE_COPY_NOFOLLOW_SYMLINKS; if (mode == GS_CP_MODE_COPY_ALL) copyflags |= G_FILE_COPY_ALL_METADATA; if (!g_file_copy (src_child, dest_child, copyflags, cancellable, NULL, NULL, error)) goto out; } } } ret = TRUE; out: if (dest_dfd != -1) (void) close (dest_dfd); g_clear_object (&src_info); g_clear_object (&enumerator); g_clear_object (&dest_child); return ret; }