/** RFC-2047 encode string with given charset. Only the Q encoding * (quoted-printable) supported at this time. * WARNING: this code returns a static buffer! */ char *rfc2047e(const char *string, const char *charset) { static char *out; char *t; const char *r; int count, minlen, idx, i; char **words = NULL; size_t l; assert(strlen(charset) < 40); if (out) { free(out); out = NULL; } /* phase 1: split original into words */ /* 1a: count, 1b: copy */ count = 0; r = string; while (*r) { count++; r += strcspn(r, ws); if (!*r) break; count++; r += strspn(r, ws); } words = (char **)xmalloc(sizeof(char *) * (count + 1)); idx = 0; r = string; while (*r) { l = strcspn(r, ws); words[idx] = (char *)xmalloc(l+1); memcpy(words[idx], r, l); words[idx][l] = '\0'; idx++; r += l; if (!*r) break; l = strspn(r, ws); words[idx] = (char *)xmalloc(l+1); memcpy(words[idx], r, l); words[idx][l] = '\0'; idx++; r += l; } /* phase 2: encode words */ /* a: find ranges of adjacent words to need encoding */ /* b: encode ranges */ idx = 0; while (idx < count) { int end; char *tmp; if (!needs_enc(words[idx])) { idx += 2; continue; } for (end = idx + 2; end < count; end += 2) { if (!needs_enc(words[end])) break; } end -= 2; tmp = encode_words(&words[idx], end - idx + 1, charset); free(words[idx]); words[idx] = tmp; for (i = idx + 1; i <= end; i++) words[i][0] = '\0'; idx = end + 2; } l = 0; for (idx = 0; idx < count; idx++) { l += strlen(words[idx]); } /* phase 3: limit lengths */ minlen = strlen(charset) + 7; /* allocate ample memory */ out = (char *)xmalloc(l + (l / (72 - minlen) + 1) * (minlen + 2) + 1); if (count) t = stpcpy(out, words[0]); else t = out, *out = 0; l = strlen(out); for (i = 1; i < count; i+=2) { size_t m; char *tmp; m = strlen(words[i]); if (i + 1 < count) m += strcspn(words[i+1], "\r\n"); if (l + m > 74) t = stpcpy(t, "\r\n"); t = stpcpy(t, words[i]); if (i + 1 < count) { t = stpcpy(t, words[i+1]); } tmp = strrchr(out, '\n'); if (tmp == NULL) tmp = out; else tmp++; l = strlen(tmp); } /* free memory */ for (i = 0; i < count; i++) free(words[i]); free(words); return out; }
/* Modify a Key description, replacing certain special format characters. List of currently supported replacements: %% - Replaced by a single % %c - Replaced by the content of COMMENT. %F - Replaced by an ssh style fingerprint computed from KEY. The functions returns 0 on success or an error code. On success a newly allocated string is stored at the address of RESULT. */ static gpg_error_t modify_description (const char *in, const char *comment, const gcry_sexp_t key, char **result) { size_t comment_length; size_t in_len; size_t out_len; char *out; size_t i; int special, pass; char *ssh_fpr = NULL; comment_length = strlen (comment); in_len = strlen (in); /* First pass calculates the length, second pass does the actual copying. */ out = NULL; out_len = 0; for (pass=0; pass < 2; pass++) { special = 0; for (i = 0; i < in_len; i++) { if (special) { special = 0; switch (in[i]) { case '%': if (out) *out++ = '%'; else out_len++; break; case 'c': /* Comment. */ if (out) { memcpy (out, comment, comment_length); out += comment_length; } else out_len += comment_length; break; case 'F': /* SSH style fingerprint. */ if (!ssh_fpr && key) ssh_get_fingerprint_string (key, &ssh_fpr); if (ssh_fpr) { if (out) out = stpcpy (out, ssh_fpr); else out_len += strlen (ssh_fpr); } break; default: /* Invalid special sequences are kept as they are. */ if (out) { *out++ = '%'; *out++ = in[i]; } else out_len+=2; break; } } else if (in[i] == '%') special = 1; else { if (out) *out++ = in[i]; else out_len++; } } if (!pass) { *result = out = xtrymalloc (out_len + 1); if (!out) { xfree (ssh_fpr); return gpg_error_from_syserror (); } } } *out = 0; assert (*result + out_len == out); xfree (ssh_fpr); return 0; }
char * xheader_format_name (struct tar_stat_info *st, const char *fmt, size_t n) { char *buf; size_t len = strlen (fmt); char *q; const char *p; char *dirp = NULL; char *dir = NULL; char *base = NULL; char pidbuf[UINTMAX_STRSIZE_BOUND]; char const *pptr = NULL; char nbuf[UINTMAX_STRSIZE_BOUND]; char const *nptr = NULL; for (p = fmt; *p && (p = strchr (p, '%')); ) { switch (p[1]) { case '%': len--; break; case 'd': if (st) { if (!dirp) dirp = dir_name (st->orig_file_name); dir = safer_name_suffix (dirp, false, absolute_names_option); len += strlen (dir) - 2; } break; case 'f': if (st) { base = last_component (st->orig_file_name); len += strlen (base) - 2; } break; case 'p': pptr = umaxtostr (getpid (), pidbuf); len += pidbuf + sizeof pidbuf - 1 - pptr - 2; break; case 'n': nptr = umaxtostr (n, nbuf); len += nbuf + sizeof nbuf - 1 - nptr - 2; break; } p++; } buf = xmalloc (len + 1); for (q = buf, p = fmt; *p; ) { if (*p == '%') { switch (p[1]) { case '%': *q++ = *p++; p++; break; case 'd': if (dir) q = stpcpy (q, dir); p += 2; break; case 'f': if (base) q = stpcpy (q, base); p += 2; break; case 'p': q = stpcpy (q, pptr); p += 2; break; case 'n': q = stpcpy (q, nptr); p += 2; break; default: *q++ = *p++; if (*p) *q++ = *p++; } } else *q++ = *p++; } free (dirp); /* Do not allow it to end in a slash */ while (q > buf && ISSLASH (q[-1])) q--; *q = 0; return buf; }
static gpgme_error_t uiserver_sign (void *engine, gpgme_data_t in, gpgme_data_t out, gpgme_sig_mode_t mode, int use_armor, int use_textmode, int include_certs, gpgme_ctx_t ctx /* FIXME */) { engine_uiserver_t uiserver = engine; gpgme_error_t err = 0; const char *protocol; char *cmd; gpgme_key_t key; if (!uiserver || !in || !out) return gpg_error (GPG_ERR_INV_VALUE); if (uiserver->protocol == GPGME_PROTOCOL_DEFAULT) protocol = ""; else if (uiserver->protocol == GPGME_PROTOCOL_OpenPGP) protocol = " --protocol=OpenPGP"; else if (uiserver->protocol == GPGME_PROTOCOL_CMS) protocol = " --protocol=CMS"; else return gpgme_error (GPG_ERR_UNSUPPORTED_PROTOCOL); if (asprintf (&cmd, "SIGN%s%s", protocol, (mode == GPGME_SIG_MODE_DETACH) ? " --detached" : "") < 0) return gpg_error_from_errno (errno); key = gpgme_signers_enum (ctx, 0); if (key) { const char *s = NULL; if (key && key->uids) s = key->uids->email; if (s && strlen (s) < 80) { char buf[100]; strcpy (stpcpy (buf, "SENDER --info "), s); err = uiserver_assuan_simple_command (uiserver->assuan_ctx, buf, uiserver->status.fnc, uiserver->status.fnc_value); } else err = gpg_error (GPG_ERR_INV_VALUE); gpgme_key_unref (key); if (err) { free (cmd); return err; } } uiserver->input_cb.data = in; err = uiserver_set_fd (uiserver, INPUT_FD, map_data_enc (uiserver->input_cb.data)); if (err) { free (cmd); return err; } uiserver->output_cb.data = out; err = uiserver_set_fd (uiserver, OUTPUT_FD, use_armor ? "--armor" : map_data_enc (uiserver->output_cb.data)); if (err) { free (cmd); return err; } uiserver->inline_data = NULL; err = start (uiserver, cmd); free (cmd); return err; }
void nis_print_group_entry (const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 50]; char leafbuf[grouplen + 3]; char domainbuf[grouplen + 3]; nis_result *res; char *cp, *cp2; u_int i; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME); if (res == NULL) return; if (NIS_RES_STATUS (res) != NIS_SUCCESS || NIS_RES_NUMOBJ (res) != 1 || __type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ) { nis_freeresult (res); return; } char *mem_exp[NIS_RES_NUMOBJ (res)]; char *mem_imp[NIS_RES_NUMOBJ (res)]; char *mem_rec[NIS_RES_NUMOBJ (res)]; char *nomem_exp[NIS_RES_NUMOBJ (res)]; char *nomem_imp[NIS_RES_NUMOBJ (res)]; char *nomem_rec[NIS_RES_NUMOBJ (res)]; unsigned long mem_exp_cnt = 0, mem_imp_cnt = 0, mem_rec_cnt = 0; unsigned long nomem_exp_cnt = 0, nomem_imp_cnt = 0, nomem_rec_cnt = 0; for (i = 0; i < NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; ++i) { char *grmem = NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val[i]; int neg = grmem[0] == '-'; switch (grmem[neg]) { case '*': if (neg) { nomem_imp[nomem_imp_cnt] = grmem; ++nomem_imp_cnt; } else { mem_imp[mem_imp_cnt] = grmem; ++mem_imp_cnt; } break; case '@': if (neg) { nomem_rec[nomem_rec_cnt] = grmem; ++nomem_rec_cnt; } else { mem_rec[mem_rec_cnt] = grmem; ++mem_rec_cnt; } break; default: if (neg) { nomem_exp[nomem_exp_cnt] = grmem; ++nomem_exp_cnt; } else { mem_exp[mem_exp_cnt] = grmem; ++mem_exp_cnt; } break; } } { char buf[strlen (NIS_RES_OBJECT (res)->zo_domain) + 10]; printf (_("Group entry for \"%s.%s\" group:\n"), NIS_RES_OBJECT (res)->zo_name, nis_domain_of_r (NIS_RES_OBJECT (res)->zo_domain, buf, strlen (NIS_RES_OBJECT (res)->zo_domain) + 10)); } if (mem_exp_cnt) { fputs (_(" Explicit members:\n"), stdout); for (i = 0; i < mem_exp_cnt; ++i) printf ("\t%s\n", mem_exp[i]); } else fputs (_(" No explicit members\n"), stdout); if (mem_imp_cnt) { fputs (_(" Implicit members:\n"), stdout); for (i = 0; i < mem_imp_cnt; ++i) printf ("\t%s\n", &mem_imp[i][2]); } else fputs (_(" No implicit members\n"), stdout); if (mem_rec_cnt) { fputs (_(" Recursive members:\n"), stdout); for (i = 0; i < mem_rec_cnt; ++i) printf ("\t%s\n", &mem_rec[i][1]); } else fputs (_(" No recursive members\n"), stdout); if (nomem_exp_cnt) { fputs (_(" Explicit nonmembers:\n"), stdout); for (i = 0; i < nomem_exp_cnt; ++i) printf ("\t%s\n", &nomem_exp[i][1]); } else fputs (_(" No explicit nonmembers\n"), stdout); if (nomem_imp_cnt) { fputs (_(" Implicit nonmembers:\n"), stdout); for (i = 0; i < nomem_imp_cnt; ++i) printf ("\t%s\n", &nomem_imp[i][3]); } else fputs (_(" No implicit nonmembers\n"), stdout); if (nomem_rec_cnt) { fputs (_(" Recursive nonmembers:\n"), stdout); for (i = 0; i < nomem_rec_cnt; ++i) printf ("\t%s=n", &nomem_rec[i][2]); } else fputs (_(" No recursive nonmembers\n"), stdout); nis_freeresult (res); } }
/** * assuan_inquire: * @ctx: An assuan context * @keyword: The keyword used for the inquire * @r_buffer: Returns an allocated buffer * @r_length: Returns the length of this buffer * @maxlen: If not 0, the size limit of the inquired data. * * A Server may use this to Send an inquire. r_buffer, r_length and * maxlen may all be NULL/0 to indicate that no real data is expected. * * Return value: 0 on success or an ASSUAN error code **/ gpg_error_t assuan_inquire (assuan_context_t ctx, const char *keyword, unsigned char **r_buffer, size_t *r_length, size_t maxlen) { gpg_error_t rc; struct membuf mb; char cmdbuf[LINELENGTH-10]; /* (10 = strlen ("INQUIRE ")+CR,LF) */ unsigned char *line, *p; int linelen; int nodataexpected; if (!ctx || !keyword || (10 + strlen (keyword) >= sizeof (cmdbuf))) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); nodataexpected = !r_buffer && !r_length && !maxlen; if (!nodataexpected && (!r_buffer || !r_length)) return _assuan_error (ctx, GPG_ERR_ASS_INV_VALUE); if (!ctx->is_server) return _assuan_error (ctx, GPG_ERR_ASS_NOT_A_SERVER); if (ctx->in_inquire) return _assuan_error (ctx, GPG_ERR_ASS_NESTED_COMMANDS); ctx->in_inquire = 1; if (nodataexpected) memset (&mb, 0, sizeof mb); /* avoid compiler warnings */ else init_membuf (ctx, &mb, maxlen? maxlen:1024, maxlen); strcpy (stpcpy (cmdbuf, "INQUIRE "), keyword); rc = assuan_write_line (ctx, cmdbuf); if (rc) goto out; for (;;) { do { do rc = _assuan_read_line (ctx); while (_assuan_error_is_eagain (ctx, rc)); if (rc) goto out; line = (unsigned char *) ctx->inbound.line; linelen = ctx->inbound.linelen; } while (*line == '#' || !linelen); /* Note: As a convenience for manual testing we allow case insensitive keywords. */ if ((line[0] == 'E'||line[0] == 'e') && (line[1] == 'N' || line[1] == 'n') && (line[2] == 'D' || line[2] == 'd') && (!line[3] || line[3] == ' ')) break; /* END command received*/ if ((line[0] == 'C' || line[0] == 'c') && (line[1] == 'A' || line[1] == 'a') && (line[2] == 'N' || line[2] == 'n')) { rc = _assuan_error (ctx, GPG_ERR_ASS_CANCELED); goto out; } if ((line[0] != 'D' && line[0] != 'd') || line[1] != ' ' || nodataexpected) { rc = _assuan_error (ctx, GPG_ERR_ASS_UNEXPECTED_CMD); goto out; } if (linelen < 3) continue; line += 2; linelen -= 2; p = line; while (linelen) { for (;linelen && *p != '%'; linelen--, p++) ; put_membuf (ctx, &mb, line, p-line); if (linelen > 2) { /* handle escaping */ unsigned char tmp[1]; p++; *tmp = xtoi_2 (p); p += 2; linelen -= 3; put_membuf (ctx, &mb, tmp, 1); } line = p; } if (mb.too_large) { rc = _assuan_error (ctx, GPG_ERR_ASS_TOO_MUCH_DATA); goto out; } } if (!nodataexpected) { *r_buffer = get_membuf (ctx, &mb, r_length); if (!*r_buffer) rc = _assuan_error (ctx, gpg_err_code_from_syserror ()); } out: if (!nodataexpected) free_membuf (ctx, &mb); ctx->in_inquire = 0; return rc; }
static int process_root_password(void) { static const char table[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "./"; struct spwd item = { .sp_namp = (char*) "root", .sp_min = -1, .sp_max = -1, .sp_warn = -1, .sp_inact = -1, .sp_expire = -1, .sp_flag = (unsigned long) -1, /* this appears to be what everybody does ... */ }; _cleanup_close_ int lock = -1; char salt[3+16+1+1]; uint8_t raw[16]; unsigned i; char *j; const char *etc_shadow; int r; etc_shadow = prefix_roota(arg_root, "/etc/shadow"); if (faccessat(AT_FDCWD, etc_shadow, F_OK, AT_SYMLINK_NOFOLLOW) >= 0) return 0; mkdir_parents(etc_shadow, 0755); lock = take_password_lock(arg_root); if (lock < 0) return lock; if (arg_copy_root_password && arg_root) { struct spwd *p; errno = 0; p = getspnam("root"); if (p || errno != ENOENT) { if (!p) { if (!errno) errno = EIO; log_error_errno(errno, "Failed to find shadow entry for root: %m"); return -errno; } r = write_root_shadow(etc_shadow, p); if (r < 0) return log_error_errno(r, "Failed to write %s: %m", etc_shadow); log_info("%s copied.", etc_shadow); return 0; } } r = prompt_root_password(); if (r < 0) return r; if (!arg_root_password) return 0; r = dev_urandom(raw, 16); if (r < 0) return log_error_errno(r, "Failed to get salt: %m"); /* We only bother with SHA512 hashed passwords, the rest is legacy, and we don't do legacy. */ assert_cc(sizeof(table) == 64 + 1); j = stpcpy(salt, "$6$"); for (i = 0; i < 16; i++) j[i] = table[raw[i] & 63]; j[i++] = '$'; j[i] = 0; errno = 0; item.sp_pwdp = crypt(arg_root_password, salt); if (!item.sp_pwdp) { if (!errno) errno = -EINVAL; log_error_errno(errno, "Failed to encrypt password: %m"); return -errno; } item.sp_lstchg = (long) (now(CLOCK_REALTIME) / USEC_PER_DAY); r = write_root_shadow(etc_shadow, &item); if (r < 0) return log_error_errno(r, "Failed to write %s: %m", etc_shadow); log_info("%s written.", etc_shadow); return 0; } static void help(void) { printf("%s [OPTIONS...]\n\n" "Configures basic settings of the system.\n\n" " -h --help Show this help\n" " --version Show package version\n" " --root=PATH Operate on an alternate filesystem root\n" " --locale=LOCALE Set primary locale (LANG=)\n" " --locale-messages=LOCALE Set message locale (LC_MESSAGES=)\n" " --timezone=TIMEZONE Set timezone\n" " --hostname=NAME Set host name\n" " --machine-ID=ID Set machine ID\n" " --root-password=PASSWORD Set root password\n" " --root-password-file=FILE Set root password from file\n" " --prompt-locale Prompt the user for locale settings\n" " --prompt-timezone Prompt the user for timezone\n" " --prompt-hostname Prompt the user for hostname\n" " --prompt-root-password Prompt the user for root password\n" " --prompt Prompt for all of the above\n" " --copy-locale Copy locale from host\n" " --copy-timezone Copy timezone from host\n" " --copy-root-password Copy root password from host\n" " --copy Copy locale, timezone, root password\n" " --setup-machine-id Generate a new random machine ID\n" , program_invocation_short_name); }
int main(int argc, char* argv[]) { struct option longopts[] = { { "force", no_argument, 0, 'f' }, { "interactive", no_argument, 0, 'i' }, { "recursive", no_argument, 0, 'R' }, { "help", no_argument, 0, 0 }, { "version", no_argument, 0, 1 }, { 0, 0, 0, 0 } }; bool force = false; bool prompt = false; bool recursive = false; int c; while ((c = getopt_long(argc, argv, "fiRr", longopts, NULL)) != -1) { switch (c) { case 0: return help(argv[0], "[OPTIONS] SOURCE... DESTINATION\n" " -f, --force force copy\n" " -i, --interactive prompt before overwrite\n" " -R, -r, --recursive recursively copy directories\n" " --help display this help\n" " --version display version info"); case 1: return version(argv[0]); case 'f': force = true; prompt = false; break; case 'i': force = false; prompt = true; break; case 'r': case 'R': recursive = true; break; case '?': return 1; } } if (optind >= argc) errx(1, "missing source operand"); if (optind == argc - 1) errx(1, "missing destination operand"); const char* destination = argv[argc - 1]; if (optind == argc - 2) { struct stat destSt; int statResult = stat(destination, &destSt); if (statResult < 0 && errno != ENOENT) { err(1, "stat: '%s'", destination); } else if ((statResult < 0 && errno == ENOENT) || !S_ISDIR(destSt.st_mode)) { copy(AT_FDCWD, argv[optind], argv[optind], AT_FDCWD, destination, destination, force, prompt, recursive); return status; } } int destFd = open(destination, O_SEARCH | O_DIRECTORY); if (destFd < 0) err(1, "open: '%s'", destination); for (int i = optind; i < argc - 1; i++) { const char* source = argv[i]; char* sourceCopy = strdup(source); if (!sourceCopy) err(1, "strdup"); char* destName = basename(sourceCopy); if (strcmp(destName, "/") == 0) { destName = "."; } char* destPath = malloc(strlen(destination) + strlen(destName) + 2); if (!destPath) err(1, "malloc"); stpcpy(stpcpy(stpcpy(destPath, destination), "/"), destName); copy(AT_FDCWD, source, source, destFd, destName, destPath, force, prompt, recursive); free(sourceCopy); free(destPath); } }
static int do_test (void) { struct sigaction sa; sa.sa_handler = handler; sa.sa_flags = 0; sigemptyset (&sa.sa_mask); sigaction (SIGABRT, &sa, NULL); /* Avoid all the buffer overflow messages on stderr. */ int fd = open (_PATH_DEVNULL, O_WRONLY); if (fd == -1) close (STDERR_FILENO); else { dup2 (fd, STDERR_FILENO); close (fd); } setenv ("LIBC_FATAL_STDERR_", "1", 1); struct A { char buf1[9]; char buf2[1]; } a; struct wA { wchar_t buf1[9]; wchar_t buf2[1]; } wa; printf ("Test checking routines at fortify level %d\n", #ifdef __USE_FORTIFY_LEVEL (int) __USE_FORTIFY_LEVEL #else 0 #endif ); /* These ops can be done without runtime checking of object size. */ memcpy (buf, "abcdefghij", 10); memmove (buf + 1, buf, 9); if (memcmp (buf, "aabcdefghi", 10)) FAIL (); if (mempcpy (buf + 5, "abcde", 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10)) FAIL (); memset (buf + 8, 'j', 2); if (memcmp (buf, "aabcdabcjj", 10)) FAIL (); strcpy (buf + 4, "EDCBA"); if (memcmp (buf, "aabcEDCBA", 10)) FAIL (); if (stpcpy (buf + 8, "F") != buf + 9 || memcmp (buf, "aabcEDCBF", 10)) FAIL (); strncpy (buf + 6, "X", 4); if (memcmp (buf, "aabcEDX\0\0", 10)) FAIL (); if (sprintf (buf + 7, "%s", "67") != 2 || memcmp (buf, "aabcEDX67", 10)) FAIL (); if (snprintf (buf + 7, 3, "%s", "987654") != 6 || memcmp (buf, "aabcEDX98", 10)) FAIL (); /* These ops need runtime checking, but shouldn't __chk_fail. */ memcpy (buf, "abcdefghij", l0 + 10); memmove (buf + 1, buf, l0 + 9); if (memcmp (buf, "aabcdefghi", 10)) FAIL (); if (mempcpy (buf + 5, "abcde", l0 + 5) != buf + 10 || memcmp (buf, "aabcdabcde", 10)) FAIL (); memset (buf + 8, 'j', l0 + 2); if (memcmp (buf, "aabcdabcjj", 10)) FAIL (); strcpy (buf + 4, str1 + 5); if (memcmp (buf, "aabcEDCBA", 10)) FAIL (); if (stpcpy (buf + 8, str2) != buf + 9 || memcmp (buf, "aabcEDCBF", 10)) FAIL (); strncpy (buf + 6, "X", l0 + 4); if (memcmp (buf, "aabcEDX\0\0", 10)) FAIL (); if (stpncpy (buf + 5, "cd", l0 + 5) != buf + 7 || memcmp (buf, "aabcEcd\0\0", 10)) FAIL (); if (sprintf (buf + 7, "%d", num1) != 2 || memcmp (buf, "aabcEcd67", 10)) FAIL (); if (snprintf (buf + 7, 3, "%d", num2) != 6 || memcmp (buf, "aabcEcd98", 10)) FAIL (); buf[l0 + 8] = '\0'; strcat (buf, "A"); if (memcmp (buf, "aabcEcd9A", 10)) FAIL (); buf[l0 + 7] = '\0'; strncat (buf, "ZYXWV", l0 + 2); if (memcmp (buf, "aabcEcdZY", 10)) FAIL (); memcpy (a.buf1, "abcdefghij", l0 + 10); memmove (a.buf1 + 1, a.buf1, l0 + 9); if (memcmp (a.buf1, "aabcdefghi", 10)) FAIL (); if (mempcpy (a.buf1 + 5, "abcde", l0 + 5) != a.buf1 + 10 || memcmp (a.buf1, "aabcdabcde", 10)) FAIL (); memset (a.buf1 + 8, 'j', l0 + 2); if (memcmp (a.buf1, "aabcdabcjj", 10)) FAIL (); #if __USE_FORTIFY_LEVEL < 2 /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 and sufficient GCC support, as the string operations overflow from a.buf1 into a.buf2. */ strcpy (a.buf1 + 4, str1 + 5); if (memcmp (a.buf1, "aabcEDCBA", 10)) FAIL (); if (stpcpy (a.buf1 + 8, str2) != a.buf1 + 9 || memcmp (a.buf1, "aabcEDCBF", 10)) FAIL (); strncpy (a.buf1 + 6, "X", l0 + 4); if (memcmp (a.buf1, "aabcEDX\0\0", 10)) FAIL (); if (sprintf (a.buf1 + 7, "%d", num1) != 2 || memcmp (a.buf1, "aabcEDX67", 10)) FAIL (); if (snprintf (a.buf1 + 7, 3, "%d", num2) != 6 || memcmp (a.buf1, "aabcEDX98", 10)) FAIL (); a.buf1[l0 + 8] = '\0'; strcat (a.buf1, "A"); if (memcmp (a.buf1, "aabcEDX9A", 10)) FAIL (); a.buf1[l0 + 7] = '\0'; strncat (a.buf1, "ZYXWV", l0 + 2); if (memcmp (a.buf1, "aabcEDXZY", 10)) FAIL (); #endif #if __USE_FORTIFY_LEVEL >= 1 /* Now check if all buffer overflows are caught at runtime. */ CHK_FAIL_START memcpy (buf + 1, "abcdefghij", l0 + 10); CHK_FAIL_END CHK_FAIL_START memmove (buf + 2, buf + 1, l0 + 9); CHK_FAIL_END CHK_FAIL_START p = mempcpy (buf + 6, "abcde", l0 + 5); CHK_FAIL_END CHK_FAIL_START memset (buf + 9, 'j', l0 + 2); CHK_FAIL_END CHK_FAIL_START strcpy (buf + 5, str1 + 5); CHK_FAIL_END CHK_FAIL_START p = stpcpy (buf + 9, str2); CHK_FAIL_END CHK_FAIL_START strncpy (buf + 7, "X", l0 + 4); CHK_FAIL_END CHK_FAIL_START stpncpy (buf + 6, "cd", l0 + 5); CHK_FAIL_END CHK_FAIL_START sprintf (buf + 8, "%d", num1); CHK_FAIL_END CHK_FAIL_START snprintf (buf + 8, l0 + 3, "%d", num2); CHK_FAIL_END memcpy (buf, str1 + 2, l0 + 9); CHK_FAIL_START strcat (buf, "AB"); CHK_FAIL_END memcpy (buf, str1 + 3, l0 + 8); CHK_FAIL_START strncat (buf, "ZYXWV", l0 + 3); CHK_FAIL_END CHK_FAIL_START memcpy (a.buf1 + 1, "abcdefghij", l0 + 10); CHK_FAIL_END CHK_FAIL_START memmove (a.buf1 + 2, a.buf1 + 1, l0 + 9); CHK_FAIL_END CHK_FAIL_START p = mempcpy (a.buf1 + 6, "abcde", l0 + 5); CHK_FAIL_END CHK_FAIL_START memset (a.buf1 + 9, 'j', l0 + 2); CHK_FAIL_END #if __USE_FORTIFY_LEVEL >= 2 # define O 0 #else # define O 1 #endif CHK_FAIL_START strcpy (a.buf1 + (O + 4), str1 + 5); CHK_FAIL_END CHK_FAIL_START p = stpcpy (a.buf1 + (O + 8), str2); CHK_FAIL_END CHK_FAIL_START strncpy (a.buf1 + (O + 6), "X", l0 + 4); CHK_FAIL_END CHK_FAIL_START sprintf (a.buf1 + (O + 7), "%d", num1); CHK_FAIL_END CHK_FAIL_START snprintf (a.buf1 + (O + 7), l0 + 3, "%d", num2); CHK_FAIL_END memcpy (a.buf1, str1 + (3 - O), l0 + 8 + O); CHK_FAIL_START strcat (a.buf1, "AB"); CHK_FAIL_END memcpy (a.buf1, str1 + (4 - O), l0 + 7 + O); CHK_FAIL_START strncat (a.buf1, "ZYXWV", l0 + 3); CHK_FAIL_END #endif /* These ops can be done without runtime checking of object size. */ wmemcpy (wbuf, L"abcdefghij", 10); wmemmove (wbuf + 1, wbuf, 9); if (wmemcmp (wbuf, L"aabcdefghi", 10)) FAIL (); if (wmempcpy (wbuf + 5, L"abcde", 5) != wbuf + 10 || wmemcmp (wbuf, L"aabcdabcde", 10)) FAIL (); wmemset (wbuf + 8, L'j', 2); if (wmemcmp (wbuf, L"aabcdabcjj", 10)) FAIL (); wcscpy (wbuf + 4, L"EDCBA"); if (wmemcmp (wbuf, L"aabcEDCBA", 10)) FAIL (); if (wcpcpy (wbuf + 8, L"F") != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10)) FAIL (); wcsncpy (wbuf + 6, L"X", 4); if (wmemcmp (wbuf, L"aabcEDX\0\0", 10)) FAIL (); if (swprintf (wbuf + 7, 3, L"%ls", L"987654") >= 0 || wmemcmp (wbuf, L"aabcEDX98", 10)) FAIL (); if (swprintf (wbuf + 7, 3, L"64") != 2 || wmemcmp (wbuf, L"aabcEDX64", 10)) FAIL (); /* These ops need runtime checking, but shouldn't __chk_fail. */ wmemcpy (wbuf, L"abcdefghij", l0 + 10); wmemmove (wbuf + 1, wbuf, l0 + 9); if (wmemcmp (wbuf, L"aabcdefghi", 10)) FAIL (); if (wmempcpy (wbuf + 5, L"abcde", l0 + 5) != wbuf + 10 || wmemcmp (wbuf, L"aabcdabcde", 10)) FAIL (); wmemset (wbuf + 8, L'j', l0 + 2); if (wmemcmp (wbuf, L"aabcdabcjj", 10)) FAIL (); wcscpy (wbuf + 4, wstr1 + 5); if (wmemcmp (wbuf, L"aabcEDCBA", 10)) FAIL (); if (wcpcpy (wbuf + 8, wstr2) != wbuf + 9 || wmemcmp (wbuf, L"aabcEDCBF", 10)) FAIL (); wcsncpy (wbuf + 6, L"X", l0 + 4); if (wmemcmp (wbuf, L"aabcEDX\0\0", 10)) FAIL (); if (wcpncpy (wbuf + 5, L"cd", l0 + 5) != wbuf + 7 || wmemcmp (wbuf, L"aabcEcd\0\0", 10)) FAIL (); if (swprintf (wbuf + 7, 3, L"%d", num2) >= 0 || wmemcmp (wbuf, L"aabcEcd98", 10)) FAIL (); wbuf[l0 + 8] = L'\0'; wcscat (wbuf, L"A"); if (wmemcmp (wbuf, L"aabcEcd9A", 10)) FAIL (); wbuf[l0 + 7] = L'\0'; wcsncat (wbuf, L"ZYXWV", l0 + 2); if (wmemcmp (wbuf, L"aabcEcdZY", 10)) FAIL (); wmemcpy (wa.buf1, L"abcdefghij", l0 + 10); wmemmove (wa.buf1 + 1, wa.buf1, l0 + 9); if (wmemcmp (wa.buf1, L"aabcdefghi", 10)) FAIL (); if (wmempcpy (wa.buf1 + 5, L"abcde", l0 + 5) != wa.buf1 + 10 || wmemcmp (wa.buf1, L"aabcdabcde", 10)) FAIL (); wmemset (wa.buf1 + 8, L'j', l0 + 2); if (wmemcmp (wa.buf1, L"aabcdabcjj", 10)) FAIL (); #if __USE_FORTIFY_LEVEL < 2 /* The following tests are supposed to crash with -D_FORTIFY_SOURCE=2 and sufficient GCC support, as the string operations overflow from a.buf1 into a.buf2. */ wcscpy (wa.buf1 + 4, wstr1 + 5); if (wmemcmp (wa.buf1, L"aabcEDCBA", 10)) FAIL (); if (wcpcpy (wa.buf1 + 8, wstr2) != wa.buf1 + 9 || wmemcmp (wa.buf1, L"aabcEDCBF", 10)) FAIL (); wcsncpy (wa.buf1 + 6, L"X", l0 + 4); if (wmemcmp (wa.buf1, L"aabcEDX\0\0", 10)) FAIL (); if (swprintf (wa.buf1 + 7, 3, L"%d", num2) >= 0 || wmemcmp (wa.buf1, L"aabcEDX98", 10)) FAIL (); wa.buf1[l0 + 8] = L'\0'; wcscat (wa.buf1, L"A"); if (wmemcmp (wa.buf1, L"aabcEDX9A", 10)) FAIL (); wa.buf1[l0 + 7] = L'\0'; wcsncat (wa.buf1, L"ZYXWV", l0 + 2); if (wmemcmp (wa.buf1, L"aabcEDXZY", 10)) FAIL (); #endif #if __USE_FORTIFY_LEVEL >= 1 /* Now check if all buffer overflows are caught at runtime. */ CHK_FAIL_START wmemcpy (wbuf + 1, L"abcdefghij", l0 + 10); CHK_FAIL_END CHK_FAIL_START wmemmove (wbuf + 2, wbuf + 1, l0 + 9); CHK_FAIL_END CHK_FAIL_START wp = wmempcpy (wbuf + 6, L"abcde", l0 + 5); CHK_FAIL_END CHK_FAIL_START wmemset (wbuf + 9, L'j', l0 + 2); CHK_FAIL_END CHK_FAIL_START wcscpy (wbuf + 5, wstr1 + 5); CHK_FAIL_END CHK_FAIL_START wp = wcpcpy (wbuf + 9, wstr2); CHK_FAIL_END CHK_FAIL_START wcsncpy (wbuf + 7, L"X", l0 + 4); CHK_FAIL_END CHK_FAIL_START wcpncpy (wbuf + 6, L"cd", l0 + 5); CHK_FAIL_END wmemcpy (wbuf, wstr1 + 2, l0 + 9); CHK_FAIL_START wcscat (wbuf, L"AB"); CHK_FAIL_END wmemcpy (wbuf, wstr1 + 3, l0 + 8); CHK_FAIL_START wcsncat (wbuf, L"ZYXWV", l0 + 3); CHK_FAIL_END CHK_FAIL_START wmemcpy (wa.buf1 + 1, L"abcdefghij", l0 + 10); CHK_FAIL_END CHK_FAIL_START wmemmove (wa.buf1 + 2, wa.buf1 + 1, l0 + 9); CHK_FAIL_END CHK_FAIL_START wp = wmempcpy (wa.buf1 + 6, L"abcde", l0 + 5); CHK_FAIL_END CHK_FAIL_START wmemset (wa.buf1 + 9, L'j', l0 + 2); CHK_FAIL_END #if __USE_FORTIFY_LEVEL >= 2 # define O 0 #else # define O 1 #endif CHK_FAIL_START wcscpy (wa.buf1 + (O + 4), wstr1 + 5); CHK_FAIL_END CHK_FAIL_START wp = wcpcpy (wa.buf1 + (O + 8), wstr2); CHK_FAIL_END CHK_FAIL_START wcsncpy (wa.buf1 + (O + 6), L"X", l0 + 4); CHK_FAIL_END wmemcpy (wa.buf1, wstr1 + (3 - O), l0 + 8 + O); CHK_FAIL_START wcscat (wa.buf1, L"AB"); CHK_FAIL_END wmemcpy (wa.buf1, wstr1 + (4 - O), l0 + 7 + O); CHK_FAIL_START wcsncat (wa.buf1, L"ZYXWV", l0 + 3); CHK_FAIL_END #endif /* Now checks for %n protection. */ /* Constant literals passed directly are always ok (even with warnings about possible bugs from GCC). */ int n1, n2; if (sprintf (buf, "%s%n%s%n", str2, &n1, str2, &n2) != 2 || n1 != 1 || n2 != 2) FAIL (); /* In this case the format string is not known at compile time, but resides in read-only memory, so is ok. */ if (snprintf (buf, 4, str3, str2, &n1, str2, &n2) != 2 || n1 != 1 || n2 != 2) FAIL (); strcpy (buf2 + 2, "%n%s%n"); /* When the format string is writable and contains %n, with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ CHK_FAIL2_START if (sprintf (buf, buf2, str2, &n1, str2, &n1) != 2) FAIL (); CHK_FAIL2_END CHK_FAIL2_START if (snprintf (buf, 3, buf2, str2, &n1, str2, &n1) != 2) FAIL (); CHK_FAIL2_END /* But if there is no %n, even writable format string should work. */ buf2[6] = '\0'; if (sprintf (buf, buf2 + 4, str2) != 1) FAIL (); /* Constant literals passed directly are always ok (even with warnings about possible bugs from GCC). */ if (printf ("%s%n%s%n", str4, &n1, str5, &n2) != 14 || n1 != 7 || n2 != 14) FAIL (); /* In this case the format string is not known at compile time, but resides in read-only memory, so is ok. */ if (printf (str3, str4, &n1, str5, &n2) != 14 || n1 != 7 || n2 != 14) FAIL (); strcpy (buf2 + 2, "%n%s%n"); /* When the format string is writable and contains %n, with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ CHK_FAIL2_START if (printf (buf2, str4, &n1, str5, &n1) != 14) FAIL (); CHK_FAIL2_END /* But if there is no %n, even writable format string should work. */ buf2[6] = '\0'; if (printf (buf2 + 4, str5) != 7) FAIL (); FILE *fp = stdout; /* Constant literals passed directly are always ok (even with warnings about possible bugs from GCC). */ if (fprintf (fp, "%s%n%s%n", str4, &n1, str5, &n2) != 14 || n1 != 7 || n2 != 14) FAIL (); /* In this case the format string is not known at compile time, but resides in read-only memory, so is ok. */ if (fprintf (fp, str3, str4, &n1, str5, &n2) != 14 || n1 != 7 || n2 != 14) FAIL (); strcpy (buf2 + 2, "%n%s%n"); /* When the format string is writable and contains %n, with -D_FORTIFY_SOURCE=2 it causes __chk_fail. */ CHK_FAIL2_START if (fprintf (fp, buf2, str4, &n1, str5, &n1) != 14) FAIL (); CHK_FAIL2_END /* But if there is no %n, even writable format string should work. */ buf2[6] = '\0'; if (fprintf (fp, buf2 + 4, str5) != 7) FAIL (); if (freopen (temp_filename, "r", stdin) == NULL) { puts ("could not open temporary file"); exit (1); } if (gets (buf) != buf || memcmp (buf, "abcdefgh", 9)) FAIL (); if (gets (buf) != buf || memcmp (buf, "ABCDEFGHI", 10)) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (gets (buf) != buf) FAIL (); CHK_FAIL_END #endif rewind (stdin); if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "abcdefgh\n", 10)) FAIL (); if (fgets (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) FAIL (); rewind (stdin); if (fgets (buf, l0 + sizeof (buf), stdin) != buf || memcmp (buf, "abcdefgh\n", 10)) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (fgets (buf, sizeof (buf) + 1, stdin) != buf) FAIL (); CHK_FAIL_END CHK_FAIL_START if (fgets (buf, l0 + sizeof (buf) + 1, stdin) != buf) FAIL (); CHK_FAIL_END #endif rewind (stdin); if (fgets_unlocked (buf, sizeof (buf), stdin) != buf || memcmp (buf, "abcdefgh\n", 10)) FAIL (); if (fgets_unlocked (buf, sizeof (buf), stdin) != buf || memcmp (buf, "ABCDEFGHI", 10)) FAIL (); rewind (stdin); if (fgets_unlocked (buf, l0 + sizeof (buf), stdin) != buf || memcmp (buf, "abcdefgh\n", 10)) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (fgets_unlocked (buf, sizeof (buf) + 1, stdin) != buf) FAIL (); CHK_FAIL_END CHK_FAIL_START if (fgets_unlocked (buf, l0 + sizeof (buf) + 1, stdin) != buf) FAIL (); CHK_FAIL_END #endif lseek (fileno (stdin), 0, SEEK_SET); if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 || memcmp (buf, "abcdefgh\n", 9)) FAIL (); if (read (fileno (stdin), buf, sizeof (buf) - 1) != sizeof (buf) - 1 || memcmp (buf, "ABCDEFGHI", 9)) FAIL (); lseek (fileno (stdin), 0, SEEK_SET); if (read (fileno (stdin), buf, l0 + sizeof (buf) - 1) != sizeof (buf) - 1 || memcmp (buf, "abcdefgh\n", 9)) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (read (fileno (stdin), buf, sizeof (buf) + 1) != sizeof (buf) + 1) FAIL (); CHK_FAIL_END #endif if (pread (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) != sizeof (buf) - 1 || memcmp (buf, "\nABCDEFGH", 9)) FAIL (); if (pread (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 || memcmp (buf, "abcdefgh\n", 9)) FAIL (); if (pread (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) != sizeof (buf) - 1 || memcmp (buf, "h\nABCDEFG", 9)) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (pread (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) != sizeof (buf) + 1) FAIL (); CHK_FAIL_END #endif if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, sizeof (buf) - 2) != sizeof (buf) - 1 || memcmp (buf, "\nABCDEFGH", 9)) FAIL (); if (pread64 (fileno (stdin), buf, sizeof (buf) - 1, 0) != sizeof (buf) - 1 || memcmp (buf, "abcdefgh\n", 9)) FAIL (); if (pread64 (fileno (stdin), buf, l0 + sizeof (buf) - 1, sizeof (buf) - 3) != sizeof (buf) - 1 || memcmp (buf, "h\nABCDEFG", 9)) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (pread64 (fileno (stdin), buf, sizeof (buf) + 1, 2 * sizeof (buf)) != sizeof (buf) + 1) FAIL (); CHK_FAIL_END #endif if (freopen (temp_filename, "r", stdin) == NULL) { puts ("could not open temporary file"); exit (1); } if (fseek (stdin, 9 + 10 + 11, SEEK_SET)) { puts ("could not seek in test file"); exit (1); } #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (gets (buf) != buf) FAIL (); CHK_FAIL_END #endif /* Check whether missing N$ formats are detected. */ CHK_FAIL2_START printf ("%3$d\n", 1, 2, 3, 4); CHK_FAIL2_END CHK_FAIL2_START fprintf (stdout, "%3$d\n", 1, 2, 3, 4); CHK_FAIL2_END CHK_FAIL2_START sprintf (buf, "%3$d\n", 1, 2, 3, 4); CHK_FAIL2_END CHK_FAIL2_START snprintf (buf, sizeof (buf), "%3$d\n", 1, 2, 3, 4); CHK_FAIL2_END int sp[2]; if (socketpair (PF_UNIX, SOCK_STREAM, 0, sp)) FAIL (); else { const char *sendstr = "abcdefgh\nABCDEFGH\n0123456789\n"; if (send (sp[0], sendstr, strlen (sendstr), 0) != strlen (sendstr)) FAIL (); char recvbuf[12]; if (recv (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK) != sizeof recvbuf || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0) FAIL (); if (recv (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK) != sizeof recvbuf - 7 || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (recv (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK) != sizeof recvbuf) FAIL (); CHK_FAIL_END CHK_FAIL_START if (recv (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK) != sizeof recvbuf - 3) FAIL (); CHK_FAIL_END #endif socklen_t sl; struct sockaddr_un sa_un; sl = sizeof (sa_un); if (recvfrom (sp[1], recvbuf, sizeof recvbuf, MSG_PEEK, &sa_un, &sl) != sizeof recvbuf || memcmp (recvbuf, sendstr, sizeof recvbuf) != 0) FAIL (); sl = sizeof (sa_un); if (recvfrom (sp[1], recvbuf + 6, l0 + sizeof recvbuf - 7, MSG_PEEK, &sa_un, &sl) != sizeof recvbuf - 7 || memcmp (recvbuf + 6, sendstr, sizeof recvbuf - 7) != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START sl = sizeof (sa_un); if (recvfrom (sp[1], recvbuf + 1, sizeof recvbuf, MSG_PEEK, &sa_un, &sl) != sizeof recvbuf) FAIL (); CHK_FAIL_END CHK_FAIL_START sl = sizeof (sa_un); if (recvfrom (sp[1], recvbuf + 4, l0 + sizeof recvbuf - 3, MSG_PEEK, &sa_un, &sl) != sizeof recvbuf - 3) FAIL (); CHK_FAIL_END #endif close (sp[0]); close (sp[1]); } char fname[] = "/tmp/tst-chk1-dir-XXXXXX\0foo"; char *enddir = strchr (fname, '\0'); if (mkdtemp (fname) == NULL) { printf ("mkdtemp failed: %m\n"); return 1; } *enddir = '/'; if (symlink ("bar", fname) != 0) FAIL (); char readlinkbuf[4]; if (readlink (fname, readlinkbuf, 4) != 3 || memcmp (readlinkbuf, "bar", 3) != 0) FAIL (); if (readlink (fname, readlinkbuf + 1, l0 + 3) != 3 || memcmp (readlinkbuf, "bbar", 4) != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (readlink (fname, readlinkbuf + 2, l0 + 3) != 3) FAIL (); CHK_FAIL_END CHK_FAIL_START if (readlink (fname, readlinkbuf + 3, 4) != 3) FAIL (); CHK_FAIL_END #endif char *cwd1 = getcwd (NULL, 0); if (cwd1 == NULL) FAIL (); char *cwd2 = getcwd (NULL, 250); if (cwd2 == NULL) FAIL (); if (cwd1 && cwd2) { if (strcmp (cwd1, cwd2) != 0) FAIL (); *enddir = '\0'; if (chdir (fname)) FAIL (); char *cwd3 = getcwd (NULL, 0); if (cwd3 == NULL) FAIL (); if (strcmp (fname, cwd3) != 0) printf ("getcwd after chdir is '%s' != '%s'," "get{c,}wd tests skipped\n", cwd3, fname); else { char getcwdbuf[sizeof fname - 3]; char *cwd4 = getcwd (getcwdbuf, sizeof getcwdbuf); if (cwd4 != getcwdbuf || strcmp (getcwdbuf, fname) != 0) FAIL (); cwd4 = getcwd (getcwdbuf + 1, l0 + sizeof getcwdbuf - 1); if (cwd4 != getcwdbuf + 1 || getcwdbuf[0] != fname[0] || strcmp (getcwdbuf + 1, fname) != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (getcwd (getcwdbuf + 2, l0 + sizeof getcwdbuf) != getcwdbuf + 2) FAIL (); CHK_FAIL_END CHK_FAIL_START if (getcwd (getcwdbuf + 2, sizeof getcwdbuf) != getcwdbuf + 2) FAIL (); CHK_FAIL_END #endif if (getwd (getcwdbuf) != getcwdbuf || strcmp (getcwdbuf, fname) != 0) FAIL (); if (getwd (getcwdbuf + 1) != getcwdbuf + 1 || strcmp (getcwdbuf + 1, fname) != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START if (getwd (getcwdbuf + 2) != getcwdbuf + 2) FAIL (); CHK_FAIL_END #endif } if (chdir (cwd1) != 0) FAIL (); free (cwd3); } free (cwd1); free (cwd2); *enddir = '/'; if (unlink (fname) != 0) FAIL (); *enddir = '\0'; if (rmdir (fname) != 0) FAIL (); #if PATH_MAX > 0 char largebuf[PATH_MAX]; char *realres = realpath (".", largebuf); if (realres != largebuf) FAIL (); # if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char realbuf[1]; realres = realpath (".", realbuf); if (realres != realbuf) FAIL (); CHK_FAIL_END # endif #endif if (setlocale (LC_ALL, "de_DE.UTF-8") != NULL) { assert (MB_CUR_MAX <= 10); /* First a simple test. */ char enough[10]; if (wctomb (enough, L'A') != 1) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 /* We know the wchar_t encoding is ISO 10646. So pick a character which has a multibyte representation which does not fit. */ CHK_FAIL_START char smallbuf[2]; if (wctomb (smallbuf, L'\x100') != 2) FAIL (); CHK_FAIL_END #endif mbstate_t s; memset (&s, '\0', sizeof (s)); if (wcrtomb (enough, L'D', &s) != 1 || enough[0] != 'D') FAIL (); #if __USE_FORTIFY_LEVEL >= 1 /* We know the wchar_t encoding is ISO 10646. So pick a character which has a multibyte representation which does not fit. */ CHK_FAIL_START char smallbuf[2]; if (wcrtomb (smallbuf, L'\x100', &s) != 2) FAIL (); CHK_FAIL_END #endif wchar_t wenough[10]; memset (&s, '\0', sizeof (s)); const char *cp = "A"; if (mbsrtowcs (wenough, &cp, 10, &s) != 1 || wcscmp (wenough, L"A") != 0) FAIL (); cp = "BC"; if (mbsrtowcs (wenough, &cp, l0 + 10, &s) != 2 || wcscmp (wenough, L"BC") != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START wchar_t wsmallbuf[2]; cp = "ABC"; mbsrtowcs (wsmallbuf, &cp, 10, &s); CHK_FAIL_END #endif cp = "A"; if (mbstowcs (wenough, cp, 10) != 1 || wcscmp (wenough, L"A") != 0) FAIL (); cp = "DEF"; if (mbstowcs (wenough, cp, l0 + 10) != 3 || wcscmp (wenough, L"DEF") != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START wchar_t wsmallbuf[2]; cp = "ABC"; mbstowcs (wsmallbuf, cp, 10); CHK_FAIL_END #endif memset (&s, '\0', sizeof (s)); cp = "ABC"; wcscpy (wenough, L"DEF"); if (mbsnrtowcs (wenough, &cp, 1, 10, &s) != 1 || wcscmp (wenough, L"AEF") != 0) FAIL (); cp = "IJ"; if (mbsnrtowcs (wenough, &cp, 1, l0 + 10, &s) != 1 || wcscmp (wenough, L"IEF") != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START wchar_t wsmallbuf[2]; cp = "ABC"; mbsnrtowcs (wsmallbuf, &cp, 3, 10, &s); CHK_FAIL_END #endif memset (&s, '\0', sizeof (s)); const wchar_t *wcp = L"A"; if (wcsrtombs (enough, &wcp, 10, &s) != 1 || strcmp (enough, "A") != 0) FAIL (); wcp = L"BC"; if (wcsrtombs (enough, &wcp, l0 + 10, &s) != 2 || strcmp (enough, "BC") != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[2]; wcp = L"ABC"; wcsrtombs (smallbuf, &wcp, 10, &s); CHK_FAIL_END #endif memset (enough, 'Z', sizeof (enough)); wcp = L"EF"; if (wcstombs (enough, wcp, 10) != 2 || strcmp (enough, "EF") != 0) FAIL (); wcp = L"G"; if (wcstombs (enough, wcp, l0 + 10) != 1 || strcmp (enough, "G") != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[2]; wcp = L"ABC"; wcstombs (smallbuf, wcp, 10); CHK_FAIL_END #endif memset (&s, '\0', sizeof (s)); wcp = L"AB"; if (wcsnrtombs (enough, &wcp, 1, 10, &s) != 1 || strcmp (enough, "A") != 0) FAIL (); wcp = L"BCD"; if (wcsnrtombs (enough, &wcp, 1, l0 + 10, &s) != 1 || strcmp (enough, "B") != 0) FAIL (); #if __USE_FORTIFY_LEVEL >= 1 CHK_FAIL_START char smallbuf[2]; wcp = L"ABC"; wcsnrtombs (smallbuf, &wcp, 3, 10, &s); CHK_FAIL_END #endif }
/** * Display help text for an option. * @param fp output file handle * @param columns output display width control * @param opt option(s) * @param translation_domain translation domain */ static void singleOptionHelp(FILE * fp, columns_t columns, const struct poptOption * opt, /*@null@*/ const char * translation_domain) /*@globals fileSystem @*/ /*@modifies fp, fileSystem @*/ { size_t maxLeftCol = columns->cur; size_t indentLength = maxLeftCol + 5; size_t lineLength = columns->max - indentLength; const char * help = D_(translation_domain, opt->descrip); const char * argDescrip = getArgDescrip(opt, translation_domain); /* Display shortName iff printable non-space. */ int prtshort = (int)(isprint((int)opt->shortName) && opt->shortName != ' '); size_t helpLength; char * defs = NULL; char * left; size_t nb = maxLeftCol + 1; int displaypad = 0; /* Make sure there's more than enough room in target buffer. */ if (opt->longName) nb += strlen(opt->longName); if (F_ISSET(opt, TOGGLE)) nb += sizeof("[no]") - 1; if (argDescrip) nb += strlen(argDescrip); left = (char*) xmalloc(nb); assert(left); /* XXX can't happen */ if (left == NULL) return; left[0] = '\0'; left[maxLeftCol] = '\0'; #define prtlong (opt->longName != NULL) /* XXX splint needs a clue */ if (!(prtshort || prtlong)) goto out; if (prtshort && prtlong) { char *dash = F_ISSET(opt, ONEDASH) ? "-" : "--"; left[0] = '-'; left[1] = opt->shortName; (void) stpcpy(stpcpy(stpcpy(left+2, ", "), dash), opt->longName); } else if (prtshort) { left[0] = '-'; left[1] = opt->shortName; left[2] = '\0'; } else if (prtlong) { /* XXX --long always padded for alignment with/without "-X, ". */ char *dash = poptArgType(opt) == POPT_ARG_MAINCALL ? "" : (F_ISSET(opt, ONEDASH) ? "-" : "--"); const char *longName = opt->longName; const char *toggle; if (F_ISSET(opt, TOGGLE)) { toggle = "[no]"; if (longName[0] == 'n' && longName[1] == 'o') { longName += sizeof("no") - 1; if (longName[0] == '-') longName++; } } else toggle = ""; (void) stpcpy(stpcpy(stpcpy(stpcpy(left, " "), dash), toggle), longName); } #undef prtlong if (argDescrip) { char * le = left + strlen(left); if (F_ISSET(opt, OPTIONAL)) *le++ = '['; /* Choose type of output */ if (F_ISSET(opt, SHOW_DEFAULT)) { defs = singleOptionDefaultValue(lineLength, opt, translation_domain); if (defs) { char * t = (char*) xmalloc((help ? strlen(help) : 0) + strlen(defs) + sizeof(" ")); assert(t); /* XXX can't happen */ if (t) { char * te = t; if (help) te = stpcpy(te, help); *te++ = ' '; strcpy(te, defs); defs = _free(defs); defs = t; } } } if (opt->argDescrip == NULL) { switch (poptArgType(opt)) { case POPT_ARG_NONE: break; case POPT_ARG_VAL: #ifdef NOTNOW /* XXX pug ugly nerdy output */ { long aLong = opt->val; int ops = F_ISSET(opt, LOGICALOPS); int negate = F_ISSET(opt, NOT); /* Don't bother displaying typical values */ if (!ops && (aLong == 0L || aLong == 1L || aLong == -1L)) break; *le++ = '['; switch (ops) { case POPT_ARGFLAG_OR: *le++ = '|'; /*@innerbreak@*/ break; case POPT_ARGFLAG_AND: *le++ = '&'; /*@innerbreak@*/ break; case POPT_ARGFLAG_XOR: *le++ = '^'; /*@innerbreak@*/ break; default: /*@innerbreak@*/ break; } *le++ = (opt->longName != NULL ? '=' : ' '); if (negate) *le++ = '~'; /*@-formatconst@*/ le += sprintf(le, (ops ? "0x%lx" : "%ld"), aLong); /*@=formatconst@*/ *le++ = ']'; } #endif break; case POPT_ARG_INT: case POPT_ARG_SHORT: case POPT_ARG_LONG: case POPT_ARG_LONGLONG: case POPT_ARG_FLOAT: case POPT_ARG_DOUBLE: case POPT_ARG_STRING: *le++ = (opt->longName != NULL ? '=' : ' '); le = stpcpy(le, argDescrip); break; default: break; } } else { char *leo; /* XXX argDescrip[0] determines "--foo=bar" or "--foo bar". */ if (!strchr(" =(", argDescrip[0])) *le++ = ((poptArgType(opt) == POPT_ARG_MAINCALL) ? ' ' : (poptArgType(opt) == POPT_ARG_ARGV) ? ' ' : '='); le = stpcpy(leo = le, argDescrip); /* Adjust for (possible) wide characters. */ displaypad = (int)((le - leo) - stringDisplayWidth(argDescrip)); } if (F_ISSET(opt, OPTIONAL)) *le++ = ']'; *le = '\0'; } if (help) POPT_fprintf(fp," %-*s ", (int)(maxLeftCol+displaypad), left); else { POPT_fprintf(fp," %s\n", left); goto out; } left = _free(left); if (defs) help = defs; helpLength = strlen(help); while (helpLength > lineLength) { const char * ch; char format[16]; ch = help + lineLength - 1; while (ch > help && !_isspaceptr(ch)) ch = POPT_prev_char(ch); if (ch == help) break; /* give up */ while (ch > (help + 1) && _isspaceptr(ch)) ch = POPT_prev_char (ch); ch = POPT_next_char(ch); /* * XXX strdup is necessary to add NUL terminator so that an unknown * no. of (possible) multi-byte characters can be displayed. */ { char * fmthelp = xstrdup(help); if (fmthelp) { fmthelp[ch - help] = '\0'; sprintf(format, "%%s\n%%%ds", (int) indentLength); /*@-formatconst@*/ POPT_fprintf(fp, format, fmthelp, " "); /*@=formatconst@*/ free(fmthelp); } } help = ch; while (_isspaceptr(help) && *help) help = POPT_next_char(help); helpLength = strlen(help); } if (helpLength) fprintf(fp, "%s\n", help); help = NULL; out: /*@-dependenttrans@*/ defs = _free(defs); /*@=dependenttrans@*/ left = _free(left); }
static void copy(int sourceFd, const char* sourceName, const char* sourcePath, int destFd, const char* destName, const char* destPath, bool force, bool prompt, bool recursive) { struct stat sourceSt, destSt; if (fstatat(sourceFd, sourceName, &sourceSt, 0) < 0) { warn("stat: '%s'", sourcePath); status = 1; return; } bool destExists = true; if (fstatat(destFd, destName, &destSt, 0) < 0) { if (errno != ENOENT) { warn("stat: '%s'", destPath); status = 1; return; } destExists = false; } if (destExists && sourceSt.st_dev == destSt.st_dev && sourceSt.st_ino == destSt.st_ino) { warnx("'%s' and '%s' are the same file", sourcePath, destPath); status = 1; return; } if (S_ISDIR(sourceSt.st_mode)) { if (!recursive) { warnx("omitting directory '%s' because -R is not specified", sourcePath); status = 1; return; } if (destExists && !S_ISDIR(destSt.st_mode)) { warnx("cannot overwrite '%s' with directory '%s'", destPath, sourcePath); status = 1; return; } if (!destExists) { if (mkdirat(destFd, destName, S_IRWXU) < 0) { warn("mkdir: '%s'", destPath); status = 1; return; } if (fstatat(destFd, destName, &destSt, 0) < 0) { warn("stat: '%s'", destPath); status = 1; return; } destExists = true; } int newSourceFd = openat(sourceFd, sourceName, O_SEARCH | O_DIRECTORY); if (newSourceFd < 0) { warn("open: '%s'", sourcePath); status = 1; return; } DIR* dir = fdopendir(newSourceFd); if (!dir) { warn("fdopendir: '%s'", sourcePath); close(newSourceFd); status = 1; return; } int newDestFd = openat(destFd, destName, O_SEARCH | O_DIRECTORY); if (newDestFd < 0) { warn("open: '%s'", destPath); closedir(dir); status = 1; return; } struct dirent* dirent = readdir(dir); while (dirent) { if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { dirent = readdir(dir); continue; } char* newSourcePath = malloc(strlen(sourcePath) + strlen(dirent->d_name) + 2); if (!newSourcePath) err(1, "malloc"); stpcpy(stpcpy(stpcpy(newSourcePath, sourcePath), "/"), dirent->d_name); char* newDestPath = malloc(strlen(destPath) + strlen(dirent->d_name) + 2); if (!newDestPath) err(1, "malloc"); stpcpy(stpcpy(stpcpy(newDestPath, destPath), "/"), dirent->d_name); if (destExists && dirent->d_dev == destSt.st_dev && dirent->d_ino == destSt.st_ino) { warnx("cannot copy directory '%s' into itself '%s'", newSourcePath, destPath); } else { copy(newSourceFd, dirent->d_name, newSourcePath, newDestFd, dirent->d_name, newDestPath, force, prompt, recursive); } free(newSourcePath); free(newDestPath); dirent = readdir(dir); } closedir(dir); close(newDestFd); } else if (S_ISREG(sourceSt.st_mode)) { int newDestFd; if (destExists) { if (prompt) { fprintf(stderr, "%s: overwrite '%s'? ", program_invocation_short_name, destPath); if (!getConfirmation()) return; } newDestFd = openat(destFd, destName, O_WRONLY | O_TRUNC); if (newDestFd < 0) { if (force) { if (unlinkat(destFd, destName, 0) < 0) { warn("unlinkat: '%s'", destPath); status = 1; return; } } else { warn("open: '%s'", destPath); status = 1; return; } } else { destExists = true; } } if (!destExists) { newDestFd = openat(destFd, destName, O_WRONLY | O_CREAT, sourceSt.st_mode & 0777); if (newDestFd < 0) { warn("open: '%s'", destPath); status = 1; return; } } int newSourceFd = openat(sourceFd, sourceName, O_RDONLY); if (newSourceFd < 0) { warn("open: '%s'", sourcePath); close(newDestFd); status = 1; return; } copyFile(newSourceFd, sourcePath, newDestFd, destPath); close(newDestFd); close(newSourceFd); } else { warnx("unsupported file type: '%s'", sourcePath); status = 1; } }
/** * Display default value for an option. * @param lineLength display positions remaining * @param opt option(s) * @param translation_domain translation domain * @return */ static /*@only@*/ /*@null@*/ char * singleOptionDefaultValue(size_t lineLength, const struct poptOption * opt, /*@-paramuse@*/ /* FIX: i18n macros disabled with lclint */ /*@null@*/ const char * translation_domain) /*@=paramuse@*/ /*@*/ { const char * defstr = D_(translation_domain, "default"); char * le = (char*) xmalloc(4*lineLength + 1); char * l = le; assert(le); /* XXX can't happen */ if (le == NULL) return NULL; *le = '\0'; *le++ = '('; le = stpcpy(le, defstr); *le++ = ':'; *le++ = ' '; if (opt->arg) { /* XXX programmer error */ poptArg arg; arg.ptr = opt->arg; switch (poptArgType(opt)) { case POPT_ARG_VAL: case POPT_ARG_INT: le += sprintf(le, "%d", arg.intp[0]); break; case POPT_ARG_SHORT: le += sprintf(le, "%hd", arg.shortp[0]); break; case POPT_ARG_LONG: le += sprintf(le, "%ld", arg.longp[0]); break; case POPT_ARG_LONGLONG: #if defined(_MSC_VER) || defined(__MINGW32__) le += sprintf(le, "%I64d", arg.longlongp[0]); #else le += sprintf(le, "%lld", arg.longlongp[0]); #endif break; case POPT_ARG_FLOAT: { double aDouble = (double) arg.floatp[0]; le += sprintf(le, "%g", aDouble); } break; case POPT_ARG_DOUBLE: le += sprintf(le, "%g", arg.doublep[0]); break; case POPT_ARG_MAINCALL: le += sprintf(le, "%p", opt->arg); break; case POPT_ARG_ARGV: le += sprintf(le, "%p", opt->arg); break; case POPT_ARG_STRING: { const char * s = arg.argv[0]; if (s == NULL) le = stpcpy(le, "null"); else { size_t limit = 4*lineLength - (le - l) - sizeof("\"\")"); size_t slen; *le++ = '"'; strncpy(le, s, limit); le[limit] = '\0'; le += (slen = strlen(le)); if (slen == limit && s[limit]) le[-1] = le[-2] = le[-3] = '.'; *le++ = '"'; } } break; case POPT_ARG_NONE: default: l = _free(l); return NULL; /*@notreached@*/ break; } } *le++ = ')'; *le = '\0'; return l; }
static inline void stx_request_process_file(stx_request_t *r, stx_hashmap_t *open_files) { int fd; char filepath[255]; struct stat sb; char *p; size_t b_left, min; stx_open_file_cache_t *cache; p = filepath; p = stpcpy(p, r->server->webroot); b_left = p - filepath - 1; min = (r->uri_len < b_left) ? r->uri_len : b_left; p = stpncpy(p, r->uri_start, min); //append default index file when / is requested if (*(r->uri_start + r->uri_len - 1) == '/') { b_left = p - filepath - 1; min = (r->server->index_len < b_left) ? r->server->index_len : b_left; p = stpncpy(p, r->server->index, min); } *p = '\0'; if (NULL == (cache = stx_hashmap_cget(open_files, filepath))) { //cache miss stx_log(r->server->logger, STX_LOG_INFO, "Open files cache miss: %s", filepath); if ((fd = open(filepath, O_RDONLY)) == -1) { if (ENOENT == errno) { r->status = STX_STATUS_NOT_FOUND; } else if (EACCES == errno) { r->status = STX_STATUS_FORBIDDEN; } else { r->status = STX_STATUS_ERROR; stx_log_syserr(r->server->logger, "open: %s"); } return; } if (fstat(fd, &sb) == -1) { r->status = STX_STATUS_ERROR; stx_log_syserr(r->server->logger, "fstat: %s"); return; } cache = malloc(sizeof(stx_open_file_cache_t)); if (NULL == cache) { r->status = STX_STATUS_ERROR; stx_log_syserr(r->server->logger, "malloc: %s"); return; } cache->fd = fd; cache->st_size = sb.st_size; if(!stx_hashmap_cput(open_files, filepath, cache)) { r->status = STX_STATUS_ERROR; return; } } cache->count++; r->status = STX_STATUS_OK; r->content_length = cache->st_size; r->fd = cache->fd; }
static gpgme_error_t gpgsm_sign(void *engine, gpgme_data_t in, gpgme_data_t out, gpgme_sig_mode_t mode, int use_armor, int use_textmode, int include_certs, gpgme_ctx_t ctx /* FIXME */) { engine_gpgsm_t gpgsm = engine; gpgme_error_t err; char *assuan_cmd; int i; gpgme_key_t key; if(!gpgsm) return gpg_error(GPG_ERR_INV_VALUE); /* FIXME: This does not work as RESET does not reset it so we can't revert back to default. */ if(include_certs != GPGME_INCLUDE_CERTS_DEFAULT) { /* FIXME: Make sure that if we run multiple operations, that we can reset any previously set value in case the default is requested. */ if(asprintf(&assuan_cmd, "OPTION include-certs %i", include_certs) < 0) return gpg_error_from_errno(errno); err = gpgsm_assuan_simple_command(gpgsm->assuan_ctx, assuan_cmd, NULL, NULL); free(assuan_cmd); if(err) return err; } for(i = 0; (key = gpgme_signers_enum(ctx, i)); i++) { const char *s = key->subkeys ? key->subkeys->fpr : NULL; if(s && strlen(s) < 80) { char buf[100]; strcpy(stpcpy(buf, "SIGNER "), s); err = gpgsm_assuan_simple_command(gpgsm->assuan_ctx, buf, NULL, NULL); } else err = gpg_error(GPG_ERR_INV_VALUE); gpgme_key_unref(key); if(err) return err; } gpgsm->input_cb.data = in; err = gpgsm_set_fd(gpgsm, INPUT_FD, map_input_enc(gpgsm->input_cb.data)); if(err) return err; gpgsm->output_cb.data = out; err = gpgsm_set_fd(gpgsm, OUTPUT_FD, use_armor ? "--armor" : 0); if(err) return err; gpgsm_clear_fd(gpgsm, MESSAGE_FD); err = start(gpgsm, mode == GPGME_SIG_MODE_DETACH ? "SIGN --detached" : "SIGN"); return err; }
/* in case it hase been defined as a macro: */ #ifdef bindtextdomain # undef bindtextdomain #endif /* bindtextdomain */ char *bindtextdomain(const char *domainname, const char *dirname) { #if HAVE_SETENV || HAVE_PUTENV char *old_val, *new_val, *cp; size_t new_val_len; /* This does not make much sense here, but to be compatible, do it: */ if (domainname == NULL) { return NULL; } /* Compute length of added path element. If we use setenv, then we do NOT * need the first bits for NLSPATH=, but why complicate the code for this * peanuts. */ new_val_len = (sizeof("NLSPATH=") - 1 + strlen(dirname) + sizeof("/%L/LC_MESSAGES/%N.cat")); old_val = getenv("NLSPATH"); if ((old_val == NULL) || (old_val[0] == '\0')) { old_val = NULL; new_val_len += (1 + sizeof(LOCALEDIR) - 1 + sizeof("/%L/LC_MESSAGES/%N.cat")); } else { new_val_len += strlen(old_val); } new_val = (char *)malloc(new_val_len); if (new_val == NULL) { return NULL; } # if HAVE_SETENV cp = new_val; # else cp = stpcpy(new_val, "NLSPATH="); # endif /* HAVE_SETENV */ cp = stpcpy(cp, dirname); cp = stpcpy(cp, "/%L/LC_MESSAGES/%N.cat:"); if (old_val == NULL) { # if __STDC__ stpcpy(cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); # else cp = stpcpy(cp, LOCALEDIR); stpcpy(cp, "/%L/LC_MESSAGES/%N.cat"); # endif /* __STDC__ */ } else { stpcpy(cp, old_val); } # if HAVE_SETENV setenv("NLSPATH", new_val, 1); free(new_val); # else putenv(new_val); /* Do *not* free the environment entry we just entered. It is used * from now on. */ # endif /* HAVE_SETENV */ #endif /* HAVE_SETENV || HAVE_PUTENV */ return (char *)domainname; }
/* * Print reply error info */ char * clnt_sperror (CLIENT * rpch, const char *msg) { char chrbuf[1024]; struct rpc_err e; char *err; char *str = _buf (); char *strstart = str; int len; if (str == NULL) return NULL; CLNT_GETERR (rpch, &e); len = sprintf (str, "%s: ", msg); str += len; str = stpcpy (str, clnt_sperrno (e.re_status)); switch (e.re_status) { case RPC_SUCCESS: case RPC_CANTENCODEARGS: case RPC_CANTDECODERES: case RPC_TIMEDOUT: case RPC_PROGUNAVAIL: case RPC_PROCUNAVAIL: case RPC_CANTDECODEARGS: case RPC_SYSTEMERROR: case RPC_UNKNOWNHOST: case RPC_UNKNOWNPROTO: case RPC_PMAPFAILURE: case RPC_PROGNOTREGISTERED: case RPC_FAILED: break; case RPC_CANTSEND: case RPC_CANTRECV: len = sprintf (str, "; errno = %s", __strerror_r (e.re_errno, chrbuf, sizeof chrbuf)); str += len; break; case RPC_VERSMISMATCH: len= sprintf (str, _("; low version = %lu, high version = %lu"), e.re_vers.low, e.re_vers.high); str += len; break; case RPC_AUTHERROR: err = auth_errmsg (e.re_why); str = stpcpy (str, _ ("; why = ")); if (err != NULL) { str = stpcpy (str, err); } else { len = sprintf (str, _("(unknown authentication error - %d)"), (int) e.re_why); str += len; } break; case RPC_PROGVERSMISMATCH: len = sprintf (str, _("; low version = %lu, high version = %lu"), e.re_vers.low, e.re_vers.high); str += len; break; default: /* unknown */ len = sprintf (str, "; s1 = %lu, s2 = %lu", e.re_lb.s1, e.re_lb.s2); str += len; break; } *str = '\n'; *++str = '\0'; return (strstart); }
PAMH_ARG_DECL(char * create_password_hash, const char *password, unsigned int ctrl, int rounds) { const char *algoid; char salt[64]; /* contains rounds number + max 16 bytes of salt + algo id */ char *sp; if (on(UNIX_MD5_PASS, ctrl)) { /* algoid = "$1" */ return crypt_md5_wrapper(password); } else if (on(UNIX_BLOWFISH_PASS, ctrl)) { algoid = "$2a$"; } else if (on(UNIX_SHA256_PASS, ctrl)) { algoid = "$5$"; } else if (on(UNIX_SHA512_PASS, ctrl)) { algoid = "$6$"; } else { /* must be crypt/bigcrypt */ char tmppass[9]; char *crypted; crypt_make_salt(salt, 2); if (off(UNIX_BIGCRYPT, ctrl) && strlen(password) > 8) { strncpy(tmppass, password, sizeof(tmppass)-1); tmppass[sizeof(tmppass)-1] = '\0'; password = tmppass; } crypted = bigcrypt(password, salt); memset(tmppass, '\0', sizeof(tmppass)); password = NULL; return crypted; } #ifdef HAVE_CRYPT_GENSALT_R if (on(UNIX_BLOWFISH_PASS, ctrl)) { char entropy[17]; crypt_make_salt(entropy, sizeof(entropy) - 1); sp = crypt_gensalt_r (algoid, rounds, entropy, sizeof(entropy), salt, sizeof(salt)); } else { #endif sp = stpcpy(salt, algoid); if (on(UNIX_ALGO_ROUNDS, ctrl)) { sp += snprintf(sp, sizeof(salt) - 3, "rounds=%u$", rounds); } crypt_make_salt(sp, 8); /* For now be conservative so the resulting hashes * are not too long. 8 bytes of salt prevents dictionary * attacks well enough. */ #ifdef HAVE_CRYPT_GENSALT_R } #endif sp = crypt(password, salt); if (strncmp(algoid, sp, strlen(algoid)) != 0) { /* libxcrypt/libc doesn't know the algorithm, use MD5 */ pam_syslog(pamh, LOG_ERR, "Algo %s not supported by the crypto backend, " "falling back to MD5\n", on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" : on(UNIX_SHA256_PASS, ctrl) ? "sha256" : on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid); memset(sp, '\0', strlen(sp)); return crypt_md5_wrapper(password); } return x_strdup(sp); }
nis_error nis_creategroup (const_nis_name group, unsigned int flags) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 50]; char leafbuf[grouplen + 2]; char domainbuf[grouplen + 2]; nis_error status; nis_result *res; char *cp, *cp2; nis_object *obj; cp = stpcpy (buf, nis_leaf_of_r (group, leafbuf, sizeof (leafbuf) - 1)); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } else return NIS_BADNAME; obj = calloc (1, sizeof (nis_object)); if (__builtin_expect (obj == NULL, 0)) return NIS_NOMEMORY; obj->zo_oid.ctime = obj->zo_oid.mtime = time (NULL); obj->zo_name = strdup (leafbuf); obj->zo_owner = __nis_default_owner (NULL); obj->zo_group = __nis_default_group (NULL); obj->zo_domain = strdup (domainbuf); if (obj->zo_name == NULL || obj->zo_owner == NULL || obj->zo_group == NULL || obj->zo_domain == NULL) { free (obj->zo_group); free (obj->zo_owner); free (obj->zo_name); free (obj); return NIS_NOMEMORY; } obj->zo_access = __nis_default_access (NULL, 0); obj->zo_ttl = 60 * 60; obj->zo_data.zo_type = NIS_GROUP_OBJ; obj->zo_data.objdata_u.gr_data.gr_flags = flags; obj->zo_data.objdata_u.gr_data.gr_members.gr_members_len = 0; obj->zo_data.objdata_u.gr_data.gr_members.gr_members_val = NULL; res = nis_add (buf, obj); nis_free_object (obj); if (res == NULL) return NIS_NOMEMORY; status = NIS_RES_STATUS (res); nis_freeresult (res); return status; } return NIS_FAIL; }
/* line -- min size: MAX_INTERNAL_COMMAND_SIZE + sizeof(errorlevel) * 8 */ int expandEnvVars(char *ip, char * const line) { char *cp, *tp; assert(ip); assert(line); /* Return the maximum pointer into parsedline to add 'numbytes' bytes */ #define parsedMax(numbytes) \ (line + MAX_INTERNAL_COMMAND_SIZE - 1 - (numbytes)) cp = line; while(*ip) { /* Assume that at least one character is added, place the test here to simplify the switch() statement */ if(cp >= parsedMax(1)) return 0; if(*ip == '%') { switch(*++ip) { case '\0': *cp++ = '%'; break; case '%': *cp++ = *ip++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': if(0 != (tp = find_arg(*ip - '0'))) { if(cp >= parsedMax(strlen(tp))) return 0; cp = stpcpy(cp, tp); ip++; } else *cp++ = '%'; /* Let the digit be copied in the cycle */ break; #if 0 /* Caused conflicts with some batches, see %ERRORLEVEL% */ case '?': /* overflow check: parsedline has that many character "on reserve" */ cp += sprintf(cp, "%u", errorlevel); ip++; break; #endif default: #if 0 if(forvar == toupper(*ip)) { /* FOR hack */ *cp++ = '%'; /* let the var be copied in next cycle */ break; } #endif if((tp = strchr(ip, '%')) != 0) { char *evar; *tp = '\0'; if((evar = getEnv(ip)) != 0) { if(cp >= parsedMax(strlen(evar))) return 0; cp = stpcpy(cp, evar); } else if(matchtok(ip, "ERRORLEVEL")) { /* overflow check: parsedline has that many character "on reserve" */ cp += sprintf(cp, "%u", errorlevel); } else if(matchtok(ip, "_CWD") || matchtok(ip, "CD")) { if(0 == (evar = cwd(0))) { return 0; } else { if(cp >= parsedMax(strlen(evar))) return 0; cp = stpcpy(cp, evar); free(evar); } } ip = tp + 1; } else *cp++ = '%'; break; } continue; } #if 0 if(iscntrl(*ip)) { *cp++ = ' '; ++ip; } else #endif *cp++ = *ip++; } assert(cp); assert(cp < line + MAX_INTERNAL_COMMAND_SIZE); *cp = 0; return 1; }
static int decode_poll_exiting(struct tcb *const tcp, const kernel_ulong_t pts) { struct pollfd fds; const unsigned int nfds = tcp->u_arg[1]; const unsigned long size = sizeof(fds) * nfds; const kernel_ulong_t start = tcp->u_arg[0]; const kernel_ulong_t end = start + size; kernel_ulong_t cur; const unsigned int max_printed = abbrev(tcp) ? max_strlen : -1U; unsigned int printed; static char outstr[1024]; char *outptr; #define end_outstr (outstr + sizeof(outstr)) if (syserror(tcp)) return 0; if (tcp->u_rval == 0) { tcp->auxstr = "Timeout"; return RVAL_STR; } if (!verbose(tcp) || !start || !nfds || size / sizeof(fds) != nfds || end < start) return 0; outptr = outstr; for (printed = 0, cur = start; cur < end; cur += sizeof(fds)) { if (umove(tcp, cur, &fds) < 0) { if (outptr == outstr) *outptr++ = '['; else outptr = stpcpy(outptr, ", "); outptr += sprintf(outptr, "%#" PRI_klx, cur); break; } if (!fds.revents) continue; if (outptr == outstr) *outptr++ = '['; else outptr = stpcpy(outptr, ", "); if (printed >= max_printed) { outptr = stpcpy(outptr, "..."); break; } static const char fmt[] = "{fd=%d, revents="; char fdstr[sizeof(fmt) + sizeof(int) * 3]; sprintf(fdstr, fmt, fds.fd); const char *flagstr = sprintflags("", pollflags, (unsigned short) fds.revents); if (outptr + strlen(fdstr) + strlen(flagstr) + 1 >= end_outstr - (2 + 2 * sizeof(long) + sizeof(", ], ..."))) { outptr = stpcpy(outptr, "..."); break; } outptr = stpcpy(outptr, fdstr); outptr = stpcpy(outptr, flagstr); *outptr++ = '}'; ++printed; } if (outptr != outstr) *outptr++ = ']'; *outptr = '\0'; if (pts) { const char *str = sprint_timespec(tcp, pts); if (outptr + sizeof(", left ") + strlen(str) < end_outstr) { outptr = stpcpy(outptr, outptr == outstr ? "left " : ", left "); outptr = stpcpy(outptr, str); } else { outptr = stpcpy(outptr, ", ..."); } } if (outptr == outstr) return 0; tcp->auxstr = outstr; return RVAL_STR; #undef end_outstr }
int dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines) { if (unlikely (cudie == NULL || (INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit && INTUSE(dwarf_tag) (cudie) != DW_TAG_partial_unit))) return -1; int res = -1; struct linelist *linelist = NULL; unsigned int nlinelist = 0; /* If there are a large number of lines don't blow up the stack. Keep track of the last malloced linelist record and free them through the next pointer at the end. */ #define MAX_STACK_ALLOC 4096 struct linelist *malloc_linelist = NULL; /* Get the information if it is not already known. */ struct Dwarf_CU *const cu = cudie->cu; if (cu->lines == NULL) { /* Failsafe mode: no data found. */ cu->lines = (void *) -1l; cu->files = (void *) -1l; /* The die must have a statement list associated. */ Dwarf_Attribute stmt_list_mem; Dwarf_Attribute *stmt_list = INTUSE(dwarf_attr) (cudie, DW_AT_stmt_list, &stmt_list_mem); /* Get the offset into the .debug_line section. NB: this call also checks whether the previous dwarf_attr call failed. */ const unsigned char *lineendp; const unsigned char *linep = __libdw_formptr (stmt_list, IDX_debug_line, DWARF_E_NO_DEBUG_LINE, (unsigned char **) &lineendp, NULL); if (linep == NULL) goto out; /* Get the compilation directory. */ Dwarf_Attribute compdir_attr_mem; Dwarf_Attribute *compdir_attr = INTUSE(dwarf_attr) (cudie, DW_AT_comp_dir, &compdir_attr_mem); const char *comp_dir = INTUSE(dwarf_formstring) (compdir_attr); if (unlikely (linep + 4 > lineendp)) { invalid_data: __libdw_seterrno (DWARF_E_INVALID_DEBUG_LINE); goto out; } Dwarf *dbg = cu->dbg; Dwarf_Word unit_length = read_4ubyte_unaligned_inc (dbg, linep); unsigned int length = 4; if (unlikely (unit_length == DWARF3_LENGTH_64_BIT)) { if (unlikely (linep + 8 > lineendp)) goto invalid_data; unit_length = read_8ubyte_unaligned_inc (dbg, linep); length = 8; } /* Check whether we have enough room in the section. */ if (unit_length < 2 + length + 5 * 1 || unlikely (linep + unit_length > lineendp)) goto invalid_data; lineendp = linep + unit_length; /* The next element of the header is the version identifier. */ uint_fast16_t version = read_2ubyte_unaligned_inc (dbg, linep); if (unlikely (version < 2) || unlikely (version > 4)) { __libdw_seterrno (DWARF_E_VERSION); goto out; } /* Next comes the header length. */ Dwarf_Word header_length; if (length == 4) header_length = read_4ubyte_unaligned_inc (dbg, linep); else header_length = read_8ubyte_unaligned_inc (dbg, linep); const unsigned char *header_start = linep; /* Next the minimum instruction length. */ uint_fast8_t minimum_instr_len = *linep++; /* Next the maximum operations per instruction, in version 4 format. */ uint_fast8_t max_ops_per_instr = 1; if (version >= 4) { if (unlikely (lineendp - linep < 5)) goto invalid_data; max_ops_per_instr = *linep++; if (unlikely (max_ops_per_instr == 0)) goto invalid_data; } /* Then the flag determining the default value of the is_stmt register. */ uint_fast8_t default_is_stmt = *linep++; /* Now the line base. */ int_fast8_t line_base = (int8_t) *linep++; /* And the line range. */ uint_fast8_t line_range = *linep++; /* The opcode base. */ uint_fast8_t opcode_base = *linep++; /* Remember array with the standard opcode length (-1 to account for the opcode with value zero not being mentioned). */ const uint8_t *standard_opcode_lengths = linep - 1; if (unlikely (lineendp - linep < opcode_base - 1)) goto invalid_data; linep += opcode_base - 1; /* First comes the list of directories. Add the compilation directory first since the index zero is used for it. */ struct dirlist { const char *dir; size_t len; struct dirlist *next; } comp_dir_elem = { .dir = comp_dir, .len = comp_dir ? strlen (comp_dir) : 0, .next = NULL }; struct dirlist *dirlist = &comp_dir_elem; unsigned int ndirlist = 1; // XXX Directly construct array to conserve memory? while (*linep != 0) { struct dirlist *new_dir = (struct dirlist *) alloca (sizeof (*new_dir)); new_dir->dir = (char *) linep; uint8_t *endp = memchr (linep, '\0', lineendp - linep); if (endp == NULL) goto invalid_data; new_dir->len = endp - linep; new_dir->next = dirlist; dirlist = new_dir; ++ndirlist; linep = endp + 1; } /* Skip the final NUL byte. */ ++linep; /* Rearrange the list in array form. */ struct dirlist **dirarray = (struct dirlist **) alloca (ndirlist * sizeof (*dirarray)); for (unsigned int n = ndirlist; n-- > 0; dirlist = dirlist->next) dirarray[n] = dirlist; /* Now read the files. */ struct filelist null_file = { .info = { .name = "???", .mtime = 0, .length = 0 }, .next = NULL }; struct filelist *filelist = &null_file; unsigned int nfilelist = 1; if (unlikely (linep >= lineendp)) goto invalid_data; while (*linep != 0) { struct filelist *new_file = (struct filelist *) alloca (sizeof (*new_file)); /* First comes the file name. */ char *fname = (char *) linep; uint8_t *endp = memchr (fname, '\0', lineendp - linep); if (endp == NULL) goto invalid_data; size_t fnamelen = endp - (uint8_t *) fname; linep = endp + 1; /* Then the index. */ Dwarf_Word diridx; get_uleb128 (diridx, linep); if (unlikely (diridx >= ndirlist)) { __libdw_seterrno (DWARF_E_INVALID_DIR_IDX); goto out; } if (*fname == '/') /* It's an absolute path. */ new_file->info.name = fname; else { new_file->info.name = libdw_alloc (dbg, char, 1, dirarray[diridx]->len + 1 + fnamelen + 1); char *cp = new_file->info.name; if (dirarray[diridx]->dir != NULL) { /* This value could be NULL in case the DW_AT_comp_dir was not present. We cannot do much in this case. The easiest thing is to convert the path in an absolute path. */ cp = stpcpy (cp, dirarray[diridx]->dir); } *cp++ = '/'; strcpy (cp, fname); assert (strlen (new_file->info.name) < dirarray[diridx]->len + 1 + fnamelen + 1); } /* Next comes the modification time. */ get_uleb128 (new_file->info.mtime, linep); /* Finally the length of the file. */ get_uleb128 (new_file->info.length, linep); new_file->next = filelist; filelist = new_file; ++nfilelist; } /* Skip the final NUL byte. */ ++linep; /* Consistency check. */ if (unlikely (linep != header_start + header_length)) { __libdw_seterrno (DWARF_E_INVALID_DWARF); goto out; } /* We are about to process the statement program. Initialize the state machine registers (see 6.2.2 in the v2.1 specification). */ Dwarf_Word addr = 0; unsigned int op_index = 0; unsigned int file = 1; int line = 1; unsigned int column = 0; uint_fast8_t is_stmt = default_is_stmt; bool basic_block = false; bool prologue_end = false; bool epilogue_begin = false; unsigned int isa = 0; unsigned int discriminator = 0; /* Apply the "operation advance" from a special opcode or DW_LNS_advance_pc (as per DWARF4 6.2.5.1). */ inline void advance_pc (unsigned int op_advance) { addr += minimum_instr_len * ((op_index + op_advance) / max_ops_per_instr); op_index = (op_index + op_advance) % max_ops_per_instr; }
char* WEB_getStatus() { static char buffer[64]; char* p = buffer; ProgramVector* pv = getProgramVector(); if(pv == NULL) return (char*)"Missing program vector"; uint8_t err = pv->error; switch(err & 0xf0) { case NO_ERROR: { // p = stpcpy(p, (const char*)"No error"); p = stpcpy(p, (const char*)"CPU "); float percent = (pv->cycles_per_block/pv->audio_blocksize) / (float)3500; p = stpcpy(p, itoa(ceilf(percent*100), 10)); p = stpcpy(p, (const char*)"% Heap "); int mem = pv->heap_bytes_used; p = stpcpy(p, itoa(mem, 10)); break; } case MEM_ERROR: p = stpcpy(p, (const char*)"Memory Error 0x"); p = stpcpy(p, itoa(err, 16)); break; case BUS_ERROR: p = stpcpy(p, (const char*)"Bus Error 0x"); p = stpcpy(p, itoa(err, 16)); break; case USAGE_ERROR: p = stpcpy(p, (const char*)"Usage Error 0x"); p = stpcpy(p, itoa(err, 16)); break; case NMI_ERROR: p = stpcpy(p, (const char*)"Non-maskable Interrupt 0x"); p = stpcpy(p, itoa(err, 16)); break; case HARDFAULT_ERROR: p = stpcpy(p, (const char*)"HardFault Error 0x"); p = stpcpy(p, itoa(err, 16)); break; case PROGRAM_ERROR: p = stpcpy(p, (const char*)"Missing or Invalid Program 0x"); p = stpcpy(p, itoa(err, 16)); break; default: p = stpcpy(p, (const char*)"Unknown Error 0x"); p = stpcpy(p, itoa(err, 16)); break; } return buffer; }
static void init_history(void) { using_history(); if (disable_history) return; struct stat stat_info; if (!stat(".julia_history", &stat_info)) { // history file in current dir history_file = ".julia_history"; } else { char *histenv = getenv("JULIA_HISTORY"); if (histenv) { history_file = histenv; } else { #ifndef __WIN32__ char *home = getenv("HOME"); if (!home) return; asprintf(&history_file, "%s/.julia_history", home); #else char *home = getenv("AppData"); if (!home) return; asprintf(&history_file, "%s/julia/history", home); #endif } } if (!stat(history_file, &stat_info)) { read_history(history_file); for (;;) { HIST_ENTRY *entry = history_get(history_base); if (entry && isspace(entry->line[0])) free_history_entry(history_rem(history_base)); else break; } int i, j, k; for (i=1 ;; i++) { HIST_ENTRY *first = history_get(i); if (!first) break; int length = strlen(first->line)+1; for (j = i+1 ;; j++) { HIST_ENTRY *child = history_get(j); if (!child || !isspace(child->line[0])) break; length += strlen(child->line)+1; } if (j == i+1) continue; first->line = (char*)realloc(first->line, length); char *p = strchr(first->line, '\0'); for (k = i+1; k < j; k++) { *p = '\n'; #ifndef __WIN32__ p = stpcpy(p+1, history_get(i+1)->line); #else p = strcpy(p+1, history_get(i+1)->line); #endif free_history_entry(history_rem(i+1)); } } } else if (errno == ENOENT) { write_history(history_file); } else { jl_printf(jl_uv_stderr, "history file error: %s\n", strerror(errno)); exit(1); } }
/* Using Unix sockets this way is a security risk. */ static int gaih_local(const char *name, const struct gaih_service *service, const struct addrinfo *req, struct addrinfo **pai) { struct utsname utsname; struct addrinfo *ai = *pai; if ((name != NULL) && (req->ai_flags & AI_NUMERICHOST)) return (GAIH_OKIFUNSPEC | -EAI_NONAME); if ((name != NULL) || (req->ai_flags & AI_CANONNAME)) if (uname(&utsname) < 0) return -EAI_SYSTEM; if (name != NULL) { if (strcmp(name, "localhost") && strcmp(name, "local") && strcmp(name, "unix") && strcmp(name, utsname.nodename)) return (GAIH_OKIFUNSPEC | -EAI_NONAME); } if (req->ai_protocol || req->ai_socktype) { const struct gaih_typeproto *tp = gaih_inet_typeproto + 1; while (tp->name[0] && ((tp->protoflag & GAI_PROTO_NOSERVICE) != 0 || (req->ai_socktype != 0 && req->ai_socktype != tp->socktype) || (req->ai_protocol != 0 && !(tp->protoflag & GAI_PROTO_PROTOANY) && req->ai_protocol != tp->protocol)) ) { ++tp; } if (! tp->name[0]) { if (req->ai_socktype) return (GAIH_OKIFUNSPEC | -EAI_SOCKTYPE); return (GAIH_OKIFUNSPEC | -EAI_SERVICE); } } *pai = ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_un) + ((req->ai_flags & AI_CANONNAME) ? (strlen(utsname.nodename) + 1) : 0)); if (ai == NULL) return -EAI_MEMORY; ai->ai_next = NULL; ai->ai_flags = req->ai_flags; ai->ai_family = AF_LOCAL; ai->ai_socktype = req->ai_socktype ? req->ai_socktype : SOCK_STREAM; ai->ai_protocol = req->ai_protocol; ai->ai_addrlen = sizeof(struct sockaddr_un); ai->ai_addr = (void *)ai + sizeof(struct addrinfo); #if SALEN ((struct sockaddr_un *)ai->ai_addr)->sun_len = sizeof(struct sockaddr_un); #endif /* SALEN */ ((struct sockaddr_un *)ai->ai_addr)->sun_family = AF_LOCAL; memset(((struct sockaddr_un *)ai->ai_addr)->sun_path, 0, UNIX_PATH_MAX); if (service) { struct sockaddr_un *sunp = (struct sockaddr_un *)ai->ai_addr; if (strchr(service->name, '/') != NULL) { if (strlen(service->name) >= sizeof(sunp->sun_path)) return GAIH_OKIFUNSPEC | -EAI_SERVICE; strcpy(sunp->sun_path, service->name); } else { if (strlen(P_tmpdir "/") + 1 + strlen(service->name) >= sizeof(sunp->sun_path)) return (GAIH_OKIFUNSPEC | -EAI_SERVICE); stpcpy(stpcpy(sunp->sun_path, P_tmpdir "/"), service->name); } } else { /* This is a dangerous use of the interface since there is a time window between the test for the file and the actual creation (done by the caller) in which a file with the same name could be created. */ char *buf = ((struct sockaddr_un *)ai->ai_addr)->sun_path; if (__path_search(buf, L_tmpnam, NULL, NULL, 0) != 0 || __gen_tempname(buf, __GT_NOCREATE, 0) != 0 ) { return -EAI_SYSTEM; } } ai->ai_canonname = NULL; if (req->ai_flags & AI_CANONNAME) ai->ai_canonname = strcpy((char *)(ai + 1) + sizeof(struct sockaddr_un), utsname.nodename); return 0; }
static void update_status(struct svdir *s) { ssize_t sz; int fd; svstatus_t status; /* pid */ if (pidchanged) { fd = open_trunc_or_warn("supervise/pid.new"); if (fd < 0) return; if (s->pid) { char spid[sizeof(int)*3 + 2]; int size = sprintf(spid, "%u\n", (unsigned)s->pid); write(fd, spid, size); } close(fd); if (rename_or_warn("supervise/pid.new", s->islog ? "log/supervise/pid" : "log/supervise/pid"+4)) return; pidchanged = 0; } /* stat */ fd = open_trunc_or_warn("supervise/stat.new"); if (fd < -1) return; { char stat_buf[sizeof("finish, paused, got TERM, want down\n")]; char *p = stat_buf; switch (s->state) { case S_DOWN: p = stpcpy(p, "down"); break; case S_RUN: p = stpcpy(p, "run"); break; case S_FINISH: p = stpcpy(p, "finish"); break; } if (s->ctrl & C_PAUSE) p = stpcpy(p, ", paused"); if (s->ctrl & C_TERM) p = stpcpy(p, ", got TERM"); if (s->state != S_DOWN) switch (s->sd_want) { case W_DOWN: p = stpcpy(p, ", want down"); break; case W_EXIT: p = stpcpy(p, ", want exit"); break; } *p++ = '\n'; write(fd, stat_buf, p - stat_buf); close(fd); } rename_or_warn("supervise/stat.new", s->islog ? "log/supervise/stat" : "log/supervise/stat"+4); /* supervise compatibility */ memset(&status, 0, sizeof(status)); status.time_be64 = SWAP_BE64(s->start.tv_sec + 0x400000000000000aULL); status.time_nsec_be32 = SWAP_BE32(s->start.tv_nsec); status.pid_le32 = SWAP_LE32(s->pid); if (s->ctrl & C_PAUSE) status.paused = 1; if (s->sd_want == W_UP) status.want = 'u'; else status.want = 'd'; if (s->ctrl & C_TERM) status.got_term = 1; status.run_or_finish = s->state; fd = open_trunc_or_warn("supervise/status.new"); if (fd < 0) return; sz = write(fd, &status, sizeof(status)); close(fd); if (sz != sizeof(status)) { warn_cannot("write supervise/status.new"); unlink("supervise/status.new"); return; } rename_or_warn("supervise/status.new", s->islog ? "log/supervise/status" : "log/supervise/status"+4); }
nis_error nis_addmember (const_nis_name member, const_nis_name group) { if (group != NULL && group[0] != '\0') { size_t grouplen = strlen (group); char buf[grouplen + 14 + NIS_MAXNAMELEN]; char domainbuf[grouplen + 2]; nis_result *res, *res2; nis_error status; char *cp, *cp2; cp = rawmemchr (nis_leaf_of_r (group, buf, sizeof (buf) - 1), '\0'); cp = stpcpy (cp, ".groups_dir"); cp2 = nis_domain_of_r (group, domainbuf, sizeof (domainbuf) - 1); if (cp2 != NULL && cp2[0] != '\0') { *cp++ = '.'; stpcpy (cp, cp2); } res = nis_lookup (buf, FOLLOW_LINKS | EXPAND_NAME); if (NIS_RES_STATUS (res) != NIS_SUCCESS) { status = NIS_RES_STATUS (res); nis_freeresult (res); return status; } if (NIS_RES_NUMOBJ (res) != 1 || __type_of (NIS_RES_OBJECT (res)) != NIS_GROUP_OBJ) { nis_freeresult (res); return NIS_INVALIDOBJ; } u_int gr_members_len = NIS_RES_OBJECT(res)->GR_data.gr_members.gr_members_len; nis_name *new_gr_members_val = realloc (NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val, (gr_members_len + 1) * sizeof (nis_name)); if (new_gr_members_val == NULL) goto nomem_out; NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_val = new_gr_members_val; new_gr_members_val[gr_members_len] = strdup (member); if (new_gr_members_val[gr_members_len] == NULL) { nomem_out: nis_freeresult (res); return NIS_NOMEMORY; } ++NIS_RES_OBJECT (res)->GR_data.gr_members.gr_members_len; /* Check the buffer bounds are not exceeded. */ assert (strlen (NIS_RES_OBJECT(res)->zo_name) + 1 < grouplen + 14); cp = stpcpy (buf, NIS_RES_OBJECT(res)->zo_name); *cp++ = '.'; strncpy (cp, NIS_RES_OBJECT (res)->zo_domain, NIS_MAXNAMELEN); res2 = nis_modify (buf, NIS_RES_OBJECT (res)); status = NIS_RES_STATUS (res2); nis_freeresult (res); nis_freeresult (res2); return status; } else return NIS_FAIL; }
/* Return the public key for the keygrip GRIP. The result is stored at RESULT. This function extracts the public key from the private key database. On failure an error code is returned and NULL stored at RESULT. */ gpg_error_t agent_public_key_from_file (ctrl_t ctrl, const unsigned char *grip, gcry_sexp_t *result) { gpg_error_t err; int i, idx; gcry_sexp_t s_skey; char algoname[6]; char elems[7]; gcry_sexp_t uri_sexp, comment_sexp; const char *uri, *comment; size_t uri_length, comment_length; char *format, *p; void *args[4+2+2+1]; /* Size is max. # of elements + 2 for uri + 2 for comment + end-of-list. */ int argidx; gcry_sexp_t list, l2; const char *s; gcry_mpi_t *array; (void)ctrl; *result = NULL; err = read_key_file (grip, &s_skey); if (err) return err; err = key_parms_from_sexp (s_skey, &list, algoname, sizeof algoname, elems, sizeof elems); if (err) { gcry_sexp_release (s_skey); return err; } /* Allocate an array for the parameters and copy them out of the secret key. FIXME: We should have a generic copy function. */ array = xtrycalloc (strlen(elems) + 1, sizeof *array); if (!array) { err = gpg_error_from_syserror (); gcry_sexp_release (list); gcry_sexp_release (s_skey); return err; } for (idx=0, s=elems; *s; s++, idx++ ) { l2 = gcry_sexp_find_token (list, s, 1); if (!l2) { /* Required parameter not found. */ for (i=0; i<idx; i++) gcry_mpi_release (array[i]); xfree (array); gcry_sexp_release (list); gcry_sexp_release (s_skey); return gpg_error (GPG_ERR_BAD_SECKEY); } array[idx] = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); gcry_sexp_release (l2); if (!array[idx]) { /* Required parameter is invalid. */ for (i=0; i<idx; i++) gcry_mpi_release (array[i]); xfree (array); gcry_sexp_release (list); gcry_sexp_release (s_skey); return gpg_error (GPG_ERR_BAD_SECKEY); } } gcry_sexp_release (list); list = NULL; uri = NULL; uri_length = 0; uri_sexp = gcry_sexp_find_token (s_skey, "uri", 0); if (uri_sexp) uri = gcry_sexp_nth_data (uri_sexp, 1, &uri_length); comment = NULL; comment_length = 0; comment_sexp = gcry_sexp_find_token (s_skey, "comment", 0); if (comment_sexp) comment = gcry_sexp_nth_data (comment_sexp, 1, &comment_length); gcry_sexp_release (s_skey); s_skey = NULL; /* FIXME: The following thing is pretty ugly code; we should investigate how to make it cleaner. Probably code to handle canonical S-expressions in a memory buffer is better suited for such a task. After all that is what we do in protect.c. Neeed to find common patterns and write a straightformward API to use them. */ assert (sizeof (size_t) <= sizeof (void*)); format = xtrymalloc (15+7*strlen (elems)+10+15+1+1); if (!format) { err = gpg_error_from_syserror (); for (i=0; array[i]; i++) gcry_mpi_release (array[i]); xfree (array); gcry_sexp_release (uri_sexp); gcry_sexp_release (comment_sexp); return err; } argidx = 0; p = stpcpy (stpcpy (format, "(public-key("), algoname); for (idx=0, s=elems; *s; s++, idx++ ) { *p++ = '('; *p++ = *s; p = stpcpy (p, " %m)"); assert (argidx < DIM (args)); args[argidx++] = &array[idx]; } *p++ = ')'; if (uri) { p = stpcpy (p, "(uri %b)"); assert (argidx+1 < DIM (args)); args[argidx++] = (void *)&uri_length; args[argidx++] = (void *)&uri; } if (comment) { p = stpcpy (p, "(comment %b)"); assert (argidx+1 < DIM (args)); args[argidx++] = (void *)&comment_length; args[argidx++] = (void*)&comment; } *p++ = ')'; *p = 0; assert (argidx < DIM (args)); args[argidx] = NULL; err = gcry_sexp_build_array (&list, NULL, format, args); xfree (format); for (i=0; array[i]; i++) gcry_mpi_release (array[i]); xfree (array); gcry_sexp_release (uri_sexp); gcry_sexp_release (comment_sexp); if (!err) *result = list; return err; }
/** \ingroup rpmfi * Retrieve file names from header. * * The representation of file names in package headers changed in rpm-4.0. * Originally, file names were stored as an array of absolute paths. * In rpm-4.0, file names are stored as separate arrays of dirname's and * basename's, * with a dirname index to associate the correct dirname * with each basname. * * This function is used to retrieve file names independent of how the * file names are represented in the package header. * * @param h header * @param tagN RPMTAG_BASENAMES | PMTAG_ORIGBASENAMES * @param withstate take file state into account? * @retval td tag data container * @return 1 on success */ static int fnTag(Header h, rpmTag tagN, int withstate, rpmtd td) { const char **baseNames, **dirNames; const char *fileStates = NULL; uint32_t *dirIndexes; rpm_count_t count, retcount, dncount; size_t size = 0; rpmTag dirNameTag = RPMTAG_DIRNAMES; rpmTag dirIndexesTag = RPMTAG_DIRINDEXES; int i, j; int rc = 0; /* assume failure */ struct rpmtd_s bnames, dnames, dixs, fstates; if (tagN == RPMTAG_ORIGBASENAMES) { dirNameTag = RPMTAG_ORIGDIRNAMES; dirIndexesTag = RPMTAG_ORIGDIRINDEXES; } if (!headerGet(h, tagN, &bnames, HEADERGET_MINMEM)) { return 0; /* no file list */ } (void) headerGet(h, dirNameTag, &dnames, HEADERGET_MINMEM); (void) headerGet(h, dirIndexesTag, &dixs, HEADERGET_MINMEM); retcount = count = rpmtdCount(&bnames); dncount = rpmtdCount(&dnames); /* Basic sanity checking for our interrelated tags */ if (rpmtdCount(&dixs) != count || dncount < 1 || dncount > count) td->flags |= RPMTD_INVALID; if (withstate) { /* no recorded states means no installed files */ if (!headerGet(h, RPMTAG_FILESTATES, &fstates, HEADERGET_MINMEM)) goto exit; if (rpmtdCount(&fstates) != count) td->flags |= RPMTD_INVALID; fileStates = fstates.data; } if (td->flags & RPMTD_INVALID) goto exit; baseNames = bnames.data; dirNames = dnames.data; dirIndexes = dixs.data; /* * fsm, psm and rpmfi assume the data is stored in a single allocation * block, until those assumptions are removed we need to jump through * a few hoops here and precalculate sizes etc */ for (i = 0; i < count; i++) { if (fileStates && !RPMFILE_IS_INSTALLED(fileStates[i])) { retcount--; continue; } /* Sanity check directory indexes are within bounds */ if (dirIndexes[i] >= dncount) { td->flags |= RPMTD_INVALID; break; } size += strlen(baseNames[i]) + strlen(dirNames[dirIndexes[i]]) + 1; } if (!(td->flags & RPMTD_INVALID)) { char **fileNames = xmalloc(size + (sizeof(*fileNames) * retcount)); char *t = ((char *) fileNames) + (sizeof(*fileNames) * retcount); for (i = 0, j = 0; i < count; i++) { if (fileStates && !RPMFILE_IS_INSTALLED(fileStates[i])) continue; fileNames[j++] = t; t = stpcpy( stpcpy(t, dirNames[dirIndexes[i]]), baseNames[i]); *t++ = '\0'; } td->data = fileNames; td->count = retcount; td->type = RPM_STRING_ARRAY_TYPE; td->flags |= RPMTD_ALLOCED; rc = 1; } exit: rpmtdFreeData(&bnames); rpmtdFreeData(&dnames); rpmtdFreeData(&dixs); /* only safe if the headerGet() on file states was actually called */ if (fileStates) rpmtdFreeData(&fstates); return rc; }
/** * Create (if necessary) directories not explicitly included in package. * @param files file data * @param fs file states * @param plugins rpm plugins handle * @return 0 on success */ static int fsmMkdirs(rpmfiles files, rpmfs fs, rpmPlugins plugins) { DNLI_t dnli = dnlInitIterator(files, fs, 0); struct stat sb; const char *dpath; int dc = rpmfilesDC(files); int rc = 0; int i; int ldnlen = 0; int ldnalloc = 0; char * ldn = NULL; short * dnlx = NULL; dnlx = (dc ? xcalloc(dc, sizeof(*dnlx)) : NULL); if (dnlx != NULL) while ((dpath = dnlNextIterator(dnli)) != NULL) { size_t dnlen = strlen(dpath); char * te, dn[dnlen+1]; dc = dnli->isave; if (dc < 0) continue; dnlx[dc] = dnlen; if (dnlen <= 1) continue; if (dnlen <= ldnlen && rstreq(dpath, ldn)) continue; /* Copy as we need to modify the string */ (void) stpcpy(dn, dpath); /* Assume '/' directory exists, "mkdir -p" for others if non-existent */ for (i = 1, te = dn + 1; *te != '\0'; te++, i++) { if (*te != '/') continue; *te = '\0'; /* Already validated? */ if (i < ldnlen && (ldn[i] == '/' || ldn[i] == '\0') && rstreqn(dn, ldn, i)) { *te = '/'; /* Move pre-existing path marker forward. */ dnlx[dc] = (te - dn); continue; } /* Validate next component of path. */ rc = fsmStat(dn, 1, &sb); /* lstat */ *te = '/'; /* Directory already exists? */ if (rc == 0 && S_ISDIR(sb.st_mode)) { /* Move pre-existing path marker forward. */ dnlx[dc] = (te - dn); } else if (rc == RPMERR_ENOENT) { *te = '\0'; mode_t mode = S_IFDIR | (_dirPerms & 07777); rpmFsmOp op = (FA_CREATE|FAF_UNOWNED); /* Run fsm file pre hook for all plugins */ rc = rpmpluginsCallFsmFilePre(plugins, NULL, dn, mode, op); if (!rc) rc = fsmMkdir(dn, mode); if (!rc) { rc = rpmpluginsCallFsmFilePrepare(plugins, NULL, dn, dn, mode, op); } /* Run fsm file post hook for all plugins */ rpmpluginsCallFsmFilePost(plugins, NULL, dn, mode, op, rc); if (!rc) { rpmlog(RPMLOG_DEBUG, "%s directory created with perms %04o\n", dn, (unsigned)(mode & 07777)); } *te = '/'; } if (rc) break; } if (rc) break; /* Save last validated path. */ if (ldnalloc < (dnlen + 1)) { ldnalloc = dnlen + 100; ldn = xrealloc(ldn, ldnalloc); } if (ldn != NULL) { /* XXX can't happen */ strcpy(ldn, dn); ldnlen = dnlen; } } free(dnlx); free(ldn); dnlFreeIterator(dnli); return rc; }
int copyinout(Ftw_t* ftw) { register File_t* f = &state.out->file; register char* s; register off_t c; register ssize_t n; register int rfd; register int wfd; if (getfile(state.out, f, ftw) && selectfile(state.out, f)) { s = f->name; f->name = stash(&state.out->path.copy, NiL, state.pwdlen + f->namesize); strcpy(stpcpy(f->name, state.pwd), s + (*s == '/')); if ((wfd = openout(state.out, f)) >= 0) { if ((rfd = openin(state.out, f)) >= 0) { #if defined(SEEK_DATA) && defined(SEEK_HOLE) off_t data; off_t hole; int more; data = 0; more = 1; while (more) { if ((hole = lseek(rfd, data, SEEK_HOLE)) < data) { hole = lseek(rfd, 0, SEEK_END); more = 0; } while ((c = hole - data) > 0) { if (c > state.buffersize) c = state.buffersize; if (lseek(rfd, data, SEEK_SET) != data || (n = read(rfd, state.tmp.buffer, (size_t)c)) <= 0) { error(ERROR_SYSTEM|2, "%s: read error", f->name); more = 0; break; } if (lseek(wfd, data, SEEK_SET) != data || write(wfd, state.tmp.buffer, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); more = 0; break; } state.out->io->count += n; data += n; } if (!more) break; if ((data = lseek(rfd, hole, SEEK_DATA)) < hole) { if ((data = lseek(rfd, -1, SEEK_END)) < 0 || (data + 1) > hole && (lseek(wfd, data, SEEK_SET) != data || write(wfd, "", 1) != 1)) error(ERROR_SYSTEM|2, "%s: write error", f->name); state.out->io->count += 1; break; } } #else holeinit(wfd); for (c = f->st->st_size; c > 0; c -= n) { if ((n = read(rfd, state.tmp.buffer, (size_t)((c > state.buffersize) ? state.buffersize : c))) <= 0) { error(ERROR_SYSTEM|2, "%s: read error", f->name); break; } if (holewrite(wfd, state.tmp.buffer, n) != n) { error(ERROR_SYSTEM|2, "%s: write error", f->name); break; } state.out->io->count += n; } holedone(wfd); #endif closeout(state.out, f, wfd); closein(state.out, f, rfd); setfile(state.out, f); listentry(f); } else closeout(state.out, f, wfd); } else if (wfd != -1) listentry(f); } return 0; }