/* * Parse a RTM_NEWADDR or RTM_DELADDR message. */ bool NetlinkEvent::parseIfAddrMessage(const struct nlmsghdr *nh) { struct ifaddrmsg *ifaddr = (struct ifaddrmsg *) NLMSG_DATA(nh); struct ifa_cacheinfo *cacheinfo = NULL; char addrstr[INET6_ADDRSTRLEN] = ""; char ifname[IFNAMSIZ]; if (!checkRtNetlinkLength(nh, sizeof(*ifaddr))) return false; // Sanity check. int type = nh->nlmsg_type; if (type != RTM_NEWADDR && type != RTM_DELADDR) { SLOGE("parseIfAddrMessage on incorrect message type 0x%x\n", type); return false; } // For log messages. const char *msgtype = rtMessageName(type); struct rtattr *rta; int len = IFA_PAYLOAD(nh); for (rta = IFA_RTA(ifaddr); RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) { if (rta->rta_type == IFA_ADDRESS) { // Only look at the first address, because we only support notifying // one change at a time. if (maybeLogDuplicateAttribute(*addrstr != '\0', "IFA_ADDRESS", msgtype)) continue; // Convert the IP address to a string. if (ifaddr->ifa_family == AF_INET) { struct in_addr *addr4 = (struct in_addr *) RTA_DATA(rta); if (RTA_PAYLOAD(rta) < sizeof(*addr4)) { SLOGE("Short IPv4 address (%zu bytes) in %s", RTA_PAYLOAD(rta), msgtype); continue; } inet_ntop(AF_INET, addr4, addrstr, sizeof(addrstr)); } else if (ifaddr->ifa_family == AF_INET6) { struct in6_addr *addr6 = (struct in6_addr *) RTA_DATA(rta); if (RTA_PAYLOAD(rta) < sizeof(*addr6)) { SLOGE("Short IPv6 address (%zu bytes) in %s", RTA_PAYLOAD(rta), msgtype); continue; } inet_ntop(AF_INET6, addr6, addrstr, sizeof(addrstr)); } else { SLOGE("Unknown address family %d\n", ifaddr->ifa_family); continue; } // Find the interface name. if (!if_indextoname(ifaddr->ifa_index, ifname)) { SLOGE("Unknown ifindex %d in %s", ifaddr->ifa_index, msgtype); return false; } } else if (rta->rta_type == IFA_CACHEINFO) { // Address lifetime information. if (maybeLogDuplicateAttribute(cacheinfo, "IFA_CACHEINFO", msgtype)) continue; if (RTA_PAYLOAD(rta) < sizeof(*cacheinfo)) { SLOGE("Short IFA_CACHEINFO (%zu vs. %zu bytes) in %s", RTA_PAYLOAD(rta), sizeof(cacheinfo), msgtype); continue; } cacheinfo = (struct ifa_cacheinfo *) RTA_DATA(rta); } } if (addrstr[0] == '\0') { SLOGE("No IFA_ADDRESS in %s\n", msgtype); return false; } // Fill in netlink event information. mAction = (type == RTM_NEWADDR) ? NlActionAddressUpdated : NlActionAddressRemoved; mSubsystem = strdup("net"); asprintf(&mParams[0], "ADDRESS=%s/%d", addrstr, ifaddr->ifa_prefixlen); asprintf(&mParams[1], "INTERFACE=%s", ifname); asprintf(&mParams[2], "FLAGS=%u", ifaddr->ifa_flags); asprintf(&mParams[3], "SCOPE=%u", ifaddr->ifa_scope); if (cacheinfo) { asprintf(&mParams[4], "PREFERRED=%u", cacheinfo->ifa_prefered); asprintf(&mParams[5], "VALID=%u", cacheinfo->ifa_valid); asprintf(&mParams[6], "CSTAMP=%u", cacheinfo->cstamp); asprintf(&mParams[7], "TSTAMP=%u", cacheinfo->tstamp); } return true; }
void input_item_SetURI( input_item_t *p_i, const char *psz_uri ) { assert( psz_uri ); #ifndef NDEBUG if( !strstr( psz_uri, "://" ) || strchr( psz_uri, ' ' ) || strchr( psz_uri, '"' ) ) fprintf( stderr, "Warning: %s(\"%s\"): file path instead of URL.\n", __func__, psz_uri ); #endif vlc_mutex_lock( &p_i->lock ); free( p_i->psz_uri ); p_i->psz_uri = strdup( psz_uri ); p_i->i_type = GuessType( p_i ); if( p_i->psz_name ) ; else if( p_i->i_type == ITEM_TYPE_FILE || p_i->i_type == ITEM_TYPE_DIRECTORY ) { const char *psz_filename = strrchr( p_i->psz_uri, '/' ); if( psz_filename && *psz_filename == '/' ) psz_filename++; if( psz_filename && *psz_filename ) p_i->psz_name = strdup( psz_filename ); /* Make the name more readable */ if( p_i->psz_name ) { decode_URI( p_i->psz_name ); EnsureUTF8( p_i->psz_name ); } } else { /* Strip login and password from title */ int r; vlc_url_t url; vlc_UrlParse( &url, psz_uri, 0 ); if( url.psz_protocol ) { if( url.i_port > 0 ) r=asprintf( &p_i->psz_name, "%s://%s:%d%s", url.psz_protocol, url.psz_host, url.i_port, url.psz_path ? url.psz_path : "" ); else r=asprintf( &p_i->psz_name, "%s://%s%s", url.psz_protocol, url.psz_host ? url.psz_host : "", url.psz_path ? url.psz_path : "" ); } else { if( url.i_port > 0 ) r=asprintf( &p_i->psz_name, "%s:%d%s", url.psz_host, url.i_port, url.psz_path ? url.psz_path : "" ); else r=asprintf( &p_i->psz_name, "%s%s", url.psz_host, url.psz_path ? url.psz_path : "" ); } vlc_UrlClean( &url ); if( -1==r ) p_i->psz_name=NULL; /* recover from undefined value */ } vlc_mutex_unlock( &p_i->lock ); }
void run_symlink(int argc, char **argv) { EUID_ASSERT(); char *program = strrchr(argv[0], '/'); if (program) program += 1; else program = argv[0]; if (strcmp(program, "firejail") == 0) return; // find the real program // probably the first entry returend by "which -a" is a symlink - use the second entry! char *p = getenv("PATH"); if (!p) { fprintf(stderr, "Error: PATH environment variable not set\n"); exit(1); } char *path = strdup(p); if (!path) errExit("strdup"); char *selfpath = realpath("/proc/self/exe", NULL); if (!selfpath) errExit("realpath"); // look in path for our program char *tok = strtok(path, ":"); int found = 0; while (tok) { char *name; if (asprintf(&name, "%s/%s", tok, program) == -1) errExit("asprintf"); struct stat s; if (stat(name, &s) == 0) { char* rp = realpath(name, NULL); if (!rp) errExit("realpath"); if (strcmp(selfpath, rp) != 0) { program = strdup(name); found = 1; free(rp); break; } free(rp); } free(name); tok = strtok(NULL, ":"); } if (!found) { fprintf(stderr, "Error: cannot find the program in the path\n"); exit(1); } free(selfpath); // start the argv[0] program in a new sandbox char *firejail; if (asprintf(&firejail, "%s/bin/firejail", PREFIX) == -1) errExit("asprintf"); printf("Redirecting symlink to %s\n", program); // run command char *a[3 + argc]; a[0] = firejail; a[1] = program; int i; for (i = 0; i < (argc - 1); i++) a[i + 2] = argv[i + 1]; a[i + 2] = NULL; execvp(a[0], a); perror("execvp"); exit(1); }
static int get_dev_mtd(const char *fdt_flash_path, char **mtd_path) { struct dirent **namelist; char fdt_node_path[PATH_MAX]; int count, i, rc, fd; bool done; if (!fdt_flash_path) return -1; fd = open(fdt_flash_path, O_RDONLY); if (fd == -1) { fprintf(stderr, "Couldn't open '%s' FDT attribute to determine which flash device to use\n", fdt_flash_path); fprintf(stderr, "Is your skiboot new enough to expose the flash through the device tree?\n"); hint_root(); return -1; } rc = read(fd, fdt_node_path, sizeof(fdt_node_path)); close(fd); if (rc == -1) { fprintf(stderr, "Couldn't read flash FDT node from '%s'\n", fdt_flash_path); hint_root(); return -1; } count = scandir(SYSFS_MTD_PATH, &namelist, NULL, alphasort); if (count == -1) { fprintf(stderr, "Couldn't scan '%s' for MTD\n", SYSFS_MTD_PATH); hint_root(); return -1; } rc = 0; done = false; for (i = 0; i < count; i++) { struct dirent *dirent; char *dev_path; char fdt_node_path_tmp[PATH_MAX]; dirent = namelist[i]; /* * The call to asprintf must happen last as when it succeeds it * will allocate dev_path */ if (dirent->d_name[0] == '.' || rc || done || asprintf(&dev_path, "%s/%s/device/of_node", SYSFS_MTD_PATH, dirent->d_name) < 0) { free(namelist[i]); continue; } rc = readlink(dev_path, fdt_node_path_tmp, sizeof(fdt_node_path_tmp) - 1); free(dev_path); if (rc == -1) { /* * This might fail because it could not exist if the system has flash * devices that present as mtd but don't have corresponding FDT * nodes, just continue silently. */ free(namelist[i]); /* Should still try the next dir so reset rc */ rc = 0; continue; } fdt_node_path_tmp[rc] = '\0'; if (strstr(fdt_node_path_tmp, fdt_node_path)) { uint32_t flags, size; /* * size and flags could perhaps have be gotten another way but this * method is super unlikely to fail so it will do. */ /* Check to see if device is writeable */ rc = get_dev_attr(dirent->d_name, "flags", &flags); if (rc) { free(namelist[i]); continue; } /* Get the size of the mtd device while we're at it */ rc = get_dev_attr(dirent->d_name, "size", &size); if (rc) { free(namelist[i]); continue; } rc = asprintf(&dev_path, "/dev/%s", dirent->d_name); if (rc < 0) { free(namelist[i]); continue; } rc = 0; *mtd_path = dev_path; done = true; } free(namelist[i]); } free(namelist); if (!done) { fprintf(stderr, "Couldn't find '%s' corresponding MTD\n", fdt_flash_path); fprintf(stderr, "Is your kernel new enough to expose MTD?\n"); } /* explicit negative value so as to not return a libflash code */ return done ? rc : -1; }
static int recv_krb5_auth (int s, u_char *buf, struct sockaddr *thisaddr, struct sockaddr *thataddr, char **client_username, char **server_username, char **cmd) { uint32_t len; krb5_auth_context auth_context = NULL; krb5_ticket *ticket; krb5_error_code status; krb5_data cksum_data; krb5_principal server; char *str; if (memcmp (buf, "\x00\x00\x00\x13", 4) != 0) return -1; len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | (buf[3]); if (net_read(s, buf, len) != len) syslog_and_die ("reading auth info: %s", strerror(errno)); if (len != sizeof(KRB5_SENDAUTH_VERSION) || memcmp (buf, KRB5_SENDAUTH_VERSION, len) != 0) syslog_and_die ("bad sendauth version: %.8s", buf); status = krb5_sock_to_principal (context, s, "host", KRB5_NT_SRV_HST, &server); if (status) syslog_and_die ("krb5_sock_to_principal: %s", krb5_get_err_text(context, status)); status = krb5_recvauth_match_version(context, &auth_context, &s, match_kcmd_version, NULL, server, KRB5_RECVAUTH_IGNORE_VERSION, NULL, &ticket); krb5_free_principal (context, server); if (status) syslog_and_die ("krb5_recvauth: %s", krb5_get_err_text(context, status)); *server_username = read_str (s, USERNAME_SZ, "remote username"); *cmd = read_str (s, ARG_MAX + 1, "command"); *client_username = read_str (s, ARG_MAX + 1, "local username"); if(protocol_version == 2) { status = krb5_auth_con_getremotesubkey(context, auth_context, &keyblock); if(status != 0 || keyblock == NULL) syslog_and_die("failed to get remote subkey"); } else if(protocol_version == 1) { status = krb5_auth_con_getkey (context, auth_context, &keyblock); if(status != 0 || keyblock == NULL) syslog_and_die("failed to get key"); } if (status != 0 || keyblock == NULL) syslog_and_die ("krb5_auth_con_getkey: %s", krb5_get_err_text(context, status)); status = krb5_crypto_init(context, keyblock, 0, &crypto); if(status) syslog_and_die("krb5_crypto_init: %s", krb5_get_err_text(context, status)); cksum_data.length = asprintf (&str, "%u:%s%s", ntohs(socket_get_port (thisaddr)), *cmd, *server_username); if (str == NULL) syslog_and_die ("asprintf: out of memory"); cksum_data.data = str; status = krb5_verify_authenticator_checksum(context, auth_context, cksum_data.data, cksum_data.length); if (status) syslog_and_die ("krb5_verify_authenticator_checksum: %s", krb5_get_err_text(context, status)); free (cksum_data.data); if (strncmp (*client_username, "-u ", 3) == 0) { do_unique_tkfile = 1; memmove (*client_username, *client_username + 3, strlen(*client_username) - 2); } if (strncmp (*client_username, "-U ", 3) == 0) { char *end, *temp_tkfile; do_unique_tkfile = 1; if (strncmp (*client_username + 3, "FILE:", 5) == 0) { temp_tkfile = tkfile; } else { strlcpy (tkfile, "FILE:", sizeof(tkfile)); temp_tkfile = tkfile + 5; } end = strchr(*client_username + 3,' '); if (end == NULL) syslog_and_die("missing argument after -U"); snprintf(temp_tkfile, sizeof(tkfile) - (temp_tkfile - tkfile), "%.*s", (int)(end - *client_username - 3), *client_username + 3); memmove (*client_username, end + 1, strlen(end+1)+1); } kerberos_status = save_krb5_creds (s, auth_context, ticket->client); if(!krb5_kuserok (context, ticket->client, *server_username)) fatal (s, NULL, "Permission denied."); if (strncmp (*cmd, "-x ", 3) == 0) { do_encrypt = 1; memmove (*cmd, *cmd + 3, strlen(*cmd) - 2); } else { if(do_encrypt) fatal (s, NULL, "Encryption is required."); do_encrypt = 0; } { char *name; if (krb5_unparse_name (context, ticket->client, &name) == 0) { char addr_str[256]; if (inet_ntop (thataddr->sa_family, socket_get_address (thataddr), addr_str, sizeof(addr_str)) == NULL) strlcpy (addr_str, "unknown address", sizeof(addr_str)); syslog(LOG_INFO|LOG_AUTH, "kerberos v5 shell from %s on %s as %s, cmd '%.80s'", name, addr_str, *server_username, *cmd); free (name); } } krb5_auth_con_free(context, auth_context); return 0; }
int main(int argc, char **argv) { struct exec exec; int ch, cnt, efd, fd, sflag; char *binfile, *corefile; char fname[MAXPATHLEN + 1]; sflag = 0; corefile = NULL; while ((ch = getopt(argc, argv, "c:s")) != -1) { switch (ch) { case 'c': corefile = optarg; break; case 's': sflag = 1; break; default: usage(); break; } } argv += optind; argc -= optind; /* XXX we should check that the pid argument is really a number */ switch (argc) { case 1: pid = atoi(argv[0]); asprintf(&binfile, "/proc/%d/file", pid); if (binfile == NULL) errx(1, "allocation failure"); break; case 2: pid = atoi(argv[1]); binfile = argv[0]; break; default: usage(); } efd = open(binfile, O_RDONLY, 0); if (efd < 0) err(1, "%s", binfile); cnt = read(efd, &exec, sizeof(exec)); if (cnt != sizeof(exec)) errx(1, "%s exec header: %s", binfile, cnt > 0 ? strerror(EIO) : strerror(errno)); if (IS_ELF(*(Elf_Ehdr *)&exec)) { close(efd); } else errx(1, "Invalid executable file"); if (corefile == NULL) { (void)snprintf(fname, sizeof(fname), "core.%d", pid); corefile = fname; } fd = open(corefile, O_RDWR|O_CREAT|O_TRUNC, DEFFILEMODE); if (fd < 0) err(1, "%s", corefile); if (sflag) { signal(SIGHUP, killed); signal(SIGINT, killed); signal(SIGTERM, killed); if (kill(pid, SIGSTOP) == -1) err(1, "%d: stop signal", pid); atexit(restart_target); } elf_coredump(fd, pid); (void)close(fd); exit(0); }
static void cm_file_local_dir_readdir(void **state) { int ret; char *subdir_path = NULL; char *file_path = NULL; struct elasto_fh *fh_tmpdir; struct elasto_fh *fh_subdir; struct elasto_fh *fh_file; struct cm_unity_state *cm_us = cm_unity_state_get(); struct elasto_dent finder_dent; /* create a new subdir nested under tmpdir */ ret = asprintf(&subdir_path, "%s/readdir_test", cm_us->local_tmpdir); assert_false(ret < 0); ret = elasto_fopen(&cm_us->local_auth, subdir_path, (ELASTO_FOPEN_DIRECTORY | ELASTO_FOPEN_CREATE | ELASTO_FOPEN_EXCL), NULL, &fh_subdir); assert_int_equal(ret, ELASTO_FOPEN_RET_CREATED); /* open the tmpdir */ ret = elasto_fopen(&cm_us->local_auth, cm_us->local_tmpdir, ELASTO_FOPEN_DIRECTORY, NULL, &fh_tmpdir); assert_int_equal(ret, ELASTO_FOPEN_RET_EXISTED); /* check that the new subdir appears in tmpdir readdir */ memset(&finder_dent, 0, sizeof(finder_dent)); finder_dent.name = "readdir_test"; ret = elasto_freaddir(fh_tmpdir, &finder_dent, cm_file_local_dir_readdir_finder_dent_cb); assert_int_equal(ret, 0); ret = elasto_fclose(fh_tmpdir); assert_true(ret >= 0); assert_true(finder_dent.fstat.field_mask == ELASTO_FSTAT_FIELD_TYPE); assert_true(finder_dent.fstat.ent_type == ELASTO_FSTAT_ENT_DIR); /* create a new file under subdir */ ret = asprintf(&file_path, "%s/readdir_file", subdir_path); assert_true(ret >= 0); ret = elasto_fopen(&cm_us->local_auth, file_path, (ELASTO_FOPEN_CREATE | ELASTO_FOPEN_EXCL), NULL, &fh_file); assert_int_equal(ret, ELASTO_FOPEN_RET_CREATED); /* readdir expect file entry */ memset(&finder_dent, 0, sizeof(finder_dent)); finder_dent.name = "readdir_file"; ret = elasto_freaddir(fh_subdir, &finder_dent, cm_file_local_dir_readdir_finder_dent_cb); assert_int_equal(ret, 0); assert_true(finder_dent.fstat.field_mask == (ELASTO_FSTAT_FIELD_TYPE | ELASTO_FSTAT_FIELD_SIZE | ELASTO_FSTAT_FIELD_BSIZE)); assert_true(finder_dent.fstat.ent_type == ELASTO_FSTAT_ENT_FILE); assert_true(finder_dent.fstat.size == 0); assert_true(finder_dent.fstat.blksize != 0); ret = elasto_funlink_close(fh_file); assert_true(ret >= 0); ret = elasto_funlink_close(fh_subdir); assert_true(ret >= 0); free(subdir_path); free(file_path); }
struct fstab *fs_mgr_read_fstab(const char *fstab_path) { FILE *fstab_file; int cnt, entries; ssize_t len; size_t alloc_len = 0; char *line = NULL; const char *delim = " \t"; char *save_ptr, *p; struct fstab *fstab = NULL; struct fs_mgr_flag_values flag_vals; #define FS_OPTIONS_LEN 1024 char tmp_fs_options[FS_OPTIONS_LEN]; fstab_file = fopen(fstab_path, "r"); if (!fstab_file) { ERROR("Cannot open file %s\n", fstab_path); return 0; } entries = 0; while ((len = getline(&line, &alloc_len, fstab_file)) != -1) { /* if the last character is a newline, shorten the string by 1 byte */ if (line[len - 1] == '\n') { line[len - 1] = '\0'; } /* Skip any leading whitespace */ p = line; while (isspace(*p)) { p++; } /* ignore comments or empty lines */ if (*p == '#' || *p == '\0') continue; entries++; } if (!entries) { ERROR("No entries found in fstab\n"); goto err; } /* Allocate and init the fstab structure */ fstab = calloc(1, sizeof(struct fstab)); fstab->num_entries = entries; fstab->fstab_filename = strdup(fstab_path); fstab->recs = calloc(fstab->num_entries, sizeof(struct fstab_rec)); fseek(fstab_file, 0, SEEK_SET); cnt = 0; while ((len = getline(&line, &alloc_len, fstab_file)) != -1) { /* if the last character is a newline, shorten the string by 1 byte */ if (line[len - 1] == '\n') { line[len - 1] = '\0'; } /* Skip any leading whitespace */ p = line; while (isspace(*p)) { p++; } /* ignore comments or empty lines */ if (*p == '#' || *p == '\0') continue; /* If a non-comment entry is greater than the size we allocated, give an * error and quit. This can happen in the unlikely case the file changes * between the two reads. */ if (cnt >= entries) { ERROR("Tried to process more entries than counted\n"); break; } if (!(p = strtok_r(line, delim, &save_ptr))) { ERROR("Error parsing mount source\n"); goto err; } fstab->recs[cnt].blk_device = strdup(p); if (!(p = strtok_r(NULL, delim, &save_ptr))) { ERROR("Error parsing mount_point\n"); goto err; } fstab->recs[cnt].mount_point = strdup(p); if (!(p = strtok_r(NULL, delim, &save_ptr))) { ERROR("Error parsing fs_type\n"); goto err; } fstab->recs[cnt].fs_type = strdup(p); if (!(p = strtok_r(NULL, delim, &save_ptr))) { ERROR("Error parsing mount_flags\n"); goto err; } tmp_fs_options[0] = '\0'; fstab->recs[cnt].flags = parse_flags(p, mount_flags, NULL, tmp_fs_options, FS_OPTIONS_LEN); /* fs_options are optional */ if (tmp_fs_options[0]) { fstab->recs[cnt].fs_options = strdup(tmp_fs_options); } else { fstab->recs[cnt].fs_options = NULL; } if (!(p = strtok_r(NULL, delim, &save_ptr))) { ERROR("Error parsing fs_mgr_options\n"); goto err; } fstab->recs[cnt].fs_mgr_flags = parse_flags(p, fs_mgr_flags, &flag_vals, NULL, 0); fstab->recs[cnt].key_loc = flag_vals.key_loc; fstab->recs[cnt].verity_loc = flag_vals.verity_loc; fstab->recs[cnt].length = flag_vals.part_length; fstab->recs[cnt].label = flag_vals.label; fstab->recs[cnt].partnum = flag_vals.partnum; fstab->recs[cnt].swap_prio = flag_vals.swap_prio; fstab->recs[cnt].zram_size = flag_vals.zram_size; /* If an A/B partition, modify block device to be the real block device */ if (fstab->recs[cnt].fs_mgr_flags & MF_SLOTSELECT) { char propbuf[PROPERTY_VALUE_MAX]; char *tmp; /* use the kernel parameter if set */ property_get("ro.boot.slot_suffix", propbuf, ""); if (asprintf(&tmp, "%s%s", fstab->recs[cnt].blk_device, propbuf) > 0) { free(fstab->recs[cnt].blk_device); fstab->recs[cnt].blk_device = tmp; } else { ERROR("Error updating block device name\n"); goto err; } } cnt++; } fclose(fstab_file); free(line); return fstab; err: fclose(fstab_file); free(line); if (fstab) fs_mgr_free_fstab(fstab); return NULL; }
static char* check_for_link(char *line, int *skip_chars) { char *start = line; char *p = line; char *url = NULL; char *title = NULL; char *result = NULL; int found = 0; if (*p == '[') /* [ link [title] ] */ { /* XXX TODO XXX * Allow links like [the Main page] ( covert to the_main_page ) */ url = start+1; *p = '\0'; p++; while ( *p != ']' && *p != '\0' && !isspace(*p) ) p++; if (isspace(*p)) { *p = '\0'; title = ++p; while ( *p != ']' && *p != '\0' ) p++; } *p = '\0'; p++; } else if (!strncasecmp(p, "http://", 7) || !strncasecmp(p, "mailto://", 9) || !strncasecmp(p, "file://", 7)) { while ( *p != '\0' && !isspace(*p) ) p++; found = 1; } else if (isupper(*p)) /* Camel-case */ { int num_upper_char = 1; p++; while ( *p != '\0' && isalnum(*p) ) { if (isupper(*p)) { found = 1; num_upper_char++; } p++; } if (num_upper_char == (p-start)) /* Dont make ALLCAPS links */ return NULL; } if (found) /* cant really set http/camel links in place */ { url = malloc(sizeof(char) * ((p - start) + 2) ); memset(url, 0, sizeof(char) * ((p - start) + 2)); strncpy(url, start, p - start); *start = '\0'; } if (url != NULL) { int len = strlen(url); *skip_chars = p - start; /* is it an image ? */ if (!strncmp(url+len-4, ".gif", 4) || !strncmp(url+len-4, ".png", 4) || !strncmp(url+len-4, ".jpg", 4) || !strncmp(url+len-5, ".jpeg", 5)) { if (title) asprintf(&result, "<a href='%s'><img src='%s' border='0'></a>", title, url); else asprintf(&result, "<img src='%s' border='0'>", url); } else { char *extra_attr = ""; if (!strncasecmp(url, "http://", 7)) extra_attr = " title='WWW link' "; if (title) asprintf(&result,"<a %s href='%s'>%s</a>", extra_attr, url, title); else asprintf(&result, "<a %s href='%s'>%s</a>", extra_attr, url, url); } return result; } return NULL; }
/* * Back-end function to actually send the email */ static int send_email(char *msg) { int i, err = PMIX_SUCCESS; char *str = NULL; char *errmsg = NULL; struct sigaction sig, oldsig; bool set_oldsig = false; smtp_session_t session = NULL; smtp_message_t message = NULL; message_status_t ms; pmix_plog_smtp_component_t *c = &mca_plog_smtp_component; if (NULL == c->to_argv) { c->to_argv = pmix_argv_split(c->to, ','); if (NULL == c->to_argv || NULL == c->to_argv[0]) { return PMIX_ERR_OUT_OF_RESOURCE; } } ms.sent_flag = SENT_NONE; ms.prev_string = NULL; ms.msg = msg; /* Temporarily disable SIGPIPE so that if remote servers timeout or hang up on us, it doesn't kill this application. We'll restore the original SIGPIPE handler when we're done. */ sig.sa_handler = SIG_IGN; sigemptyset(&sig.sa_mask); sig.sa_flags = 0; sigaction(SIGPIPE, &sig, &oldsig); set_oldsig = true; /* Try to get a libesmtp session. If so, assume that libesmtp is happy and proceeed */ session = smtp_create_session(); if (NULL == session) { err = PMIX_ERR_NOT_SUPPORTED; errmsg = "stmp_create_session"; goto error; } /* Create the message */ message = smtp_add_message(session); if (NULL == message) { err = PMIX_ERROR; errmsg = "stmp_add_message"; goto error; } /* Set the SMTP server (yes, it's a weird return status!) */ asprintf(&str, "%s:%d", c->server, c->port); if (0 == smtp_set_server(session, str)) { err = PMIX_ERROR; errmsg = "stmp_set_server"; goto error; } free(str); str = NULL; /* Add the sender */ if (0 == smtp_set_reverse_path(message, c->from_addr)) { err = PMIX_ERROR; errmsg = "stmp_set_reverse_path"; goto error; } /* Set the subject and some headers */ asprintf(&str, "PMIx SMTP Plog v%d.%d.%d", c->super.base.pmix_mca_component_major_version, c->super.base.pmix_mca_component_minor_version, c->super.base.pmix_mca_component_release_version); if (0 == smtp_set_header(message, "Subject", c->subject) || 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1) || 0 == smtp_set_header(message, "To", NULL, NULL) || 0 == smtp_set_header(message, "From", (NULL != c->from_name ? c->from_name : c->from_addr), c->from_addr) || 0 == smtp_set_header(message, "X-Mailer", str) || 0 == smtp_set_header_option(message, "Subject", Hdr_OVERRIDE, 1)) { err = PMIX_ERROR; errmsg = "smtp_set_header"; goto error; } free(str); str = NULL; /* Add the recipients */ for (i = 0; NULL != c->to_argv[i]; ++i) { if (NULL == smtp_add_recipient(message, c->to_argv[i])) { err = PMIX_ERR_OUT_OF_RESOURCE; errmsg = "stmp_add_recipient"; goto error; } } /* Set the callback to get the message */ if (0 == smtp_set_messagecb(message, message_cb, &ms)) { err = PMIX_ERROR; errmsg = "smtp_set_messagecb"; goto error; } /* Send it! */ if (0 == smtp_start_session(session)) { err = PMIX_ERROR; errmsg = "smtp_start_session"; goto error; } /* Fall through */ error: if (NULL != str) { free(str); } if (NULL != session) { smtp_destroy_session(session); } /* Restore the SIGPIPE handler */ if (set_oldsig) { sigaction(SIGPIPE, &oldsig, NULL); } if (PMIX_SUCCESS != err) { int e; char em[256]; e = smtp_errno(); smtp_strerror(e, em, sizeof(em)); pmix_show_help("help-pmix-plog-smtp.txt", "send_email failed", true, "libesmtp library call failed", errmsg, em, e, msg); } return err; }
void add_mount_from_spec(char *spec) { int rc; size_t c; _free_ char **opts = NULL; _free_ char *tmp = strdup(spec); if (tmp == NULL) fail_printf("OOM"); c = split_str(tmp, &opts, ","); if (c == 0) fail_printf("Invalid mount spec '%s'", spec); if (strncmp(opts[0], "bind", 4) == 0) { _free_ char *src = NULL; _free_ char *dst = NULL; if (c < 3) fail_printf("Invalid mount spec '%s'", spec); src = realpath(opts[1], NULL); if (src == NULL) sysf_printf("realpath()"); dst = realpath(opts[2], NULL); if (dst == NULL) sysf_printf("realpath()"); add_mount(src, dst, NULL, MS_BIND, NULL); if (strncmp(opts[0], "bind-ro", 8) == 0) add_mount(src, dst, NULL, MS_REMOUNT | MS_BIND | MS_RDONLY, NULL); } else if (strncmp(opts[0], "aufs", 5) == 0) { _free_ char *dst = NULL; _free_ char *overlay = NULL; _free_ char *aufs_opts = NULL; if (c < 3) fail_printf("Invalid mount spec '%s'", spec); overlay = realpath(opts[1], NULL); if (overlay == NULL) sysf_printf("realpath()"); dst = realpath(opts[2], NULL); if (dst == NULL) sysf_printf("realpath()"); rc = asprintf(&aufs_opts, "br:%s=rw:%s=ro", overlay, dst); if (rc < 0) fail_printf("OOM"); add_mount(NULL, dst, "aufs", 0, aufs_opts); } else if (strncmp(opts[0], "overlay", 8) == 0) { _free_ char *dst = NULL; _free_ char *overlay = NULL; _free_ char *workdir = NULL; _free_ char *overlayfs_opts = NULL; if (c < 4) fail_printf("Invalid mount spec '%s'", spec); overlay = realpath(opts[1], NULL); if (overlay == NULL) sysf_printf("realpath()"); dst = realpath(opts[2], NULL); if (dst == NULL) sysf_printf("realpath()"); workdir = realpath(opts[3], NULL); if (workdir == NULL) sysf_printf("realpath()"); #ifdef HAVE_AUFS rc = asprintf(&overlayfs_opts, "br:%s=rw:%s=ro", overlay, dst); if (rc < 0) fail_printf("OOM"); add_mount(NULL, dst, "aufs", 0, overlayfs_opts); #elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 18, 0) rc = asprintf(&overlayfs_opts, "upperdir=%s,lowerdir=%s,workdir=%s", overlay, dst, workdir); if (rc < 0) fail_printf("OOM"); add_mount(NULL, dst, "overlay", 0, overlayfs_opts); #else fail_printf("The 'overlay' mount type is not supported"); #endif } else if (strncmp(opts[0], "tmp", 4) == 0) { _free_ char *dst = NULL; if (c < 2) fail_printf("Invalid mount spec '%s'", spec); dst = realpath(opts[1], NULL); if (dst == NULL) sysf_printf("realpath()"); add_mount("tmpfs", dst, "tmpfs", 0, NULL); } else { fail_printf("Invalid mount type '%s'", opts[0]); } }
int DoGetString(__GLXclientState * cl, GLbyte * pc, GLboolean need_swap) { ClientPtr client; __GLXcontext *cx; GLenum name; const char *string; __GLX_DECLARE_SWAP_VARIABLES; int error; char *buf = NULL, *buf1 = NULL; GLint length = 0; /* If the client has the opposite byte order, swap the contextTag and * the name. */ if (need_swap) { __GLX_SWAP_INT(pc + 4); __GLX_SWAP_INT(pc + __GLX_SINGLE_HDR_SIZE); } cx = __glXForceCurrent(cl, __GLX_GET_SINGLE_CONTEXT_TAG(pc), &error); if (!cx) { return error; } pc += __GLX_SINGLE_HDR_SIZE; name = *(GLenum *) (pc + 0); string = (const char *) CALL_GetString(GET_DISPATCH(), (name)); client = cl->client; if (string == NULL) string = ""; /* ** Restrict extensions to those that are supported by both the ** implementation and the connection. That is, return the ** intersection of client, server, and core extension strings. */ if (name == GL_EXTENSIONS) { buf1 = __glXcombine_strings(string, cl->GLClientextensions); buf = __glXcombine_strings(buf1, cx->pGlxScreen->GLextensions); free(buf1); string = buf; } else if (name == GL_VERSION) { if (atof(string) > atof(GLServerVersion)) { if (asprintf(&buf, "%s (%s)", GLServerVersion, string) == -1) { string = GLServerVersion; } else { string = buf; } } } if (string) { length = strlen((const char *) string) + 1; } __GLX_BEGIN_REPLY(length); __GLX_PUT_SIZE(length); if (need_swap) { __GLX_SWAP_REPLY_SIZE(); __GLX_SWAP_REPLY_HEADER(); } __GLX_SEND_HEADER(); WriteToClient(client, length, (char *) string); free(buf); return Success; }
/* * Parse a RTM_NEWNDUSEROPT message. */ bool NetlinkEvent::parseNdUserOptMessage(const struct nlmsghdr *nh) { struct nduseroptmsg *msg = (struct nduseroptmsg *) NLMSG_DATA(nh); if (!checkRtNetlinkLength(nh, sizeof(*msg))) return false; // Check the length is valid. int len = NLMSG_PAYLOAD(nh, sizeof(*msg)); if (msg->nduseropt_opts_len > len) { SLOGE("RTM_NEWNDUSEROPT invalid length %d > %d\n", msg->nduseropt_opts_len, len); return false; } len = msg->nduseropt_opts_len; // Check address family and packet type. if (msg->nduseropt_family != AF_INET6) { SLOGE("RTM_NEWNDUSEROPT message for unknown family %d\n", msg->nduseropt_family); return false; } if (msg->nduseropt_icmp_type != ND_ROUTER_ADVERT || msg->nduseropt_icmp_code != 0) { SLOGE("RTM_NEWNDUSEROPT message for unknown ICMPv6 type/code %d/%d\n", msg->nduseropt_icmp_type, msg->nduseropt_icmp_code); return false; } // Find the interface name. char ifname[IFNAMSIZ]; if (!if_indextoname(msg->nduseropt_ifindex, ifname)) { SLOGE("RTM_NEWNDUSEROPT on unknown ifindex %d\n", msg->nduseropt_ifindex); return false; } // The kernel sends a separate netlink message for each ND option in the RA. // So only parse the first ND option in the message. struct nd_opt_hdr *opthdr = (struct nd_opt_hdr *) (msg + 1); // The length is in multiples of 8 octets. uint16_t optlen = opthdr->nd_opt_len; if (optlen * 8 > len) { SLOGE("Invalid option length %d > %d for ND option %d\n", optlen * 8, len, opthdr->nd_opt_type); return false; } if (opthdr->nd_opt_type == ND_OPT_RDNSS) { // DNS Servers (RFC 6106). // Each address takes up 2*8 octets, and the header takes up 8 octets. // So for a valid option with one or more addresses, optlen must be // odd and greater than 1. if ((optlen < 3) || !(optlen & 0x1)) { SLOGE("Invalid optlen %d for RDNSS option\n", optlen); return false; } int numaddrs = (optlen - 1) / 2; // Find the lifetime. struct nd_opt_rdnss *rndss_opt = (struct nd_opt_rdnss *) opthdr; uint32_t lifetime = ntohl(rndss_opt->nd_opt_rdnss_lifetime); // Construct "SERVERS=<comma-separated string of DNS addresses>". // Reserve (INET6_ADDRSTRLEN + 1) chars for each address: all but the // the last address are followed by ','; the last is followed by '\0'. static const char kServerTag[] = "SERVERS="; static const int kTagLength = sizeof(kServerTag) - 1; int bufsize = kTagLength + numaddrs * (INET6_ADDRSTRLEN + 1); char *buf = (char *) malloc(bufsize); if (!buf) { SLOGE("RDNSS option: out of memory\n"); return false; } strcpy(buf, kServerTag); int pos = kTagLength; struct in6_addr *addrs = (struct in6_addr *) (rndss_opt + 1); for (int i = 0; i < numaddrs; i++) { if (i > 0) { buf[pos++] = ','; } inet_ntop(AF_INET6, addrs + i, buf + pos, bufsize - pos); pos += strlen(buf + pos); } buf[pos] = '\0'; mAction = NlActionRdnss; mSubsystem = strdup("net"); asprintf(&mParams[0], "INTERFACE=%s", ifname); asprintf(&mParams[1], "LIFETIME=%u", lifetime); mParams[2] = buf; } else { SLOGD("Unknown ND option type %d\n", opthdr->nd_opt_type); return false; } return true; }
/* * Parse a RTM_NEWROUTE or RTM_DELROUTE message. */ bool NetlinkEvent::parseRtMessage(const struct nlmsghdr *nh) { uint8_t type = nh->nlmsg_type; const char *msgname = rtMessageName(type); // Sanity check. if (type != RTM_NEWROUTE && type != RTM_DELROUTE) { SLOGE("%s: incorrect message type %d (%s)\n", __func__, type, msgname); return false; } struct rtmsg *rtm = (struct rtmsg *) NLMSG_DATA(nh); if (!checkRtNetlinkLength(nh, sizeof(*rtm))) return false; if (// Ignore static routes we've set up ourselves. (rtm->rtm_protocol != RTPROT_KERNEL && rtm->rtm_protocol != RTPROT_RA) || // We're only interested in global unicast routes. (rtm->rtm_scope != RT_SCOPE_UNIVERSE) || (rtm->rtm_type != RTN_UNICAST) || // We don't support source routing. (rtm->rtm_src_len != 0) || // Cloned routes aren't real routes. (rtm->rtm_flags & RTM_F_CLONED)) { return false; } int family = rtm->rtm_family; int prefixLength = rtm->rtm_dst_len; // Currently we only support: destination, (one) next hop, ifindex. char dst[INET6_ADDRSTRLEN] = ""; char gw[INET6_ADDRSTRLEN] = ""; char dev[IFNAMSIZ] = ""; size_t len = RTM_PAYLOAD(nh); struct rtattr *rta; for (rta = RTM_RTA(rtm); RTA_OK(rta, len); rta = RTA_NEXT(rta, len)) { switch (rta->rta_type) { case RTA_DST: if (maybeLogDuplicateAttribute(*dst, "RTA_DST", msgname)) continue; if (!inet_ntop(family, RTA_DATA(rta), dst, sizeof(dst))) return false; continue; case RTA_GATEWAY: if (maybeLogDuplicateAttribute(*gw, "RTA_GATEWAY", msgname)) continue; if (!inet_ntop(family, RTA_DATA(rta), gw, sizeof(gw))) return false; continue; case RTA_OIF: if (maybeLogDuplicateAttribute(*dev, "RTA_OIF", msgname)) continue; if (!if_indextoname(* (int *) RTA_DATA(rta), dev)) return false; default: continue; } } // If there's no RTA_DST attribute, then: // - If the prefix length is zero, it's the default route. // - If the prefix length is nonzero, there's something we don't understand. // Ignore the event. if (!*dst && !prefixLength) { if (family == AF_INET) { strncpy(dst, "0.0.0.0", sizeof(dst)); } else if (family == AF_INET6) { strncpy(dst, "::", sizeof(dst)); } } // A useful route must have a destination and at least either a gateway or // an interface. if (!*dst || (!*gw && !*dev)) return false; // Fill in netlink event information. mAction = (type == RTM_NEWROUTE) ? NlActionRouteUpdated : NlActionRouteRemoved; mSubsystem = strdup("net"); asprintf(&mParams[0], "ROUTE=%s/%d", dst, prefixLength); asprintf(&mParams[1], "GATEWAY=%s", (*gw) ? gw : ""); asprintf(&mParams[2], "INTERFACE=%s", (*dev) ? dev : ""); return true; }
char *system_getuser() { char *ret = NULL; if(asprintf(&ret, "%d", getuid()) == -1) errx(-1, "Unable to allocate memory!"); return ret; }
int main(int argc, char **argv) { int rc; pid_t pid; int i; options_t *opts = get_options(argc, argv); char *fullname = NULL; asprintf(&fullname, "%s:", opts->name ? opts->name : argv[0]); argv[0] = fullname; if(opts->detached) { pid = fork(); if(pid == 0) { rc = setsid(); if(rc == -1) { perror("setsid"); return EXIT_FAILURE; } } else if(pid == -1) { perror("fork"); return EXIT_FAILURE; } else { return EXIT_SUCCESS; } } if(opts->group) { struct group *grp = getgrnam(opts->group); if(grp == NULL) { fprintf(stderr, "getgrnam(%s): Couldn't find group\n", opts->group); return EXIT_FAILURE; } rc = setgid(grp->gr_gid); if(rc != 0) { fprintf(stderr, "setgid(%d): Couldn't set the group ID\n", grp->gr_gid); return EXIT_FAILURE; } rc = initgroups(opts->group, grp->gr_gid); if(rc == -1) { fprintf(stderr, "initgroups(%s, %d): You must run the program as root\n", opts->group, grp->gr_gid); return EXIT_FAILURE; } } if(opts->user) { struct passwd *pwd = getpwnam(opts->user); if(pwd == NULL) { fprintf(stderr, "getpwnam(%s): Couldn't find user\n", opts->user); return EXIT_FAILURE; } rc = setuid(pwd->pw_uid); if(rc != 0) { fprintf(stderr, "setuid(%d): Couldn't set the user ID\n", pwd->pw_uid); return EXIT_FAILURE; } } char **versions; numver = get_versions(opts->dir, &versions); pids = (pid_t*)calloc(numver, sizeof(pid_t)); for(i = 0; i < numver; i++) { pid = fork(); switch(pid) { case -1: perror("fork"); kill_processes(SIGTERM); return EXIT_FAILURE; case 0: rc = start_process(opts, versions[i]); if(rc == -1) { /* This is in a child process that might have a "smaller" version of the * list of PIDs. Some processes might then not be killed here. * This is probably good enough corresponding the scope of this program. */ kill_processes(SIGTERM); return EXIT_FAILURE; } default: pids[i] = pid; } } init_sighandler(); asprintf(&argv[1], "%i/%i remaining processes", numver, numver); argv[2] = NULL; int status; while((pid = wait(&status)) != -1 || errno == EINTR) { if(WIFEXITED(status) || WIFSIGNALED(status)) { int nrem = 0; for(i = 0; i < numver; i++) { if(pids[i] == pid) { pids[i] = 0; } if(pids[i] != 0) { nrem++; } } asprintf(&argv[1], "%i/%i remaining processes", nrem, numver); if(nrem == 0) { break; } } } free(fullname); free_options(opts); return EXIT_SUCCESS; }
static int rte_init(void) { int ret; char *error = NULL; char *envar, *ev1, *ev2; uint64_t unique_key[2]; char *string_key; char *rmluri; opal_value_t *kv; char *val; int u32, *u32ptr; uint16_t u16, *u16ptr; char **peers=NULL, *mycpuset, **cpusets=NULL; opal_process_name_t name; size_t i; /* run the prolog */ if (ORTE_SUCCESS != (ret = orte_ess_base_std_prolog())) { error = "orte_ess_base_std_prolog"; goto error; } /* get an async event base - we use the opal_async one so * we don't startup extra threads if not needed */ orte_event_base = opal_progress_thread_init(NULL); progress_thread_running = true; /* open and setup pmix */ if (OPAL_SUCCESS != (ret = mca_base_framework_open(&opal_pmix_base_framework, 0))) { ORTE_ERROR_LOG(ret); /* we cannot run */ error = "pmix init"; goto error; } if (OPAL_SUCCESS != (ret = opal_pmix_base_select())) { /* we cannot run */ error = "pmix init"; goto error; } /* set the event base */ opal_pmix_base_set_evbase(orte_event_base); /* initialize the selected module */ if (!opal_pmix.initialized() && (OPAL_SUCCESS != (ret = opal_pmix.init()))) { /* we cannot run */ error = "pmix init"; goto error; } u32ptr = &u32; u16ptr = &u16; /**** THE FOLLOWING ARE REQUIRED VALUES ***/ /* pmix.init set our process name down in the OPAL layer, * so carry it forward here */ ORTE_PROC_MY_NAME->jobid = OPAL_PROC_MY_NAME.jobid; ORTE_PROC_MY_NAME->vpid = OPAL_PROC_MY_NAME.vpid; /* get our local rank from PMI */ OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_RANK, ORTE_PROC_MY_NAME, &u16ptr, OPAL_UINT16); if (OPAL_SUCCESS != ret) { error = "getting local rank"; goto error; } orte_process_info.my_local_rank = u16; /* get our node rank from PMI */ OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_NODE_RANK, ORTE_PROC_MY_NAME, &u16ptr, OPAL_UINT16); if (OPAL_SUCCESS != ret) { error = "getting node rank"; goto error; } orte_process_info.my_node_rank = u16; /* get universe size */ OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_UNIV_SIZE, ORTE_PROC_MY_NAME, &u32ptr, OPAL_UINT32); if (OPAL_SUCCESS != ret) { error = "getting univ size"; goto error; } orte_process_info.num_procs = u32; /* push into the environ for pickup in MPI layer for * MPI-3 required info key */ if (NULL == getenv(OPAL_MCA_PREFIX"orte_ess_num_procs")) { asprintf(&ev1, OPAL_MCA_PREFIX"orte_ess_num_procs=%d", orte_process_info.num_procs); putenv(ev1); added_num_procs = true; } if (NULL == getenv("OMPI_APP_CTX_NUM_PROCS")) { asprintf(&ev2, "OMPI_APP_CTX_NUM_PROCS=%d", orte_process_info.num_procs); putenv(ev2); added_app_ctx = true; } /* get our app number from PMI - ok if not found */ OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_APPNUM, ORTE_PROC_MY_NAME, &u32ptr, OPAL_UINT32); if (OPAL_SUCCESS == ret) { orte_process_info.app_num = u32; } else { orte_process_info.app_num = 0; } /* get the number of local peers - required for wireup of * shared memory BTL */ OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_SIZE, ORTE_PROC_MY_NAME, &u32ptr, OPAL_UINT32); if (OPAL_SUCCESS == ret) { orte_process_info.num_local_peers = u32 - 1; // want number besides ourselves } else { orte_process_info.num_local_peers = 0; } /* setup transport keys in case the MPI layer needs them - * we can use the jobfam and stepid as unique keys * because they are unique values assigned by the RM */ if (NULL == getenv(OPAL_MCA_PREFIX"orte_precondition_transports")) { unique_key[0] = ORTE_JOB_FAMILY(ORTE_PROC_MY_NAME->jobid); unique_key[1] = ORTE_LOCAL_JOBID(ORTE_PROC_MY_NAME->jobid); if (NULL == (string_key = orte_pre_condition_transports_print(unique_key))) { ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE); return ORTE_ERR_OUT_OF_RESOURCE; } asprintf(&envar, OPAL_MCA_PREFIX"orte_precondition_transports=%s", string_key); putenv(envar); added_transport_keys = true; /* cannot free the envar as that messes up our environ */ free(string_key); } /* retrieve our topology */ val = NULL; OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_LOCAL_TOPO, ORTE_PROC_MY_NAME, &val, OPAL_STRING); if (OPAL_SUCCESS == ret && NULL != val) { /* load the topology */ if (0 != hwloc_topology_init(&opal_hwloc_topology)) { ret = OPAL_ERROR; free(val); error = "setting topology"; goto error; } if (0 != hwloc_topology_set_xmlbuffer(opal_hwloc_topology, val, strlen(val))) { ret = OPAL_ERROR; free(val); hwloc_topology_destroy(opal_hwloc_topology); error = "setting topology"; goto error; } /* since we are loading this from an external source, we have to * explicitly set a flag so hwloc sets things up correctly */ if (0 != hwloc_topology_set_flags(opal_hwloc_topology, (HWLOC_TOPOLOGY_FLAG_IS_THISSYSTEM | HWLOC_TOPOLOGY_FLAG_WHOLE_SYSTEM | HWLOC_TOPOLOGY_FLAG_IO_DEVICES))) { ret = OPAL_ERROR; hwloc_topology_destroy(opal_hwloc_topology); free(val); error = "setting topology"; goto error; } /* now load the topology */ if (0 != hwloc_topology_load(opal_hwloc_topology)) { ret = OPAL_ERROR; hwloc_topology_destroy(opal_hwloc_topology); free(val); error = "setting topology"; goto error; } free(val); /* filter the cpus thru any default cpu set */ if (OPAL_SUCCESS != (ret = opal_hwloc_base_filter_cpus(opal_hwloc_topology))) { error = "filtering topology"; goto error; } } else { /* it wasn't passed down to us, so go get it */ if (OPAL_SUCCESS != (ret = opal_hwloc_base_get_topology())) { error = "topology discovery"; goto error; } /* push it into the PMIx database in case someone * tries to retrieve it so we avoid an attempt to * get it again */ kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_LOCAL_TOPO); kv->type = OPAL_STRING; if (0 != (ret = hwloc_topology_export_xmlbuffer(opal_hwloc_topology, &kv->data.string, &u32))) { error = "topology export"; goto error; } if (OPAL_SUCCESS != (ret = opal_pmix.store_local(ORTE_PROC_MY_NAME, kv))) { error = "topology store"; goto error; } OBJ_RELEASE(kv); } /* get our local peers */ if (0 < orte_process_info.num_local_peers) { /* if my local rank if too high, then that's an error */ if (orte_process_info.num_local_peers < orte_process_info.my_local_rank) { ret = ORTE_ERR_BAD_PARAM; error = "num local peers"; goto error; } /* retrieve the local peers */ OPAL_MODEX_RECV_VALUE(ret, OPAL_PMIX_LOCAL_PEERS, ORTE_PROC_MY_NAME, &val, OPAL_STRING); if (OPAL_SUCCESS == ret && NULL != val) { peers = opal_argv_split(val, ','); free(val); /* and their cpusets, if available */ OPAL_MODEX_RECV_VALUE_OPTIONAL(ret, OPAL_PMIX_LOCAL_CPUSETS, ORTE_PROC_MY_NAME, &val, OPAL_STRING); if (OPAL_SUCCESS == ret && NULL != val) { cpusets = opal_argv_split(val, ':'); free(val); } else { cpusets = NULL; } } else { peers = NULL; cpusets = NULL; } } else { peers = NULL; cpusets = NULL; } /* set the locality */ if (NULL != peers) { /* indentify our cpuset */ if (NULL != cpusets) { mycpuset = cpusets[orte_process_info.my_local_rank]; } else { mycpuset = NULL; } name.jobid = ORTE_PROC_MY_NAME->jobid; for (i=0; NULL != peers[i]; i++) { kv = OBJ_NEW(opal_value_t); kv->key = strdup(OPAL_PMIX_LOCALITY); kv->type = OPAL_UINT16; name.vpid = strtoul(peers[i], NULL, 10); if (name.vpid == ORTE_PROC_MY_NAME->vpid) { /* we are fully local to ourselves */ u16 = OPAL_PROC_ALL_LOCAL; } else if (NULL == mycpuset || NULL == cpusets[i] || 0 == strcmp(cpusets[i], "UNBOUND")) { /* all we can say is that it shares our node */ u16 = OPAL_PROC_ON_CLUSTER | OPAL_PROC_ON_CU | OPAL_PROC_ON_NODE; } else { /* we have it, so compute the locality */ u16 = opal_hwloc_base_get_relative_locality(opal_hwloc_topology, mycpuset, cpusets[i]); } OPAL_OUTPUT_VERBOSE((1, orte_ess_base_framework.framework_output, "%s ess:pmi:locality: proc %s locality %x", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), ORTE_NAME_PRINT(&name), u16)); kv->data.uint16 = u16; ret = opal_pmix.store_local(&name, kv); if (OPAL_SUCCESS != ret) { error = "local store of locality"; opal_argv_free(peers); opal_argv_free(cpusets); goto error; } OBJ_RELEASE(kv); } opal_argv_free(peers); opal_argv_free(cpusets); } /* now that we have all required info, complete the setup */ if (ORTE_SUCCESS != (ret = orte_ess_base_app_setup(false))) { ORTE_ERROR_LOG(ret); error = "orte_ess_base_app_setup"; goto error; } /* setup process binding */ if (ORTE_SUCCESS != (ret = orte_ess_base_proc_binding())) { error = "proc_binding"; goto error; } /* this needs to be set to enable debugger use when direct launched */ if (NULL == orte_process_info.my_daemon_uri) { orte_standalone_operation = true; } /* set max procs */ if (orte_process_info.max_procs < orte_process_info.num_procs) { orte_process_info.max_procs = orte_process_info.num_procs; } /*** PUSH DATA FOR OTHERS TO FIND ***/ /* push our RML URI in case others need to talk directly to us */ rmluri = orte_rml.get_contact_info(); /* push it out for others to use */ OPAL_MODEX_SEND_VALUE(ret, OPAL_PMIX_GLOBAL, OPAL_PMIX_PROC_URI, rmluri, OPAL_STRING); if (ORTE_SUCCESS != ret) { error = "pmix put uri"; goto error; } free(rmluri); /* push our hostname so others can find us, if they need to */ OPAL_MODEX_SEND_VALUE(ret, OPAL_PMIX_GLOBAL, OPAL_PMIX_HOSTNAME, orte_process_info.nodename, OPAL_STRING); if (ORTE_SUCCESS != ret) { error = "db store hostname"; goto error; } /* if we are an ORTE app - and not an MPI app - then * we need to exchange our connection info here. * MPI_Init has its own modex, so we don't need to do * two of them. However, if we don't do a modex at all, * then processes have no way to communicate * * NOTE: only do this when the process originally launches. * Cannot do this on a restart as the rest of the processes * in the job won't be executing this step, so we would hang */ if (ORTE_PROC_IS_NON_MPI && !orte_do_not_barrier) { opal_pmix.fence(NULL, 0); } return ORTE_SUCCESS; error: if (!progress_thread_running) { /* can't send the help message, so ensure it * comes out locally */ orte_show_help_finalize(); } if (ORTE_ERR_SILENT != ret && !orte_report_silent_errors) { orte_show_help("help-orte-runtime.txt", "orte_init:startup:internal-failure", true, error, ORTE_ERROR_NAME(ret), ret); } return ret; }
/* * This function is responsible for: * - Constructing the remote absolute path for the specified file/dir * - Verify the existence of the file/dir * - Determine if the specified file/dir is in fact a file or dir or unknown if not found. */ static void filem_base_process_get_remote_path_cmd(orte_process_name_t* sender, opal_buffer_t* buffer) { opal_buffer_t answer; orte_std_cntr_t count; char *filename = NULL; char *tmp_name = NULL; char cwd[OMPI_PATH_MAX]; int file_type = ORTE_FILEM_TYPE_UNKNOWN; struct stat file_status; int rc; /* * Unpack the data */ OBJ_CONSTRUCT(&answer, opal_buffer_t); count = 1; if (ORTE_SUCCESS != (rc = opal_dss.unpack(buffer, &filename, &count, OPAL_STRING))) { ORTE_ERROR_LOG(rc); goto CLEANUP; } /* * Determine the absolute path of the file */ if(filename[0] != '/') { /* if it is not an absolute path already */ getcwd(cwd, sizeof(cwd)); asprintf(&tmp_name, "%s/%s", cwd, filename); } else { tmp_name = strdup(filename); } opal_output_verbose(10, orte_filem_base_output, "filem:base: process_get_remote_path_cmd: %s -> %s: Filename Requested (%s) translated to (%s)", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), ORTE_NAME_PRINT(sender), filename, tmp_name); /* * Determine if the file/dir exists at that absolute path * Determine if the file/dir is a file or a directory */ if(0 != (rc = stat(tmp_name, &file_status) ) ){ file_type = ORTE_FILEM_TYPE_UNKNOWN; } else { /* Is it a directory? */ if(S_ISDIR(file_status.st_mode)) { file_type = ORTE_FILEM_TYPE_DIR; } else if(S_ISREG(file_status.st_mode)) { file_type = ORTE_FILEM_TYPE_FILE; } } /* * Pack up the response * Send back the reference type * - ORTE_FILEM_TYPE_FILE = File * - ORTE_FILEM_TYPE_DIR = Directory * - ORTE_FILEM_TYPE_UNKNOWN = Could not be determined, or does not exist */ if (ORTE_SUCCESS != (rc = opal_dss.pack(&answer, &tmp_name, 1, OPAL_STRING))) { ORTE_ERROR_LOG(rc); ORTE_UPDATE_EXIT_STATUS(1); orte_trigger_event(&orte_exit); goto CLEANUP; } if (ORTE_SUCCESS != (rc = opal_dss.pack(&answer, &file_type, 1, OPAL_INT))) { ORTE_ERROR_LOG(rc); ORTE_UPDATE_EXIT_STATUS(1); orte_trigger_event(&orte_exit); goto CLEANUP; } if (0 > (rc = orte_rml.send_buffer(sender, &answer, ORTE_RML_TAG_FILEM_BASE_RESP, 0))) { ORTE_ERROR_LOG(rc); } CLEANUP: if( NULL != filename) { free(filename); filename = NULL; } if( NULL != tmp_name) { free(tmp_name); tmp_name = NULL; } OBJ_DESTRUCT(&answer); }
static int OutputNew( sout_stream_t *p_stream, const char *psz_muxer, const char *psz_prefix, const char *psz_extension ) { sout_stream_sys_t *p_sys = p_stream->p_sys; char *psz_file = NULL, *psz_tmp = NULL; char *psz_output = NULL; int i_count; if( asprintf( &psz_tmp, "%s%s%s", psz_prefix, psz_extension ? "." : "", psz_extension ? psz_extension : "" ) < 0 ) { goto error; } psz_file = config_StringEscape( psz_tmp ); if( !psz_file ) { free( psz_tmp ); goto error; } free( psz_tmp ); if( asprintf( &psz_output, "std{access=file,mux='%s',dst='%s',no-append," "no-format}", psz_muxer, psz_file ) < 0 ) { psz_output = NULL; goto error; } /* Create the output */ msg_Dbg( p_stream, "Using record output `%s'", psz_output ); p_sys->p_out = sout_StreamChainNew( p_stream->p_sout, psz_output, NULL, NULL ); if( !p_sys->p_out ) goto error; /* Add es */ i_count = 0; for( int i = 0; i < p_sys->i_id; i++ ) { sout_stream_id_t *id = p_sys->id[i]; id->id = sout_StreamIdAdd( p_sys->p_out, &id->fmt ); if( id->id ) i_count++; } if( psz_file && psz_extension ) var_SetString( p_stream->p_libvlc, "record-file", psz_file ); free( psz_file ); free( psz_output ); return i_count; error: free( psz_file ); free( psz_output ); return -1; }
/* rotates the main log file */ int rotate_log_file(time_t rotation_time) { char *temp_buffer = NULL; char method_string[16] = ""; char *log_archive = NULL; struct tm *t, tm_s; int rename_result = 0; int stat_result = -1; struct stat log_file_stat; if (log_rotation_method == LOG_ROTATION_NONE) { return OK; } else if (log_rotation_method == LOG_ROTATION_HOURLY) strcpy(method_string, "HOURLY"); else if (log_rotation_method == LOG_ROTATION_DAILY) strcpy(method_string, "DAILY"); else if (log_rotation_method == LOG_ROTATION_WEEKLY) strcpy(method_string, "WEEKLY"); else if (log_rotation_method == LOG_ROTATION_MONTHLY) strcpy(method_string, "MONTHLY"); else return ERROR; /* update the last log rotation time and status log */ last_log_rotation = time(NULL); update_program_status(FALSE); t = localtime_r(&rotation_time, &tm_s); stat_result = stat(log_file, &log_file_stat); close_log_file(); /* get the archived filename to use */ dummy = asprintf(&log_archive, "%s%sicinga-%02d-%02d-%d-%02d.log", log_archive_path, (log_archive_path[strlen(log_archive_path)-1] == '/') ? "" : "/", t->tm_mon + 1, t->tm_mday, t->tm_year + 1900, t->tm_hour); /* rotate the log file */ rename_result = my_rename(log_file, log_archive); log_fp = open_log_file(); if (rename_result) { my_free(log_archive); return ERROR; } /* record the log rotation after it has been done... */ dummy = asprintf(&temp_buffer, "LOG ROTATION: %s\n", method_string); write_to_all_logs_with_timestamp(temp_buffer, NSLOG_PROCESS_INFO, &rotation_time); my_free(temp_buffer); /* record log file version format */ write_log_file_info(&rotation_time); if (stat_result == 0) { chmod(log_file, log_file_stat.st_mode); dummy = chown(log_file, log_file_stat.st_uid, log_file_stat.st_gid); } /* log current host and service state if activated*/ if (log_current_states == TRUE) { log_host_states(CURRENT_STATES, &rotation_time); log_service_states(CURRENT_STATES, &rotation_time); } /* free memory */ my_free(log_archive); return OK; }
int main(int argc, char **argv) { hardened_shadow_openlog("userdel"); if (lckpwdf() != 0) err(EXIT_FAILURE, "lckpwdf"); parse_args(argc, argv); bool user_private_groups; if (!hardened_shadow_config_get_bool("USER_PRIVATE_GROUPS", &user_private_groups)) { errx(EXIT_FAILURE, "failed to retrieve USER_PRIVATE_GROUPS setting"); } const char *userdel_command = NULL; if (!hardened_shadow_config_get_path("USERDEL_COMMAND", &userdel_command)) errx(EXIT_FAILURE, "failed to retrieve USERDEL_COMMAND setting"); /* Note: shadow-utils try to detect whether user is logged in. * However, it is not obvious how to perform such detection reliably, * especially taking daemons like cron or at into account (they usually * don't go through PAM or anything that'd allow us to prevent * running processes as user being delete in a race-free way. * * Because of those drawbacks, no such checking is performed here. */ { char* user_dir_path = NULL; if (asprintf(&user_dir_path, "/etc/hardened-shadow/%s", user_name) < 0) errx(EXIT_FAILURE, "memory allocation failure"); if (!recursively_remove_path(user_dir_path)) errx(EXIT_FAILURE, "failed to remove %s", user_dir_path); free(user_dir_path); } if (!hardened_shadow_update_group_change_user_name(user_name, NULL)) errx(EXIT_FAILURE, "hardened_shadow_update_group_change_user_name failed"); if (!hardened_shadow_replace_passwd(user_name, NULL)) errx(EXIT_FAILURE, "hardened_shadow_replace_passwd failed"); if (user_private_groups) { struct group *gr = getgrnam(user_name); if (gr) { gid_t private_gid = gr->gr_gid; bool found = false; struct passwd *pwd = NULL; setpwent(); while ((pwd = getpwent())) { if (pwd->pw_gid == private_gid) { found = true; break; } } endpwent(); if (found) { warnx("not removing private user group because it is a primary group " "of at least one other user"); } else if (!hardened_shadow_replace_group(user_name, NULL)) { errx(EXIT_FAILURE, "failed to remove user private group"); } } } /* Note: preserve exact wording of syslog messages from shadow-utils * where possible. */ hardened_shadow_syslog(LOG_INFO, "delete user '%s'", user_name); if (flag_remove && !recursively_remove_path(user_home)) errx(EXIT_FAILURE, "remove_home_directory failed"); if (!run_userdel_command(userdel_command)) errx(EXIT_FAILURE, "failed to run USERDEL_COMMAND"); hardened_shadow_flush_nscd("passwd"); hardened_shadow_flush_nscd("group"); if (ulckpwdf() != 0) warn("ulckpwdf"); free(user_home); return EXIT_SUCCESS; }
/* write to the debug log */ int log_debug_info(int level, int verbosity, const char *fmt, ...) { va_list ap; char *temp_path = NULL; struct timeval current_time; if (!(debug_level == DEBUGL_ALL || (level & debug_level))) return OK; if (verbosity > debug_verbosity) return OK; if (debug_file_fp == NULL) return ERROR; /* * lock it so concurrent threads don't stomp on each other's * writings. We maintain the lock until we've (optionally) * renamed the file. * If soft_lock() fails we return early. */ if (soft_lock(&debug_fp_lock) < 0) return ERROR; /* write the timestamp */ gettimeofday(¤t_time, NULL); fprintf(debug_file_fp, "[%lu.%06lu] [%03d.%d] [pid=%lu] ", current_time.tv_sec, current_time.tv_usec, level, verbosity, (unsigned long)getpid()); /* write the data */ va_start(ap, fmt); vfprintf(debug_file_fp, fmt, ap); va_end(ap); /* flush, so we don't have problems tailing or when fork()ing */ fflush(debug_file_fp); /* if file has grown beyond max, rotate it */ if ((unsigned long)ftell(debug_file_fp) > max_debug_file_size && max_debug_file_size > 0L) { /* close the file */ close_debug_log(); /* rotate the log file */ dummy = asprintf(&temp_path, "%s.old", debug_file); if (temp_path) { /* unlink the old debug file */ unlink(temp_path); /* rotate the debug file */ my_rename(debug_file, temp_path); /* free memory */ my_free(temp_path); } /* open a new file */ open_debug_log(); } pthread_mutex_unlock(&debug_fp_lock); return OK; }
static u32 build_default_directory_structure(const char *dir_path, struct selabel_handle *sehnd) { u32 inode; u32 root_inode; struct dentry dentries = { .filename = "lost+found", .file_type = EXT4_FT_DIR, .mode = S_IRWXU, .uid = 0, .gid = 0, .mtime = 0, }; root_inode = make_directory(0, 1, &dentries, 1); inode = make_directory(root_inode, 0, NULL, 0); *dentries.inode = inode; inode_set_permissions(inode, dentries.mode, dentries.uid, dentries.gid, dentries.mtime); #ifndef USE_MINGW if (sehnd) { char *path = NULL; char *secontext = NULL; asprintf(&path, "%slost+found", dir_path); if (selabel_lookup(sehnd, &secontext, path, S_IFDIR) < 0) { error("cannot lookup security context for %s", path); } else { inode_set_selinux(inode, secontext); freecon(secontext); } free(path); } #endif return root_inode; } #ifndef USE_MINGW /* Read a local directory and create the same tree in the generated filesystem. Calls itself recursively with each directory in the given directory. full_path is an absolute or relative path, with a trailing slash, to the directory on disk that should be copied, or NULL if this is a directory that does not exist on disk (e.g. lost+found). dir_path is an absolute path, with trailing slash, to the same directory if the image were mounted at the specified mount point */ static u32 build_directory_structure(const char *full_path, const char *dir_path, const char *target_out_path, u32 dir_inode, fs_config_func_t fs_config_func, struct selabel_handle *sehnd, int verbose, time_t fixed_time) { int entries = 0; struct dentry *dentries; struct dirent **namelist = NULL; struct stat stat; int ret; int i; u32 inode; u32 entry_inode; u32 dirs = 0; bool needs_lost_and_found = false; if (full_path) { entries = scandir(full_path, &namelist, filter_dot, (void*)alphasort); if (entries < 0) { #ifdef __GLIBC__ /* The scandir function implemented in glibc has a bug that makes it erroneously fail with ENOMEM under certain circumstances. As a workaround we can retry the scandir call with the same arguments. GLIBC BZ: https://sourceware.org/bugzilla/show_bug.cgi?id=17804 */ if (errno == ENOMEM) entries = scandir(full_path, &namelist, filter_dot, (void*)alphasort); #endif if (entries < 0) { error_errno("scandir"); return EXT4_ALLOCATE_FAILED; } } } if (dir_inode == 0) { /* root directory, check if lost+found already exists */ for (i = 0; i < entries; i++) if (strcmp(namelist[i]->d_name, "lost+found") == 0) break; if (i == entries) needs_lost_and_found = true; } dentries = calloc(entries, sizeof(struct dentry)); if (dentries == NULL) critical_error_errno("malloc"); for (i = 0; i < entries; i++) { dentries[i].filename = strdup(namelist[i]->d_name); if (dentries[i].filename == NULL) critical_error_errno("strdup"); asprintf(&dentries[i].path, "%s%s", dir_path, namelist[i]->d_name); asprintf(&dentries[i].full_path, "%s%s", full_path, namelist[i]->d_name); free(namelist[i]); ret = lstat(dentries[i].full_path, &stat); if (ret < 0) { error_errno("lstat"); i--; entries--; continue; } dentries[i].size = stat.st_size; dentries[i].mode = stat.st_mode & (S_ISUID|S_ISGID|S_ISVTX|S_IRWXU|S_IRWXG|S_IRWXO); if (fixed_time == -1) { dentries[i].mtime = stat.st_mtime; } else { dentries[i].mtime = fixed_time; } uint64_t capabilities; if (fs_config_func != NULL) { #ifdef ANDROID unsigned int mode = 0; unsigned int uid = 0; unsigned int gid = 0; int dir = S_ISDIR(stat.st_mode); fs_config_func(dentries[i].path, dir, target_out_path, &uid, &gid, &mode, &capabilities); dentries[i].mode = mode; dentries[i].uid = uid; dentries[i].gid = gid; dentries[i].capabilities = capabilities; #else error("can't set android permissions - built without android support"); #endif } #ifndef USE_MINGW if (sehnd) { if (selabel_lookup(sehnd, &dentries[i].secon, dentries[i].path, stat.st_mode) < 0) { error("cannot lookup security context for %s", dentries[i].path); } if (dentries[i].secon && verbose) printf("Labeling %s as %s\n", dentries[i].path, dentries[i].secon); } #endif if (S_ISREG(stat.st_mode)) { dentries[i].file_type = EXT4_FT_REG_FILE; } else if (S_ISDIR(stat.st_mode)) { dentries[i].file_type = EXT4_FT_DIR; dirs++; } else if (S_ISCHR(stat.st_mode)) { dentries[i].file_type = EXT4_FT_CHRDEV; } else if (S_ISBLK(stat.st_mode)) { dentries[i].file_type = EXT4_FT_BLKDEV; } else if (S_ISFIFO(stat.st_mode)) { dentries[i].file_type = EXT4_FT_FIFO; } else if (S_ISSOCK(stat.st_mode)) { dentries[i].file_type = EXT4_FT_SOCK; } else if (S_ISLNK(stat.st_mode)) { dentries[i].file_type = EXT4_FT_SYMLINK; dentries[i].link = calloc(info.block_size, 1); readlink(dentries[i].full_path, dentries[i].link, info.block_size - 1); } else { error("unknown file type on %s", dentries[i].path); i--; entries--; } } free(namelist); if (needs_lost_and_found) { /* insert a lost+found directory at the beginning of the dentries */ struct dentry *tmp = calloc(entries + 1, sizeof(struct dentry)); memset(tmp, 0, sizeof(struct dentry)); memcpy(tmp + 1, dentries, entries * sizeof(struct dentry)); dentries = tmp; dentries[0].filename = strdup("lost+found"); asprintf(&dentries[0].path, "%slost+found", dir_path); dentries[0].full_path = NULL; dentries[0].size = 0; dentries[0].mode = S_IRWXU; dentries[0].file_type = EXT4_FT_DIR; dentries[0].uid = 0; dentries[0].gid = 0; if (sehnd) { if (selabel_lookup(sehnd, &dentries[0].secon, dentries[0].path, dentries[0].mode) < 0) error("cannot lookup security context for %s", dentries[0].path); } entries++; dirs++; } inode = make_directory(dir_inode, entries, dentries, dirs); for (i = 0; i < entries; i++) { if (dentries[i].file_type == EXT4_FT_REG_FILE) { entry_inode = make_file(dentries[i].full_path, dentries[i].size); } else if (dentries[i].file_type == EXT4_FT_DIR) { char *subdir_full_path = NULL; char *subdir_dir_path; if (dentries[i].full_path) { ret = asprintf(&subdir_full_path, "%s/", dentries[i].full_path); if (ret < 0) critical_error_errno("asprintf"); } ret = asprintf(&subdir_dir_path, "%s/", dentries[i].path); if (ret < 0) critical_error_errno("asprintf"); entry_inode = build_directory_structure(subdir_full_path, subdir_dir_path, target_out_path, inode, fs_config_func, sehnd, verbose, fixed_time); free(subdir_full_path); free(subdir_dir_path); } else if (dentries[i].file_type == EXT4_FT_SYMLINK) { entry_inode = make_link(dentries[i].link); } else { error("unknown file type on %s", dentries[i].path); entry_inode = 0; } *dentries[i].inode = entry_inode; ret = inode_set_permissions(entry_inode, dentries[i].mode, dentries[i].uid, dentries[i].gid, dentries[i].mtime); if (ret) error("failed to set permissions on %s\n", dentries[i].path); /* * It's important to call inode_set_selinux() before * inode_set_capabilities(). Extended attributes need to * be stored sorted order, and we guarantee this by making * the calls in the proper order. * Please see xattr_assert_sane() in contents.c */ ret = inode_set_selinux(entry_inode, dentries[i].secon); if (ret) error("failed to set SELinux context on %s\n", dentries[i].path); ret = inode_set_capabilities(entry_inode, dentries[i].capabilities); if (ret) error("failed to set capability on %s\n", dentries[i].path); free(dentries[i].path); free(dentries[i].full_path); free(dentries[i].link); free((void *)dentries[i].filename); free(dentries[i].secon); } free(dentries); return inode; }
static void launch_daemons(int fd, short args, void *cbdata) { orte_job_map_t *map; char *jobid_string = NULL; char *param; char **argv = NULL; int argc; int rc; char *tmp; char** env = NULL; char *nodelist_flat; char **nodelist_argv; int nodelist_argc; char *vpid_string; char **custom_strings; int num_args, i; char *cur_prefix; int proc_vpid_index; orte_app_context_t *app; orte_node_t *node; orte_std_cntr_t nnode; orte_job_t *daemons; orte_state_caddy_t *state = (orte_state_caddy_t*)cbdata; /* if we are launching debugger daemons, then just go * do it - no new daemons will be launched */ if (ORTE_FLAG_TEST(state->jdata, ORTE_JOB_FLAG_DEBUGGER_DAEMON)) { state->jdata->state = ORTE_JOB_STATE_DAEMONS_LAUNCHED; ORTE_ACTIVATE_JOB_STATE(state->jdata, ORTE_JOB_STATE_DAEMONS_REPORTED); OBJ_RELEASE(state); return; } /* start by setting up the virtual machine */ daemons = orte_get_job_data_object(ORTE_PROC_MY_NAME->jobid); if (ORTE_SUCCESS != (rc = orte_plm_base_setup_virtual_machine(state->jdata))) { ORTE_ERROR_LOG(rc); goto cleanup; } /* if we don't want to launch, then don't attempt to * launch the daemons - the user really wants to just * look at the proposed process map */ if (orte_do_not_launch) { /* set the state to indicate the daemons reported - this * will trigger the daemons_reported event and cause the * job to move to the following step */ state->jdata->state = ORTE_JOB_STATE_DAEMONS_LAUNCHED; ORTE_ACTIVATE_JOB_STATE(state->jdata, ORTE_JOB_STATE_DAEMONS_REPORTED); OBJ_RELEASE(state); return; } /* Get the map for this job */ if (NULL == (map = daemons->map)) { ORTE_ERROR_LOG(ORTE_ERR_NOT_FOUND); rc = ORTE_ERR_NOT_FOUND; goto cleanup; } if (0 == map->num_new_daemons) { /* set the state to indicate the daemons reported - this * will trigger the daemons_reported event and cause the * job to move to the following step */ OPAL_OUTPUT_VERBOSE((1, orte_plm_base_framework.framework_output, "%s plm:alps: no new daemons to launch", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME))); state->jdata->state = ORTE_JOB_STATE_DAEMONS_LAUNCHED; ORTE_ACTIVATE_JOB_STATE(state->jdata, ORTE_JOB_STATE_DAEMONS_REPORTED); OBJ_RELEASE(state); return; } /* need integer value for command line parameter */ orte_util_convert_jobid_to_string(&jobid_string, daemons->jobid); /* * start building argv array */ argv = NULL; argc = 0; /* * ALPS aprun OPTIONS */ /* add the aprun command */ opal_argv_append(&argc, &argv, mca_plm_alps_component.aprun_cmd); /* Append user defined arguments to aprun */ if ( NULL != mca_plm_alps_component.custom_args ) { custom_strings = opal_argv_split(mca_plm_alps_component.custom_args, ' '); num_args = opal_argv_count(custom_strings); for (i = 0; i < num_args; ++i) { opal_argv_append(&argc, &argv, custom_strings[i]); } opal_argv_free(custom_strings); } /* number of processors needed */ opal_argv_append(&argc, &argv, "-n"); asprintf(&tmp, "%lu", (unsigned long) map->num_new_daemons); opal_argv_append(&argc, &argv, tmp); free(tmp); opal_argv_append(&argc, &argv, "-N"); opal_argv_append(&argc, &argv, "1"); opal_argv_append(&argc, &argv, "-cc"); opal_argv_append(&argc, &argv, "none"); /* create nodelist */ nodelist_argv = NULL; nodelist_argc = 0; for (nnode=0; nnode < map->nodes->size; nnode++) { if (NULL == (node = (orte_node_t*)opal_pointer_array_get_item(map->nodes, nnode))) { continue; } /* if the daemon already exists on this node, then * don't include it */ if (ORTE_FLAG_TEST(node, ORTE_NODE_FLAG_DAEMON_LAUNCHED)) { continue; } /* otherwise, add it to the list of nodes upon which * we need to launch a daemon */ opal_argv_append(&nodelist_argc, &nodelist_argv, node->name); } if (0 == opal_argv_count(nodelist_argv)) { orte_show_help("help-plm-alps.txt", "no-hosts-in-list", true); rc = ORTE_ERR_FAILED_TO_START; goto cleanup; } nodelist_flat = opal_argv_join(nodelist_argv, ','); opal_argv_free(nodelist_argv); /* if we are using all allocated nodes, then alps * doesn't need a nodelist, or if running without a batch scheduler */ if ((map->num_new_daemons < orte_num_allocated_nodes) || (orte_num_allocated_nodes == 0)) { opal_argv_append(&argc, &argv, "-L"); opal_argv_append(&argc, &argv, nodelist_flat); } /* * ORTED OPTIONS */ /* add the daemon command (as specified by user) */ orte_plm_base_setup_orted_cmd(&argc, &argv); /* Add basic orted command line options, including debug flags */ orte_plm_base_orted_append_basic_args(&argc, &argv, NULL, &proc_vpid_index, nodelist_flat); free(nodelist_flat); /* tell the new daemons the base of the name list so they can compute * their own name on the other end */ rc = orte_util_convert_vpid_to_string(&vpid_string, map->daemon_vpid_start); if (ORTE_SUCCESS != rc) { opal_output(0, "plm_alps: unable to create process name"); goto cleanup; } free(argv[proc_vpid_index]); argv[proc_vpid_index] = strdup(vpid_string); free(vpid_string); if (mca_plm_alps_component.debug) { param = opal_argv_join(argv, ' '); if (NULL != param) { opal_output(0, "plm:alps: final top-level argv:"); opal_output(0, "plm:alps: %s", param); free(param); } } /* Copy the prefix-directory specified in the corresponding app_context. If there are multiple, different prefix's in the app context, complain (i.e., only allow one --prefix option for the entire alps run -- we don't support different --prefix'es for different nodes in the ALPS plm) */ cur_prefix = NULL; for (i=0; i < state->jdata->apps->size; i++) { char *app_prefix_dir = NULL; if (NULL == (app = (orte_app_context_t*)opal_pointer_array_get_item(state->jdata->apps, i))) { continue; } orte_get_attribute(&app->attributes, ORTE_APP_PREFIX_DIR, (void**)&app_prefix_dir, OPAL_STRING); /* Check for already set cur_prefix_dir -- if different, complain */ if (NULL != app_prefix_dir) { if (NULL != cur_prefix && 0 != strcmp (cur_prefix, app_prefix_dir)) { orte_show_help("help-plm-alps.txt", "multiple-prefixes", true, cur_prefix, app_prefix_dir); goto cleanup; } /* If not yet set, copy it; iff set, then it's the same anyway */ if (NULL == cur_prefix) { cur_prefix = strdup(app_prefix_dir); if (mca_plm_alps_component.debug) { opal_output (0, "plm:alps: Set prefix:%s", cur_prefix); } } free(app_prefix_dir); } } /* protect the args in case someone has a script wrapper around aprun */ mca_base_cmd_line_wrap_args(argv); /* setup environment */ env = opal_argv_copy(orte_launch_environ); if (0 < opal_output_get_verbosity(orte_plm_base_framework.framework_output)) { param = opal_argv_join(argv, ' '); OPAL_OUTPUT_VERBOSE((1, orte_plm_base_framework.framework_output, "%s plm:alps: final top-level argv:\n\t%s", ORTE_NAME_PRINT(ORTE_PROC_MY_NAME), (NULL == param) ? "NULL" : param)); if (NULL != param) free(param); } /* exec the daemon(s) */ if (ORTE_SUCCESS != (rc = plm_alps_start_proc(argc, argv, env, cur_prefix))) { ORTE_ERROR_LOG(rc); goto cleanup; } /* indicate that the daemons for this job were launched */ state->jdata->state = ORTE_JOB_STATE_DAEMONS_LAUNCHED; daemons->state = ORTE_JOB_STATE_DAEMONS_LAUNCHED; /* flag that launch was successful, so far as we currently know */ failed_launch = false; cleanup: if (NULL != argv) { opal_argv_free(argv); } if (NULL != env) { opal_argv_free(env); } if(NULL != jobid_string) { free(jobid_string); } /* cleanup the caddy */ OBJ_RELEASE(state); /* check for failed launch - if so, force terminate */ if (failed_launch) { ORTE_FORCED_TERMINATE(ORTE_ERROR_DEFAULT_EXIT_CODE); } }
static int Open( vlc_va_vaapi_t *p_va, int i_codec_id ) { VAProfile i_profile, *p_profiles_list; bool b_supported_profile = false; int i_profiles_nb = 0; int i_surface_count; /* */ switch( i_codec_id ) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: i_profile = VAProfileMPEG2Main; i_surface_count = 2+1; break; case CODEC_ID_MPEG4: i_profile = VAProfileMPEG4AdvancedSimple; i_surface_count = 2+1; break; case CODEC_ID_WMV3: i_profile = VAProfileVC1Main; i_surface_count = 2+1; break; case CODEC_ID_VC1: i_profile = VAProfileVC1Advanced; i_surface_count = 2+1; break; case CODEC_ID_H264: i_profile = VAProfileH264High; i_surface_count = 16+1; break; default: return VLC_EGENERIC; } /* */ memset( p_va, 0, sizeof(*p_va) ); p_va->i_config_id = VA_INVALID_ID; p_va->i_context_id = VA_INVALID_ID; p_va->image.image_id = VA_INVALID_ID; /* Create a VA display */ p_va->p_display_x11 = XOpenDisplay(NULL); if( !p_va->p_display_x11 ) goto error; p_va->p_display = vaGetDisplay( p_va->p_display_x11 ); if( !p_va->p_display ) goto error; if( vaInitialize( p_va->p_display, &p_va->i_version_major, &p_va->i_version_minor ) ) goto error; /* Check if the selected profile is supported */ i_profiles_nb = vaMaxNumProfiles( p_va->p_display ); p_profiles_list = calloc( i_profiles_nb, sizeof( VAProfile ) ); if ( !p_profiles_list ) goto error; VAStatus i_status = vaQueryConfigProfiles( p_va->p_display, p_profiles_list, &i_profiles_nb ); if ( i_status == VA_STATUS_SUCCESS ) { for( int i = 0; i < i_profiles_nb; i++ ) { if ( p_profiles_list[i] == i_profile ) { b_supported_profile = true; break; } } } free( p_profiles_list ); if ( !b_supported_profile ) goto error; /* Create a VA configuration */ VAConfigAttrib attrib; memset( &attrib, 0, sizeof(attrib) ); attrib.type = VAConfigAttribRTFormat; if( vaGetConfigAttributes( p_va->p_display, i_profile, VAEntrypointVLD, &attrib, 1 ) ) goto error; /* Not sure what to do if not, I don't have a way to test */ if( (attrib.value & VA_RT_FORMAT_YUV420) == 0 ) goto error; if( vaCreateConfig( p_va->p_display, i_profile, VAEntrypointVLD, &attrib, 1, &p_va->i_config_id ) ) { p_va->i_config_id = VA_INVALID_ID; goto error; } p_va->i_surface_count = i_surface_count; if( asprintf( &p_va->va.description, "VA API version %d.%d", p_va->i_version_major, p_va->i_version_minor ) < 0 ) p_va->va.description = NULL; return VLC_SUCCESS; error: return VLC_EGENERIC; }
static int plm_alps_start_proc(int argc, char **argv, char **env, char *prefix) { int fd; pid_t alps_pid; char *exec_argv = opal_path_findv(argv[0], 0, env, NULL); if (NULL == exec_argv) { return ORTE_ERR_NOT_FOUND; } alps_pid = fork(); if (-1 == alps_pid) { ORTE_ERROR_LOG(ORTE_ERR_SYS_LIMITS_CHILDREN); return ORTE_ERR_SYS_LIMITS_CHILDREN; } alpsrun = OBJ_NEW(orte_proc_t); alpsrun->pid = alps_pid; /* be sure to mark it as alive so we don't instantly fire */ ORTE_FLAG_SET(alpsrun, ORTE_PROC_FLAG_ALIVE); /* setup the waitpid so we can find out if alps succeeds! */ orte_wait_cb(alpsrun, alps_wait_cb, NULL); if (0 == alps_pid) { /* child */ char *bin_base = NULL, *lib_base = NULL; /* Figure out the basenames for the libdir and bindir. There is a lengthy comment about this in plm_rsh_module.c explaining all the rationale for how / why we're doing this. */ lib_base = opal_basename(opal_install_dirs.libdir); bin_base = opal_basename(opal_install_dirs.bindir); /* If we have a prefix, then modify the PATH and LD_LIBRARY_PATH environment variables. */ if (NULL != prefix) { char *oldenv, *newenv; /* Reset PATH */ oldenv = getenv("PATH"); if (NULL != oldenv) { asprintf(&newenv, "%s/%s:%s", prefix, bin_base, oldenv); } else { asprintf(&newenv, "%s/%s", prefix, bin_base); } opal_setenv("PATH", newenv, true, &env); if (mca_plm_alps_component.debug) { opal_output(0, "plm:alps: reset PATH: %s", newenv); } free(newenv); /* Reset LD_LIBRARY_PATH */ oldenv = getenv("LD_LIBRARY_PATH"); if (NULL != oldenv) { asprintf(&newenv, "%s/%s:%s", prefix, lib_base, oldenv); } else { asprintf(&newenv, "%s/%s", prefix, lib_base); } opal_setenv("LD_LIBRARY_PATH", newenv, true, &env); if (mca_plm_alps_component.debug) { opal_output(0, "plm:alps: reset LD_LIBRARY_PATH: %s", newenv); } free(newenv); } fd = open("/dev/null", O_CREAT|O_WRONLY|O_TRUNC, 0666); if(fd > 0) { dup2(fd, 0); } /* When not in debug mode and --debug-daemons was not passed, * tie stdout/stderr to dev null so we don't see messages from orted */ if (0 == mca_plm_alps_component.debug && !orte_debug_daemons_flag) { if (fd >= 0) { if (fd != 1) { dup2(fd,1); } if (fd != 2) { dup2(fd,2); } } } if (fd > 2) { close(fd); } /* get the alps process out of orterun's process group so that signals sent from the shell (like those resulting from cntl-c) don't get sent to alps */ setpgid(0, 0); execve(exec_argv, argv, env); opal_output(0, "plm:alps:start_proc: exec failed"); /* don't return - need to exit - returning would be bad - we're not in the calling process anymore */ exit(1); } else { /* parent */ /* just in case, make sure that the alps process is not in our process group any more. Stevens says always do this on both sides of the fork... */ setpgid(alps_pid, alps_pid); free(exec_argv); } return ORTE_SUCCESS; }
static void wait_for_connection(const char *service) { struct addrinfo hints; struct addrinfo *res, *addr; struct pollfd *fds, *fdp; int nfds; int i; int error; int on = 1; memset(&hints, 0, sizeof(hints)); hints.ai_family = PF_UNSPEC; hints.ai_flags = AI_PASSIVE; hints.ai_socktype = SOCK_STREAM; error = getaddrinfo(NULL, service, &hints, &res); if (error) { char *p; error = asprintf(&p, "getaddrinfo: %s\n", gai_strerror(error)); fatal(2, error >= 0 ? p : ""); } for (addr = res, nfds = 0; addr; addr = addr->ai_next, nfds++) ; fds = malloc(sizeof(struct pollfd) * nfds); for (addr = res, fdp = fds; addr; addr = addr->ai_next, fdp++) { int s; if (addr->ai_family == AF_LOCAL) { nextaddr: fdp--; nfds--; continue; } s = socket(addr->ai_family, SOCK_STREAM, 0); if (s < 0) { if (errno == EAFNOSUPPORT || errno == EINVAL) { goto nextaddr; } fatalperror(2, "socket"); } if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on))) { fatalperror(2, "setsockopt"); } if (bind(s, addr->ai_addr, addr->ai_addrlen)) { #ifdef linux if (fdp != fds && errno == EADDRINUSE) { close(s); goto nextaddr; } #endif fatalperror(2, "bind"); } if (listen(s, 1)) { fatalperror(2, "listen"); } if (fcntl(s, F_SETFL, O_NONBLOCK)) { fatalperror(2, "fcntl"); } fdp->fd = s; fdp->events = POLLIN; } freeaddrinfo(res); while (1) { if (poll(fds, nfds, -1) < 0) { if (errno == EINTR) { continue; } fatalperror(2, "poll"); } for (i = 0, fdp = fds; i < nfds; i++, fdp++) { int fd; if (!(fdp->revents & POLLIN)) { continue; } fd = accept(fdp->fd, 0, 0); if (fd >= 0) { dup2(fd, 0); close(fd); goto out; } if (errno != EAGAIN) { fatalperror(2, "accept"); } } } out: for (i = 0, fdp = fds; i < nfds; i++, fdp++) { close(fdp->fd); } free(fds); }
static void device_added(struct udev_device *udev_device) { const char *path, *name = NULL; char *config_info = NULL; const char *syspath; const char *tags_prop; const char *key, *value, *tmp; InputOption *input_options; InputAttributes attrs = { }; DeviceIntPtr dev = NULL; struct udev_list_entry *set, *entry; struct udev_device *parent; int rc; const char *dev_seat; path = udev_device_get_devnode(udev_device); syspath = udev_device_get_syspath(udev_device); if (!path || !syspath) return; dev_seat = udev_device_get_property_value(udev_device, "ID_SEAT"); if (!dev_seat) dev_seat = "seat0"; if (SeatId && strcmp(dev_seat, SeatId)) return; if (!SeatId && strcmp(dev_seat, "seat0")) return; #ifdef CONFIG_UDEV_KMS if (!strcmp(udev_device_get_subsystem(udev_device), "drm")) { const char *sysname = udev_device_get_sysname(udev_device); if (strncmp(sysname, "card", 4) != 0) return; LogMessage(X_INFO, "config/udev: Adding drm device (%s)\n", path); config_udev_odev_setup_attribs(path, syspath, NewGPUDeviceRequest); return; } #endif if (!udev_device_get_property_value(udev_device, "ID_INPUT")) { LogMessageVerb(X_INFO, 10, "config/udev: ignoring device %s without " "property ID_INPUT set\n", path); return; } input_options = input_option_new(NULL, "_source", "server/udev"); if (!input_options) return; parent = udev_device_get_parent(udev_device); if (parent) { const char *ppath = udev_device_get_devnode(parent); const char *product = udev_device_get_property_value(parent, "PRODUCT"); const char *pnp_id = udev_device_get_sysattr_value(parent, "id"); unsigned int usb_vendor, usb_model; name = udev_device_get_sysattr_value(parent, "name"); LOG_SYSATTR(ppath, "name", name); if (!name) { name = udev_device_get_property_value(parent, "NAME"); LOG_PROPERTY(ppath, "NAME", name); } if (pnp_id) attrs.pnp_id = strdup(pnp_id); LOG_SYSATTR(ppath, "id", pnp_id); /* construct USB ID in lowercase hex - "0000:ffff" */ if (product && sscanf(product, "%*x/%4x/%4x/%*x", &usb_vendor, &usb_model) == 2) { if (asprintf(&attrs.usb_id, "%04x:%04x", usb_vendor, usb_model) == -1) attrs.usb_id = NULL; else LOG_PROPERTY(ppath, "PRODUCT", product); } } if (!name) name = "(unnamed)"; else attrs.product = strdup(name); input_options = input_option_new(input_options, "name", name); input_options = input_option_new(input_options, "path", path); input_options = input_option_new(input_options, "device", path); if (path) attrs.device = strdup(path); tags_prop = udev_device_get_property_value(udev_device, "ID_INPUT.tags"); LOG_PROPERTY(path, "ID_INPUT.tags", tags_prop); attrs.tags = xstrtokenize(tags_prop, ","); if (asprintf(&config_info, "udev:%s", syspath) == -1) { config_info = NULL; goto unwind; } if (device_is_duplicate(config_info)) { LogMessage(X_WARNING, "config/udev: device %s already added. " "Ignoring.\n", name); goto unwind; } set = udev_device_get_properties_list_entry(udev_device); udev_list_entry_foreach(entry, set) { key = udev_list_entry_get_name(entry); if (!key) continue; value = udev_list_entry_get_value(entry); if (!strncasecmp(key, UDEV_XKB_PROP_KEY, sizeof(UDEV_XKB_PROP_KEY) - 1)) { LOG_PROPERTY(path, key, value); tmp = key + sizeof(UDEV_XKB_PROP_KEY) - 1; if (!strcasecmp(tmp, "rules")) input_options = input_option_new(input_options, "xkb_rules", value); else if (!strcasecmp(tmp, "layout")) input_options = input_option_new(input_options, "xkb_layout", value); else if (!strcasecmp(tmp, "variant")) input_options = input_option_new(input_options, "xkb_variant", value); else if (!strcasecmp(tmp, "model")) input_options = input_option_new(input_options, "xkb_model", value); else if (!strcasecmp(tmp, "options")) input_options = input_option_new(input_options, "xkb_options", value); } else if (!strcmp(key, "ID_VENDOR")) { LOG_PROPERTY(path, key, value); attrs.vendor = strdup(value); } else if (!strcmp(key, "ID_INPUT_KEY")) { LOG_PROPERTY(path, key, value); attrs.flags |= ATTR_KEYBOARD; } else if (!strcmp(key, "ID_INPUT_MOUSE")) { LOG_PROPERTY(path, key, value); attrs.flags |= ATTR_POINTER; } else if (!strcmp(key, "ID_INPUT_JOYSTICK")) { LOG_PROPERTY(path, key, value); attrs.flags |= ATTR_JOYSTICK; } else if (!strcmp(key, "ID_INPUT_TABLET")) { LOG_PROPERTY(path, key, value); attrs.flags |= ATTR_TABLET; } else if (!strcmp(key, "ID_INPUT_TOUCHPAD")) { LOG_PROPERTY(path, key, value); attrs.flags |= ATTR_TOUCHPAD; } else if (!strcmp(key, "ID_INPUT_TOUCHSCREEN")) { LOG_PROPERTY(path, key, value); attrs.flags |= ATTR_TOUCHSCREEN; } }
/** * Saves the in-memory configuration into a file. * @return 0 on success, -1 on error. */ int config_SaveConfigFile (vlc_object_t *p_this) { if( config_PrepareDir( p_this ) ) { msg_Err( p_this, "no configuration directory" ); return -1; } /* * Save module config in file */ char *temporary; char *permanent = config_GetConfigFile (p_this); if (permanent == NULL) return -1; if (asprintf (&temporary, "%s.%u", permanent, getpid ()) == -1) { free (permanent); return -1; } else { struct stat st; /* Some users make vlcrc read-only to prevent changes. * The atomic replacement scheme breaks this "feature", * so we check for read-only by hand. */ if (stat (permanent, &st) == 0 && !(st.st_mode & S_IWUSR)) { msg_Err (p_this, "configuration file is read-only"); goto error; } } /* Configuration lock must be taken before vlcrc serializer below. */ vlc_rwlock_rdlock (&config_lock); /* The temporary configuration file is per-PID. Therefore this function * should be serialized against itself within a given process. */ static vlc_mutex_t lock = VLC_STATIC_MUTEX; vlc_mutex_lock (&lock); int fd = vlc_open (temporary, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR|S_IWUSR); if (fd == -1) { vlc_rwlock_unlock (&config_lock); vlc_mutex_unlock (&lock); goto error; } FILE *file = fdopen (fd, "wt"); if (file == NULL) { msg_Err (p_this, "cannot create configuration file: %s", vlc_strerror_c(errno)); vlc_rwlock_unlock (&config_lock); vlc_close (fd); vlc_mutex_unlock (&lock); goto error; } fprintf( file, "\xEF\xBB\xBF###\n" "### "PACKAGE_NAME" "PACKAGE_VERSION"\n" "###\n" "\n" "###\n" "### lines beginning with a '#' character are comments\n" "###\n" "\n" ); /* Ensure consistent number formatting... */ locale_t loc = newlocale (LC_NUMERIC_MASK, "C", NULL); locale_t baseloc = uselocale (loc); /* We would take the config lock here. But this would cause a lock * inversion with the serializer above and config_AutoSaveConfigFile(). vlc_rwlock_rdlock (&config_lock);*/ /* Look for the selected module, if NULL then save everything */ size_t count; module_t **list = module_list_get (&count); for (size_t i = 0; i < count; i++) { module_t *p_parser = list[i]; module_config_t *p_item, *p_end; if( !p_parser->i_config_items ) continue; fprintf( file, "[%s]", module_get_object (p_parser) ); if( p_parser->psz_longname ) fprintf( file, " # %s\n\n", p_parser->psz_longname ); else fprintf( file, "\n\n" ); for( p_item = p_parser->p_config, p_end = p_item + p_parser->confsize; p_item < p_end; p_item++ ) { if (!CONFIG_ITEM(p_item->i_type) /* ignore hint */ || p_item->b_removed /* ignore deprecated option */ || p_item->b_unsaveable) /* ignore volatile option */ continue; if (IsConfigIntegerType (p_item->i_type)) { int64_t val = p_item->value.i; config_Write (file, p_item->psz_text, (CONFIG_CLASS(p_item->i_type) == CONFIG_ITEM_BOOL) ? N_("boolean") : N_("integer"), val == p_item->orig.i, p_item->psz_name, "%"PRId64, val); } else if (IsConfigFloatType (p_item->i_type)) { float val = p_item->value.f; config_Write (file, p_item->psz_text, N_("float"), val == p_item->orig.f, p_item->psz_name, "%f", val); } else { const char *psz_value = p_item->value.psz; bool modified; assert (IsConfigStringType (p_item->i_type)); modified = !!strcmp (psz_value ? psz_value : "", p_item->orig.psz ? p_item->orig.psz : ""); config_Write (file, p_item->psz_text, N_("string"), !modified, p_item->psz_name, "%s", psz_value ? psz_value : ""); } } } vlc_rwlock_unlock (&config_lock); module_list_free (list); if (loc != (locale_t)0) { uselocale (baseloc); freelocale (loc); } /* * Flush to disk and replace atomically */ fflush (file); /* Flush from run-time */ if (ferror (file)) { vlc_unlink (temporary); vlc_mutex_unlock (&lock); msg_Err (p_this, "cannot write configuration file"); fclose (file); goto error; } #if defined(__APPLE__) || defined(__ANDROID__) fsync (fd); /* Flush from OS */ #else fdatasync (fd); /* Flush from OS */ #endif #if defined (_WIN32) || defined (__OS2__) /* Windows cannot (re)move open files nor overwrite existing ones */ fclose (file); vlc_unlink (permanent); #endif /* Atomically replace the file... */ if (vlc_rename (temporary, permanent)) vlc_unlink (temporary); /* (...then synchronize the directory, err, TODO...) */ /* ...and finally close the file */ vlc_mutex_unlock (&lock); #if !defined (_WIN32) && !defined (__OS2__) fclose (file); #endif free (temporary); free (permanent); return 0; error: free (temporary); free (permanent); return -1; }
FAR char *telnetd_driver(int sd, FAR struct telnetd_s *daemon) { FAR struct telnetd_dev_s *priv; FAR struct socket *psock; FAR char *devpath = NULL; int ret; /* Allocate instance data for this driver */ priv = (FAR struct telnetd_dev_s*)malloc(sizeof(struct telnetd_dev_s)); if (!priv) { nlldbg("Failed to allocate the driver data structure\n"); return NULL; } /* Initialize the allocated driver instance */ sem_init(&priv->td_exclsem, 0, 1); priv->td_state = STATE_NORMAL; priv->td_crefs = 0; priv->td_pending = 0; priv->td_offset = 0; /* Clone the internal socket structure. We do this so that it will be * independent of threads and of socket descriptors (the original socket * instance resided in the daemon's socket array). */ psock = sockfd_socket(sd); if (!psock) { nlldbg("Failed to convert sd=%d to a socket structure\n", sd); goto errout_with_dev; } ret = net_clone(psock, &priv->td_psock); if (ret < 0) { nlldbg("net_clone failed: %d\n", ret); goto errout_with_dev; } /* And close the original */ psock_close(psock); /* Allocation a unique minor device number of the telnet drvier */ do { ret = sem_wait(&g_telnetdcommon.exclsem); if (ret < 0 && errno != -EINTR) { goto errout_with_dev; } } while (ret < 0); priv->td_minor = g_telnetdcommon.minor; g_telnetdcommon.minor++; sem_post(&g_telnetdcommon.exclsem); /* Create a path and name for the driver. */ ret = asprintf(&devpath, TELNETD_DEVFMT, priv->td_minor); if (ret < 0) { nlldbg("Failed to allocate the driver path\n"); goto errout_with_dev; } /* Register the driver */ ret = register_driver(devpath, &g_telnetdfops, 0666, priv); if (ret < 0) { nlldbg("Failed to register the driver %s: %d\n", devpath, ret); goto errout_with_devpath; } /* Return the path to the new telnet driver */ return devpath; errout_with_devpath: free(devpath); errout_with_dev: free(priv); return NULL; }