int gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct iso646_data *new_data; enum direction dir = illegal_dir; int result; enum variant var = 0; for (const char *name = names; *name != '\0'; name = __rawmemchr (name, '\0') + 1) { if (__strcasecmp (step->__from_name, name) == 0) { dir = from_iso646; break; } else if (__strcasecmp (step->__to_name, name) == 0) { dir = to_iso646; break; } ++var; } result = __GCONV_NOCONV; if (__builtin_expect (dir, from_iso646) != illegal_dir) { new_data = (struct iso646_data *) malloc (sizeof (struct iso646_data)); result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; step->__data = new_data; if (dir == from_iso646) { step->__min_needed_from = MIN_NEEDED_FROM; step->__max_needed_from = MIN_NEEDED_FROM; step->__min_needed_to = MIN_NEEDED_TO; step->__max_needed_to = MIN_NEEDED_TO; } else { step->__min_needed_from = MIN_NEEDED_TO; step->__max_needed_from = MIN_NEEDED_TO; step->__min_needed_to = MIN_NEEDED_FROM; step->__max_needed_to = MIN_NEEDED_FROM; } step->__stateful = 0; result = __GCONV_OK; } } return result; }
int gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct iso646_data *new_data; enum direction dir = illegal_dir; enum variant var; int result; for (var = sizeof (names) / sizeof (names[0]) - 1; var > illegal_var; --var) if (__strcasecmp (step->__from_name, names[var]) == 0) { dir = from_iso646; break; } else if (__strcasecmp (step->__to_name, names[var]) == 0) { dir = to_iso646; break; } result = __GCONV_NOCONV; if (__builtin_expect (dir, from_iso646) != illegal_dir) { new_data = (struct iso646_data *) malloc (sizeof (struct iso646_data)); result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; step->__data = new_data; if (dir == from_iso646) { step->__min_needed_from = MIN_NEEDED_FROM; step->__max_needed_from = MIN_NEEDED_FROM; step->__min_needed_to = MIN_NEEDED_TO; step->__max_needed_to = MIN_NEEDED_TO; } else { step->__min_needed_from = MIN_NEEDED_TO; step->__max_needed_from = MIN_NEEDED_TO; step->__min_needed_to = MIN_NEEDED_FROM; step->__max_needed_to = MIN_NEEDED_FROM; } step->__stateful = 0; result = __GCONV_OK; } } return result; }
int gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct utf8_data *new_data; enum direction dir = illegal_dir; int emit_bom; int result; emit_bom = (__strcasecmp (step->__to_name, "UTF-32//") == 0); if (__strcasecmp (step->__from_name, "ISO-10646/UTF8/") == 0 && (__strcasecmp (step->__to_name, "UTF-32//") == 0 || __strcasecmp (step->__to_name, "UTF-32BE//") == 0 || __strcasecmp (step->__to_name, "INTERNAL") == 0)) { dir = from_utf8; } else if (__strcasecmp (step->__to_name, "ISO-10646/UTF8/") == 0 && (__strcasecmp (step->__from_name, "UTF-32BE//") == 0 || __strcasecmp (step->__from_name, "INTERNAL") == 0)) { dir = to_utf8; } result = __GCONV_NOCONV; if (dir != illegal_dir) { new_data = (struct utf8_data *) malloc (sizeof (struct utf8_data)); result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->emit_bom = emit_bom; step->__data = new_data; if (dir == from_utf8) { step->__min_needed_from = MIN_NEEDED_FROM; step->__max_needed_from = MIN_NEEDED_FROM; step->__min_needed_to = MIN_NEEDED_TO; step->__max_needed_to = MIN_NEEDED_TO; } else { step->__min_needed_from = MIN_NEEDED_TO; step->__max_needed_from = MIN_NEEDED_TO; step->__min_needed_to = MIN_NEEDED_FROM; step->__max_needed_to = MIN_NEEDED_FROM; } step->__stateful = 0; result = __GCONV_OK; } } return result; }
int gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct utf16_data *new_data; enum direction dir = illegal_dir; enum variant var = illegal_var; int result; if (__strcasecmp (step->__from_name, "UTF-16//") == 0) { dir = from_utf16; var = UTF_16; } else if (__strcasecmp (step->__to_name, "UTF-16//") == 0) { dir = to_utf16; var = UTF_16; } else if (__strcasecmp (step->__from_name, "UTF-16BE//") == 0) { dir = from_utf16; var = UTF_16BE; } else if (__strcasecmp (step->__to_name, "UTF-16BE//") == 0) { dir = to_utf16; var = UTF_16BE; } else if (__strcasecmp (step->__from_name, "UTF-16LE//") == 0) { dir = from_utf16; var = UTF_16LE; } else if (__strcasecmp (step->__to_name, "UTF-16LE//") == 0) { dir = to_utf16; var = UTF_16LE; } result = __GCONV_NOCONV; if (__builtin_expect (dir, to_utf16) != illegal_dir) { new_data = (struct utf16_data *) malloc (sizeof (struct utf16_data)); result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; step->__data = new_data; if (dir == from_utf16) { step->__min_needed_from = MIN_NEEDED_FROM; step->__max_needed_from = MAX_NEEDED_FROM; step->__min_needed_to = MIN_NEEDED_TO; step->__max_needed_to = MIN_NEEDED_TO; } else { step->__min_needed_from = MIN_NEEDED_TO; step->__max_needed_from = MIN_NEEDED_TO; step->__min_needed_to = MIN_NEEDED_FROM; step->__max_needed_to = MAX_NEEDED_FROM; } step->__stateful = 0; result = __GCONV_OK; } } return result; }
/* Test whether given (host,user,domain) triple is in NETGROUP. */ int innetgr (const char *netgroup, const char *host, const char *user, const char *domain) { #ifdef USE_NSCD if (__nss_not_use_nscd_netgroup > 0 && ++__nss_not_use_nscd_netgroup > NSS_NSCD_RETRY) __nss_not_use_nscd_netgroup = 0; if (!__nss_not_use_nscd_netgroup && !__nss_database_custom[NSS_DBSIDX_netgroup]) { int result = __nscd_innetgr (netgroup, host, user, domain); if (result >= 0) return result; } #endif union { enum nss_status (*f) (const char *, struct __netgrent *); void *ptr; } setfct; void (*endfct) (struct __netgrent *); int (*getfct) (struct __netgrent *, char *, size_t, int *); struct __netgrent entry; int result = 0; const char *current_group = netgroup; memset (&entry, '\0', sizeof (entry)); /* Walk through the services until we found an answer or we shall not work further. We can do some optimization here. Since all services must provide the `setnetgrent' function we can do all the work during one walk through the service list. */ while (1) { int no_more = setup (&setfct.ptr, &entry.nip); while (! no_more) { assert (entry.data == NULL); /* Open netgroup. */ enum nss_status status = DL_CALL_FCT (*setfct.f, (current_group, &entry)); if (status == NSS_STATUS_SUCCESS && (getfct = __nss_lookup_function (entry.nip, "getnetgrent_r")) != NULL) { char buffer[1024]; while (DL_CALL_FCT (*getfct, (&entry, buffer, sizeof buffer, &errno)) == NSS_STATUS_SUCCESS) { if (entry.type == group_val) { /* Make sure we haven't seen the name before. */ struct name_list *namep; for (namep = entry.known_groups; namep != NULL; namep = namep->next) if (strcmp (entry.val.group, namep->name) == 0) break; if (namep == NULL) for (namep = entry.needed_groups; namep != NULL; namep = namep->next) if (strcmp (entry.val.group, namep->name) == 0) break; if (namep == NULL && strcmp (netgroup, entry.val.group) != 0) { size_t group_len = strlen (entry.val.group) + 1; namep = (struct name_list *) malloc (sizeof (*namep) + group_len); if (namep == NULL) { /* Out of memory, simply return. */ result = -1; break; } namep->next = entry.needed_groups; memcpy (namep->name, entry.val.group, group_len); entry.needed_groups = namep; } } else { if ((entry.val.triple.host == NULL || host == NULL || __strcasecmp (entry.val.triple.host, host) == 0) && (entry.val.triple.user == NULL || user == NULL || strcmp (entry.val.triple.user, user) == 0) && (entry.val.triple.domain == NULL || domain == NULL || __strcasecmp (entry.val.triple.domain, domain) == 0)) { result = 1; break; } } } /* If we found one service which does know the given netgroup we don't try further. */ status = NSS_STATUS_RETURN; } /* Free all resources of the service. */ endfct = __nss_lookup_function (entry.nip, "endnetgrent"); if (endfct != NULL) DL_CALL_FCT (*endfct, (&entry)); if (result != 0) break; /* Look for the next service. */ no_more = __nss_next2 (&entry.nip, "setnetgrent", NULL, &setfct.ptr, status, 0); } if (result == 0 && entry.needed_groups != NULL) { struct name_list *tmp = entry.needed_groups; entry.needed_groups = tmp->next; tmp->next = entry.known_groups; entry.known_groups = tmp; current_group = tmp->name; continue; } /* No way out. */ break; } /* Free the memory. */ free_memory (&entry); return result == 1; }
int ruserpass (const char *host, const char **aname, const char **apass) { char *hdir, *buf, *tmp; char myname[1024], *mydomain; int t, usedefault = 0; struct stat64 stb; hdir = __libc_secure_getenv("HOME"); if (hdir == NULL) { /* If we can't get HOME, fail instead of trying ".", which is no improvement. This really should call getpwuid(getuid()). */ /*hdir = ".";*/ return -1; } buf = alloca (strlen (hdir) + 8); __stpcpy (__stpcpy (buf, hdir), "/.netrc"); cfile = fopen(buf, "rce"); if (cfile == NULL) { if (errno != ENOENT) warn("%s", buf); return (0); } /* No threads use this stream. */ __fsetlocking (cfile, FSETLOCKING_BYCALLER); if (__gethostname(myname, sizeof(myname)) < 0) myname[0] = '\0'; mydomain = __strchrnul(myname, '.'); next: while ((t = token())) switch(t) { case DEFAULT: usedefault = 1; /* FALL THROUGH */ case MACHINE: if (!usedefault) { if (token() != ID) continue; /* * Allow match either for user's input host name * or official hostname. Also allow match of * incompletely-specified host in local domain. */ if (__strcasecmp(host, tokval) == 0) goto match; /* if (__strcasecmp(hostname, tokval) == 0) goto match; if ((tmp = strchr(hostname, '.')) != NULL && __strcasecmp(tmp, mydomain) == 0 && __strncasecmp(hostname, tokval, tmp-hostname) == 0 && tokval[tmp - hostname] == '\0') goto match; */ if ((tmp = strchr(host, '.')) != NULL && __strcasecmp(tmp, mydomain) == 0 && __strncasecmp(host, tokval, tmp - host) == 0 && tokval[tmp - host] == '\0') goto match; continue; } match: while ((t = token()) && t != MACHINE && t != DEFAULT) switch(t) { case LOGIN: if (token()) { if (*aname == 0) { char *newp; newp = malloc((unsigned) strlen(tokval) + 1); if (newp == NULL) { warnx(_("out of memory")); goto bad; } *aname = strcpy(newp, tokval); } else { if (strcmp(*aname, tokval)) goto next; } } break; case PASSWD: if (strcmp(*aname, "anonymous") && fstat64(fileno(cfile), &stb) >= 0 && (stb.st_mode & 077) != 0) { warnx(_("Error: .netrc file is readable by others.")); warnx(_("Remove password or make file unreadable by others.")); goto bad; } if (token() && *apass == 0) { char *newp; newp = malloc((unsigned) strlen(tokval) + 1); if (newp == NULL) { warnx(_("out of memory")); goto bad; } *apass = strcpy(newp, tokval); } break; case ACCOUNT: break; case MACDEF: break; default: warnx(_("Unknown .netrc keyword %s"), tokval); break; } goto done; } done: (void) fclose(cfile); return (0); bad: (void) fclose(cfile); return (-1); }
install_handler (void) { struct sigaction sa; const char *sigs = getenv ("SEGFAULT_SIGNALS"); const char *name; sa.sa_handler = (void *) catch_segfault; sigemptyset (&sa.sa_mask); sa.sa_flags = SA_RESTART; /* Maybe we are expected to use an alternative stack. */ if (getenv ("SEGFAULT_USE_ALTSTACK") != 0) { void *stack_mem = malloc (2 * SIGSTKSZ); struct sigaltstack ss; if (stack_mem != NULL) { ss.ss_sp = stack_mem; ss.ss_flags = 0; ss.ss_size = 2 * SIGSTKSZ; if (sigaltstack (&ss, NULL) == 0) sa.sa_flags |= SA_ONSTACK; } } if (sigs == NULL) sigaction (SIGSEGV, &sa, NULL); else if (sigs[0] == '\0') /* Do not do anything. */ return; else { const char *where; int all = __strcasecmp (sigs, "all") == 0; #define INSTALL_FOR_SIG(sig, name) \ where = __strcasestr (sigs, name); \ if (all || (where != NULL \ && (where == sigs || !isalnum (where[-1])) \ && !isalnum (where[sizeof (name) - 1]))) \ sigaction (sig, &sa, NULL); INSTALL_FOR_SIG (SIGSEGV, "segv"); INSTALL_FOR_SIG (SIGILL, "ill"); #ifdef SIGBUS INSTALL_FOR_SIG (SIGBUS, "bus"); #endif #ifdef SIGSTKFLT INSTALL_FOR_SIG (SIGSTKFLT, "stkflt"); #endif INSTALL_FOR_SIG (SIGABRT, "abrt"); INSTALL_FOR_SIG (SIGFPE, "fpe"); } /* Preserve the output file name if there is any given. */ name = getenv ("SEGFAULT_OUTPUT_NAME"); if (name != NULL && name[0] != '\0') { int ret = access (name, R_OK | W_OK); if (ret == 0 || (ret == -1 && errno == ENOENT)) fname = __strdup (name); } }
int gconv_init (struct __gconv_step *step) { /* Determine which direction. */ struct iso2022jp_data *new_data; enum direction dir = illegal_dir; enum variant var = illegal_var; int result; if (__strcasecmp (step->__from_name, "ISO-2022-JP//") == 0) { dir = from_iso2022jp; var = iso2022jp; } else if (__strcasecmp (step->__to_name, "ISO-2022-JP//") == 0) { dir = to_iso2022jp; var = iso2022jp; } else if (__strcasecmp (step->__from_name, "ISO-2022-JP-2//") == 0) { dir = from_iso2022jp; var = iso2022jp2; } else if (__strcasecmp (step->__to_name, "ISO-2022-JP-2//") == 0) { dir = to_iso2022jp; var = iso2022jp2; } result = __GCONV_NOCONV; if (__builtin_expect (dir, from_iso2022jp) != illegal_dir) { new_data = (struct iso2022jp_data *) malloc (sizeof (struct iso2022jp_data)); result = __GCONV_NOMEM; if (new_data != NULL) { new_data->dir = dir; new_data->var = var; step->__data = new_data; if (dir == from_iso2022jp) { step->__min_needed_from = FROM_LOOP_MIN_NEEDED_FROM; step->__max_needed_from = FROM_LOOP_MAX_NEEDED_FROM; step->__min_needed_to = FROM_LOOP_MIN_NEEDED_TO; step->__max_needed_to = FROM_LOOP_MAX_NEEDED_TO; } else { step->__min_needed_from = TO_LOOP_MIN_NEEDED_FROM; step->__max_needed_from = TO_LOOP_MAX_NEEDED_FROM; step->__min_needed_to = TO_LOOP_MIN_NEEDED_TO; step->__max_needed_to = TO_LOOP_MAX_NEEDED_TO; } /* Yes, this is a stateful encoding. */ step->__stateful = 1; result = __GCONV_OK; } } return result; }