ldapvi-1.7/0000755000175000017500000000000010617054704011604 5ustar daviddavidldapvi-1.7/print.c0000644000175000017500000003045510617054666013122 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "common.h" t_print_binary_mode print_binary_mode = PRINT_UTF8; static void write_backslashed(FILE *s, char *ptr, int n) { int i; for (i = 0; i < n; i++) { char c = ptr[i]; if (c == '\n' || c == '\\') fputc('\\', s); fputc(c, s); } if (ferror(s)) syserr(); } static int utf8_string_p(unsigned char *str, int n) { int i = 0; while (i < n) { unsigned char c = str[i++]; if (c >= 0xfe) return 0; if (c >= 0xfc) { unsigned char d; if ((n - i < 5) || ((d=str[i++]) ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (c < 0xfd && d < 0x84)) return 0; } else if (c >= 0xf8) { unsigned char d; if ((n - i < 4) || ((d=str[i++]) ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (c < 0xf9 && d < 0x88)) return 0; } else if (c >= 0xf0) { unsigned char d; if ((n - i < 3) || ((d=str[i++]) ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (str[i++] ^ 0x80) >= 0x40 || (c < 0xf1 && d < 0x90)) return 0; } else if (c >= 0xe0) { unsigned char d, e; unsigned code; if ((n - i < 2) || ((d=str[i++]) ^ 0x80) >= 0x40 || ((e=str[i++]) ^ 0x80) >= 0x40 || (c < 0xe1 && d < 0xa0)) return 0; code = ((int) c & 0x0f) << 12 | ((int) d ^ 0x80) << 6 | ((int) e ^ 0x80); if ((0xd800 <= code) && (code <= 0xdfff) || code == 0xfffe || code == 0xffff) return 0; } else if (c >= 0x80) { unsigned char d; if ((n - i < 1) || ((d=str[i++]) ^ 0x80) >= 0x40 || (c < 0xc2)) return 0; } else if (c == 0) return 0; } return 1; } static int readable_string_p(char *str, int n) { int i; for (i = 0; i < n; i++) { char c = str[i]; if (c < 32 && c != '\n' && c != '\t') return 0; } return 1; } static int safe_string_p(char *str, int n) { unsigned char c; int i; if (n == 0) return 1; c = str[0]; if ((c == ' ') || (c == ':') || (c == '<')) return 0; for (i = 0; i < n; i++) { c = str[i]; if ((c == '\0') || (c == '\r') || (c == '\n') || (c >= 0x80)) return 0; } return 1; } static void print_attrval(FILE *s, char *str, int len, int prefernocolon) { int readablep; switch (print_binary_mode) { case PRINT_ASCII: readablep = readable_string_p(str, len); break; case PRINT_UTF8: readablep = utf8_string_p((unsigned char *) str, len); break; case PRINT_JUNK: readablep = 1; break; default: abort(); } if (!readablep) { fputs(":: ", s); print_base64((unsigned char *) str, len, s); } else if (prefernocolon) { fputc(' ', s); write_backslashed(s, str, len); } else if (!safe_string_p(str, len)) { fputs(":; ", s); write_backslashed(s, str, len); } else { fputs(": ", s); fwrite(str, 1, len, s); } } static void print_attribute(FILE *s, tattribute *attribute) { GPtrArray *values = attribute_values(attribute); int j; for (j = 0; j < values->len; j++) { GArray *av = g_ptr_array_index(values, j); fputs(attribute_ad(attribute), s); print_attrval(s, av->data, av->len, 0); fputc('\n', s); } if (ferror(s)) syserr(); } static void print_entroid_bottom(FILE *s, tentroid *entroid) { int i; LDAPAttributeType *at; for (i = 0; i < entroid->must->len; i++) { at = g_ptr_array_index(entroid->must, i); fprintf(s, "# required attribute not shown: %s\n", attributetype_name(at)); } for (i = 0; i < entroid->may->len; i++) { at = g_ptr_array_index(entroid->may, i); fprintf(s, "#%s: \n", attributetype_name(at)); } } void print_ldapvi_entry(FILE *s, tentry *entry, char *key, tentroid *entroid) { GPtrArray *attributes = entry_attributes(entry); int i; fputc('\n', s); fputs(key ? key : "entry", s); fputc(' ', s); fputs(entry_dn(entry), s); fputc('\n', s); if (ferror(s)) syserr(); if (entroid) fputs(entroid->comment->str, s); for (i = 0; i < attributes->len; i++) { tattribute *attribute = g_ptr_array_index(attributes, i); char *ad = attribute_ad(attribute); if ( entroid && !entroid_remove_ad(entroid, ad)) fprintf(s, "# WARNING: %s not allowed by schema\n", ad); print_attribute(s, attribute); } if (entroid) print_entroid_bottom(s, entroid); } static void print_ldapvi_ldapmod(FILE *s, LDAPMod *mod) { struct berval **values = mod->mod_bvalues; switch (mod->mod_op & ~LDAP_MOD_BVALUES) { case LDAP_MOD_ADD: fputs("add", s); break; case LDAP_MOD_DELETE: fputs("delete", s); break; case LDAP_MOD_REPLACE: fputs("replace", s); break; default: abort(); } print_attrval(s, mod->mod_type, strlen(mod->mod_type), 0); fputc('\n', s); for (; *values; values++) { struct berval *value = *values; print_attrval(s, value->bv_val, value->bv_len, 0); fputc('\n', s); } if (ferror(s)) syserr(); } void print_ldapvi_modify(FILE *s, char *dn, LDAPMod **mods) { fputs("\nmodify", s); print_attrval(s, dn, strlen(dn), 1); fputc('\n', s); for (; *mods; mods++) print_ldapvi_ldapmod(s, *mods); if (ferror(s)) syserr(); } void print_ldapvi_rename(FILE *s, char *olddn, char *newdn, int deleteoldrdn) { fputs("\nrename", s); print_attrval(s, olddn, strlen(olddn), 1); fputs(deleteoldrdn ? "\nreplace" : "\nadd", s); print_attrval(s, newdn, strlen(newdn), 0); fputc('\n', s); if (ferror(s)) syserr(); } static GString * rdns2gstring(char **ptr) { GString *result = g_string_new(""); if (*ptr) g_string_append(result, *ptr); ptr++; for (; *ptr; ptr++) { g_string_append_c(result, ','); g_string_append(result, *ptr); } return result; } /* simple version of _rename without new superior */ void print_ldapvi_modrdn(FILE *s, char *olddn, char *newrdn, int deleteoldrdn) { char **newrdns = ldap_explode_dn(olddn, 0); GString *newdn; char *tmp; fputs("\nrename", s); print_attrval(s, olddn, strlen(olddn), 1); fputs(deleteoldrdn ? "\nreplace" : "\nadd", s); /* fixme, siehe notes */ tmp = *newrdns; *newrdns = newrdn; newdn = rdns2gstring(newrdns); print_attrval(s, newdn->str, newdn->len, 0); fputc('\n', s); g_string_free(newdn, 1); *newrdns = tmp; if (ferror(s)) syserr(); ldap_value_free(newrdns); } void print_ldapvi_add(FILE *s, char *dn, LDAPMod **mods) { fputs("\nadd", s); print_attrval(s, dn, strlen(dn), 1); fputc('\n', s); for (; *mods; mods++) { LDAPMod *mod = *mods; struct berval **values = mod->mod_bvalues; for (; *values; values++) { struct berval *value = *values; fputs(mod->mod_type, s); print_attrval(s, value->bv_val, value->bv_len, 0); fputc('\n', s); } } if (ferror(s)) syserr(); } void print_ldapvi_delete(FILE *s, char *dn) { fputs("\ndelete", s); print_attrval(s, dn, strlen(dn), 1); fputc('\n', s); if (ferror(s)) syserr(); } static void print_ldif_line(FILE *s, char *ad, char *str, int len) { if (len == -1) len = strlen(str); fputs(ad, s); if (safe_string_p(str, len)) { fputs(": ", s); fwrite(str, len, 1, s); } else { fputs(":: ", s); print_base64((unsigned char *) str, len, s); } fputs("\n", s); } static void print_ldif_bervals(FILE *s, char *ad, struct berval **values) { for (; *values; values++) { struct berval *value = *values; print_ldif_line(s, ad, value->bv_val, value->bv_len); } if (ferror(s)) syserr(); } void print_ldif_modify(FILE *s, char *dn, LDAPMod **mods) { fputc('\n', s); print_ldif_line(s, "dn", dn, -1); fputs("changetype: modify\n", s); for (; *mods; mods++) { LDAPMod *mod = *mods; switch (mod->mod_op & ~LDAP_MOD_BVALUES) { case LDAP_MOD_ADD: fputs("add: ", s); break; case LDAP_MOD_DELETE: fputs("delete: ", s); break; case LDAP_MOD_REPLACE: fputs("replace: ", s); break; default: abort(); } fputs(mod->mod_type, s); fputc('\n', s); print_ldif_bervals(s, mod->mod_type, mod->mod_bvalues); fputs("-\n", s); } if (ferror(s)) syserr(); } void print_ldif_add(FILE *s, char *dn, LDAPMod **mods) { fputc('\n', s); print_ldif_line(s, "dn", dn, -1); fputs("changetype: add\n", s); for (; *mods; mods++) { LDAPMod *mod = *mods; print_ldif_bervals(s, mod->mod_type, mod->mod_bvalues); } if (ferror(s)) syserr(); } void print_ldif_rename(FILE *s, char *olddn, char *newdn, int deleteoldrdn) { char **newrdns = ldap_explode_dn(newdn, 0); int isRootDSE = !*newrdns; GString *sup; fputc('\n', s); print_ldif_line(s, "dn", olddn, -1); fputs("changetype: modrdn\n", s); print_ldif_line(s, "newrdn", isRootDSE ? "" : *newrdns, -1); fprintf(s, "deleteoldrdn: %d\n", !!deleteoldrdn); if (isRootDSE || !newrdns[1]) fputs("newsuperior:\n", s); else { sup = rdns2gstring(newrdns + 1); print_ldif_line(s, "newsuperior", sup->str, sup->len); g_string_free(sup, 1); } if (ferror(s)) syserr(); ldap_value_free(newrdns); } /* simple version of _rename without new superior */ void print_ldif_modrdn(FILE *s, char *olddn, char *newrdn, int deleteoldrdn) { fputc('\n', s); print_ldif_line(s, "dn", olddn, -1); fputs("changetype: modrdn\n", s); print_ldif_line(s, "newrdn", newrdn, -1); fprintf(s, "deleteoldrdn: %d\n", !!deleteoldrdn); if (ferror(s)) syserr(); } void print_ldif_delete(FILE *s, char *dn) { fputc('\n', s); print_ldif_line(s, "dn", dn, -1); fputs("changetype: delete\n", s); if (ferror(s)) syserr(); } void print_ldapvi_message(FILE *s, LDAP *ld, LDAPMessage *entry, int key, tentroid *entroid) { char *dn, *ad; BerElement *ber; fprintf(s, "\n%d", key); dn = ldap_get_dn(ld, entry); print_attrval(s, dn, strlen(dn), 1); ldap_memfree(dn); fputc('\n', s); if (entroid) fputs(entroid->comment->str, s); for (ad = ldap_first_attribute(ld, entry, &ber); ad; ad = ldap_next_attribute(ld, entry, ber)) { struct berval **values = ldap_get_values_len(ld, entry, ad); struct berval **ptr; if (!values) continue; if (entroid) entroid_remove_ad(entroid, ad); for (ptr = values; *ptr; ptr++) { fputs(ad, s); print_attrval(s, (*ptr)->bv_val, (*ptr)->bv_len, 0); fputc('\n', s); } ldap_memfree(ad); ldap_value_free_len(values); } ber_free(ber, 0); if (entroid) print_entroid_bottom(s, entroid); if (ferror(s)) syserr(); } void print_ldif_entry(FILE *s, tentry *entry, char *key, tentroid *entroid) { int i; GPtrArray *attributes = entry_attributes(entry); fputc('\n', s); print_ldif_line(s, "dn", entry_dn(entry), -1); if (key) fprintf(s, "ldapvi-key: %s\n", key); if (entroid) fputs(entroid->comment->str, s); for (i = 0; i < attributes->len; i++) { tattribute *attribute = g_ptr_array_index(attributes, i); char *ad = attribute_ad(attribute); GPtrArray *values = attribute_values(attribute); int j; if ( entroid && !entroid_remove_ad(entroid, ad)) fprintf(s, "# WARNING: %s not allowed by schema\n", ad); for (j = 0; j < values->len; j++) { GArray *av = g_ptr_array_index(values, j); print_ldif_line(s, ad, av->data, av->len); } } if (entroid) print_entroid_bottom(s, entroid); } void print_ldif_message(FILE *s, LDAP *ld, LDAPMessage *entry, int key, tentroid *entroid) { char *dn, *ad; BerElement *ber; fputc('\n', s); if (entroid) fputs(entroid->comment->str, s); dn = ldap_get_dn(ld, entry); print_ldif_line(s, "dn", dn, -1); ldap_memfree(dn); if (key != -1) fprintf(s, "ldapvi-key: %d\n", key); for (ad = ldap_first_attribute(ld, entry, &ber); ad; ad = ldap_next_attribute(ld, entry, ber)) { struct berval **values = ldap_get_values_len(ld, entry, ad); if (entroid) entroid_remove_ad(entroid, ad); print_ldif_bervals(s, ad, values); ldap_memfree(ad); ldap_value_free_len(values); } ber_free(ber, 0); if (entroid) print_entroid_bottom(s, entroid); if (ferror(s)) syserr(); } ldapvi-1.7/arguments.c0000644000175000017500000005060510617054666013772 0ustar daviddavid/* -*- mode: c; c-backslash-column: 78; c-backslash-max-column: 78 -*- * * Copyright (c) 2003,2004,2005,2006 David Lichteblau * Copyright (c) 2006 Perry Nguyen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include "common.h" #include "version.h" static void parse_configuration(char *, cmdline *, GPtrArray *); #define USAGE \ "Usage: ldapvi [OPTION]... [FILTER] [AD]...\n" \ "Quickstart:\n" \ " ldapvi --discover --host HOSTNAME\n" \ "Perform an LDAP search and update results using a text editor.\n" \ "\n" \ "Other usage:\n" \ " ldapvi --out [OPTION]... [FILTER] [AD]... Print entries\n" \ " ldapvi --in [OPTION]... [FILENAME] Load change records\n" \ " ldapvi --delete [OPTION]... DN... Edit a delete record\n" \ " ldapvi --rename [OPTION]... DN1 DN2 Edit a rename record\n" \ "\n" \ "Connection options:\n" \ " -h, --host URL Server.\n" \ " -D, --user USER Search filter or DN: User to bind as. [1]\n" \ " Sets --bind simple.\n" \ " -w, --password SECRET Password (also valid for SASL).\n" \ " --bind [simple,sasl]\n" \ " Disable or enable SASL.\n" \ " --bind-dialog [never,auto,always]\n" \ " Interactive login dialog.\n" \ "\n" \ "SASL options (these parameters set --bind sasl):\n" \ " -I, --sasl-interactive Set --bind-dialog always.\n" \ " -O, --sasl-secprops P SASL security properties.\n" \ " -Q, --sasl-quiet Set --bind-dialog never.\n" \ " -R, --sasl-realm R SASL realm.\n" \ " -U, --sasl-authcid AC SASL authentication identity.\n" \ " -X, --sasl-authzid AZ SASL authorization identity.\n" \ " -Y, --sasl-mech MECH SASL mechanism.\n" \ "\n" \ "Search parameters:\n" \ " -b, --base DN Search base.\n" \ " -s, --scope SCOPE Search scope. One of base|one|sub.\n" \ " -S, --sort KEYS Sort control (critical).\n" \ "\n" \ "Miscellaneous options:\n" \ " --add (Only with --in, --ldapmodify:)\n" \ " Treat attrval records as new entries to add.\n" \ " -o, --class OBJCLASS Class to add. Can be repeated. Implies -A.\n" \ " --config Print parameters in ldap.conf syntax.\n" \ " -c --continue Ignore LDAP errors and continue processing.\n" \ " --deleteoldrdn (Only with --rename:) Delete the old RDN.\n" \ " -a, --deref never|searching|finding|always\n" \ " -d, --discover Auto-detect naming contexts. [2]\n" \ " -A, --empty Don't search, start with empty file. See -o.\n" \ " --encoding [ASCII|UTF-8|binary]\n" \ " The encoding to allow. Default is UTF-8.\n" \ " -H, --help This help.\n" \ " --ldap-conf Always read libldap configuration.\n" \ " -m, --may Show missing optional attributes as comments.\n" \ " -M, --managedsait manageDsaIT control (critical).\n" \ " --noquestions Commit without asking for confirmation.\n" \ " -!, --noninteractive Never ask any questions.\n" \ " -q, --quiet Disable progress output.\n" \ " -R, --read DN Same as -b DN -s base '(objectclass=*)' + *\n" \ " -Z, --starttls Require startTLS.\n" \ " --tls [never|allow|try|strict] Level of TLS strictess.\n" \ " -v, --verbose Note every update.\n" \ "\n" \ "Shortcuts:\n" \ " --ldapsearch Short for --quiet --out\n" \ " --ldapmodify Short for --noninteractive --in\n" \ " --ldapdelete Short for --noninteractive --delete\n" \ " --ldapmoddn Short for --noninteractive --rename\n" \ "\n" \ "Environment variables: VISUAL, EDITOR, PAGER.\n" \ "\n" \ "[1] User names can be specified as distinguished names:\n" \ " uid=foo,ou=bar,dc=acme,dc=com\n" \ " or search filters:\n" \ " (uid=foo)\n" \ " Note the use of parenthesis, which can be omitted from search\n" \ " filters usually but are required here. For this searching bind to\n" \ " work, your client library must be configured with appropriate\n" \ " default search parameters.\n" \ "\n" \ "[2] Repeat the search for each naming context found and present the\n" \ " concatenation of all search results. Conflicts with --base.\n" \ " With --config, show a BASE configuration line for each context.\n" \ "\n" \ "A special (offline) option is --diff, which compares two files\n" \ "and writes any changes to standard output in LDIF format.\n" \ "\n" \ "Report bugs to \"ldapvi@lists.askja.de\"." enum ldapvi_option_numbers { OPTION_TLS = 1000, OPTION_ENCODING, OPTION_LDIF, OPTION_LDAPVI, OPTION_OUT, OPTION_IN, OPTION_DELETE, OPTION_RENAME, OPTION_MODRDN, OPTION_NOQUESTIONS, OPTION_LDAPSEARCH, OPTION_LDAPMODIFY, OPTION_LDAPDELETE, OPTION_LDAPMODDN, OPTION_LDAPMODRDN, OPTION_ADD, OPTION_CONFIG, OPTION_READ, OPTION_LDAP_CONF, OPTION_BIND, OPTION_BIND_DIALOG }; static struct poptOption options[] = { {"host", 'h', POPT_ARG_STRING, 0, 'h', 0, 0}, {"scope", 's', POPT_ARG_STRING, 0, 's', 0, 0}, {"base", 'b', POPT_ARG_STRING, 0, 'b', 0, 0}, {"user", 'D', POPT_ARG_STRING, 0, 'D', 0, 0}, {"sasl-interactive",'I',0, 0, 'I', 0, 0}, {"sasl-quiet" ,'Q',0, 0, 'Q', 0, 0}, {"sasl-secprops",'O', POPT_ARG_STRING, 0, 'O', 0, 0}, {"sasl-realm", 'R', POPT_ARG_STRING, 0, 'R', 0, 0}, {"sasl-mech", 'Y', POPT_ARG_STRING, 0, 'Y', 0, 0}, {"sasl-authzid",'X', POPT_ARG_STRING, 0, 'X', 0, 0}, {"sasl-authcid",'U', POPT_ARG_STRING, 0, 'U', 0, 0}, {"password", 'w', POPT_ARG_STRING, 0, 'w', 0, 0}, {"chase", 'C', POPT_ARG_STRING, 0, 'C', 0, 0}, {"deref", 'a', POPT_ARG_STRING, 0, 'a', 0, 0}, {"sort", 'S', POPT_ARG_STRING, 0, 'S', 0, 0}, {"class", 'o', POPT_ARG_STRING, 0, 'o', 0, 0}, {"read", 0, POPT_ARG_STRING, 0, OPTION_READ, 0, 0}, {"profile", 'p', POPT_ARG_STRING, 0, 'p', 0, 0}, {"tls", 0, POPT_ARG_STRING, 0, OPTION_TLS, 0, 0}, {"encoding", 0, POPT_ARG_STRING, 0, OPTION_ENCODING, 0, 0}, {"bind", 0, POPT_ARG_STRING, 0, OPTION_BIND, 0, 0}, {"bind-dialog", 0, POPT_ARG_STRING, 0, OPTION_BIND_DIALOG, 0, 0}, {"continuous", 'c', 0, 0, 'c', 0, 0}, {"continue", 'c', 0, 0, 'c', 0, 0}, {"empty", 'A', 0, 0, 'A', 0, 0}, {"discover", 'd', 0, 0, 'd', 0, 0}, {"quiet", 'q', 0, 0, 'q', 0, 0}, {"verbose", 'v', 0, 0, 'v', 0, 0}, {"managedsait", 'M', 0, 0, 'M', 0, 0}, {"may", 'm', 0, 0, 'm', 0, 0}, {"starttls", 'Z', 0, 0, 'Z', 0, 0}, {"help", 'H', 0, 0, 'H', 0, 0}, {"version", 'V', 0, 0, 'V', 0, 0}, {"noninteractive", '!', 0, 0, '!', 0, 0}, {"deleteoldrdn", 'r', 0, 0, 'r', 0, 0}, {"add", 0, 0, 0, OPTION_ADD, 0, 0}, {"config", 0, 0, 0, OPTION_CONFIG, 0, 0}, {"noquestions", 0, 0, 0, OPTION_NOQUESTIONS, 0, 0}, {"ldap-conf", 0, 0, 0, OPTION_LDAP_CONF, 0, 0}, {"ldif", 0, 0, 0, OPTION_LDIF, 0, 0}, {"ldapvi", 0, 0, 0, OPTION_LDAPVI, 0, 0}, {"out", 0, 0, 0, OPTION_OUT, 0, 0}, {"in", 0, 0, 0, OPTION_IN, 0, 0}, {"delete", 0, 0, 0, OPTION_DELETE, 0, 0}, {"rename", 0, 0, 0, OPTION_RENAME, 0, 0}, {"modrdn", 0, 0, 0, OPTION_MODRDN, 0, 0}, {"ldapsearch", 0, 0, 0, OPTION_LDAPSEARCH, 0, 0}, {"ldapmodify", 0, 0, 0, OPTION_LDAPMODIFY, 0, 0}, {"ldapdelete", 0, 0, 0, OPTION_LDAPDELETE, 0, 0}, {"ldapmoddn", 0, 0, 0, OPTION_LDAPMODDN, 0, 0}, {"ldapmodrdn", 0, 0, 0, OPTION_LDAPMODRDN, 0, 0}, {0, 0, 0, 0, 0} }; void usage(int fd, int rc) { if (fd == -1 && rc == 0 && isatty(1)) { int fd; int pid = pipeview(&fd); write(fd, USAGE, strlen(USAGE)); close(fd); pipeview_wait(pid); } else { if (fd != -1) dup2(fd, 1); puts(USAGE); } if (rc != -1) exit(rc); } void init_cmdline(cmdline *cmdline) { cmdline->server = 0; cmdline->basedns = g_ptr_array_new(); cmdline->scope = LDAP_SCOPE_SUBTREE; cmdline->filter = 0; cmdline->attrs = 0; cmdline->quiet = 0; cmdline->referrals = 1; cmdline->classes = 0; cmdline->ldapmodify_add = 0; cmdline->managedsait = 0; cmdline->sortkeys = 0; cmdline->starttls = 0; cmdline->tls = LDAP_OPT_X_TLS_TRY; cmdline->deref = LDAP_DEREF_NEVER; cmdline->verbose = 0; cmdline->noquestions = 0; cmdline->noninteractive = 0; cmdline->discover = 0; cmdline->config = 0; cmdline->ldif = 0; cmdline->ldapvi = 0; cmdline->mode = ldapvi_mode_edit; cmdline->rename_dor = 0; cmdline->schema_comments = 0; cmdline->continuous = 0; cmdline->profileonlyp = 0; cmdline->bind_options.authmethod = LDAP_AUTH_SIMPLE; cmdline->bind_options.dialog = BD_AUTO; cmdline->bind_options.user = 0; cmdline->bind_options.password = 0; cmdline->bind_options.sasl_authcid = 0; cmdline->bind_options.sasl_authzid = 0; cmdline->bind_options.sasl_mech = 0; cmdline->bind_options.sasl_realm = 0; cmdline->bind_options.sasl_secprops = 0; } static void parse_argument(int c, char *arg, cmdline *result, GPtrArray *ctrls) { LDAPControl *control; switch (c) { case 'H': usage(-1, 0); case 'h': result->server = arg; break; case 's': if (!strcmp(arg, "base")) result->scope = LDAP_SCOPE_BASE; else if (!strcmp(arg, "one")) result->scope = LDAP_SCOPE_ONELEVEL; else if (!strcmp(arg, "sub")) result->scope = LDAP_SCOPE_SUBTREE; else { fprintf(stderr, "invalid scope: %s\n", arg); usage(2, 1); } break; case 'b': g_ptr_array_add(result->basedns, arg); break; case 'D': result->bind_options.authmethod = LDAP_AUTH_SIMPLE; result->bind_options.user = *arg ? arg : 0; break; case 'w': result->bind_options.password = arg; break; case 'd': result->discover = 1; break; case 'c': result->continuous = 1; break; case OPTION_CONFIG: result->config = 1; break; case 'q': result->quiet = 1; break; case 'A': if (!result->classes) result->classes = g_ptr_array_new(); break; case 'o': if (!result->classes) result->classes = g_ptr_array_new(); adjoin_str(result->classes, arg); break; case 'C': if (!strcasecmp(arg, "yes")) result->referrals = 1; else if (!strcasecmp(arg, "no")) result->referrals = 0; else { fprintf(stderr, "--chase invalid%s\n", arg); usage(2, 1); } break; case 'm': result->schema_comments = 1; break; case 'M': result->managedsait = 1; control = malloc(sizeof(LDAPControl)); control->ldctl_oid = LDAP_CONTROL_MANAGEDSAIT; control->ldctl_value.bv_len = 0; control->ldctl_value.bv_val = 0; control->ldctl_iscritical = 1; g_ptr_array_add(ctrls, control); break; case 'V': puts("ldapvi " VERSION); exit(0); case 'S': result->sortkeys = arg; break; case 'Z': result->starttls = 1; break; case OPTION_TLS: if (!strcmp(arg, "never")) result->tls = LDAP_OPT_X_TLS_NEVER; else if (!strcmp(arg, "allow")) result->tls = LDAP_OPT_X_TLS_ALLOW; else if (!strcmp(arg, "try")) result->tls = LDAP_OPT_X_TLS_TRY; else if (!strcmp(arg, "strict")) result->tls = LDAP_OPT_X_TLS_HARD; else { fprintf(stderr, "invalid tls level: %s\n", arg); usage(2, 1); } break; case OPTION_ENCODING: if (!strcasecmp(arg, "ASCII")) print_binary_mode = PRINT_ASCII; else if (!strcasecmp(arg, "binary")) print_binary_mode = PRINT_JUNK; else if (!strcasecmp(arg, "UTF-8") || !strcasecmp(arg, "UTF_8") || !strcasecmp(arg, "UTF8")) print_binary_mode = PRINT_UTF8; else { fprintf(stderr, "invalid encoding: %s\n", arg); usage(2, 1); } break; case OPTION_LDIF: result->ldif = 1; break; case OPTION_LDAPVI: result->ldapvi = 1; break; case OPTION_ADD: result->ldapmodify_add = 1; break; case OPTION_LDAPSEARCH: result->quiet = 1; result->noninteractive = 1; /* fall through */ case OPTION_OUT: result->mode = ldapvi_mode_out; break; case OPTION_LDAPMODIFY: result->noninteractive = 1; /* fall through */ case OPTION_IN: result->mode = ldapvi_mode_in; break; case OPTION_LDAPDELETE: result->noninteractive = 1; /* fall through */ case OPTION_DELETE: result->mode = ldapvi_mode_delete; break; case OPTION_LDAPMODDN: result->noninteractive = 1; /* fall through */ case OPTION_RENAME: result->mode = ldapvi_mode_rename; break; case OPTION_LDAPMODRDN: result->noninteractive = 1; /* fall through */ case OPTION_MODRDN: result->mode = ldapvi_mode_modrdn; break; case 'r': result->rename_dor = 1; break; case OPTION_READ: g_ptr_array_add(result->basedns, arg); result->scope = LDAP_SCOPE_BASE; result->filter = "(objectclass=*)"; { static char *attrs[3] = {"+", "*", 0}; result->attrs = attrs; } break; case 'a': if (!strcasecmp(arg, "never")) result->deref = LDAP_DEREF_NEVER; else if (!strcasecmp(arg, "searching")) result->deref = LDAP_DEREF_SEARCHING; else if (!strcasecmp(arg, "finding")) result->deref = LDAP_DEREF_FINDING; else if (!strcasecmp(arg, "always")) result->deref = LDAP_DEREF_ALWAYS; else { fprintf(stderr, "--deref invalid: %s\n", arg); usage(2, 1); } break; case 'v': result->verbose = 1; break; case OPTION_BIND: if (!strcasecmp(arg, "simple")) result->bind_options.authmethod = LDAP_AUTH_SIMPLE; else if (!strcasecmp(arg, "sasl")) result->bind_options.authmethod = LDAP_AUTH_SASL; else { fprintf(stderr, "--bind invalid: %s\n", arg); usage(2, 1); } break; case OPTION_BIND_DIALOG: if (!strcasecmp(arg, "always")) result->bind_options.dialog = BD_ALWAYS; else if (!strcasecmp(arg, "auto")) result->bind_options.dialog = BD_AUTO; else if (!strcasecmp(arg, "never")) result->bind_options.dialog = BD_NEVER; else { fprintf(stderr, "--bind-dialog invalid: %s\n", arg); usage(2, 1); } break; case 'I': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.dialog = BD_ALWAYS; break; case 'Q': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.dialog = BD_NEVER; break; case 'U': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.sasl_authcid = arg; break; case 'X': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.sasl_authzid = arg; break; case 'Y': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.sasl_mech = arg; break; case 'R': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.sasl_realm = arg; break; case 'O': result->bind_options.authmethod = LDAP_AUTH_SASL; result->bind_options.sasl_secprops = arg; break; case '!': result->noninteractive = 1; break; case OPTION_NOQUESTIONS: result->noquestions = 1; break; case OPTION_LDAP_CONF: result->profileonlyp = 0; break; case 'p': parse_configuration(arg, result, ctrls); break; default: abort(); } } static void parse_profile_line(tattribute *attribute, cmdline *result, GPtrArray *ctrls) { char *name = attribute_ad(attribute); GPtrArray *values = attribute_values(attribute); int i; struct poptOption *o = 0; if (!strcmp(name, "filter")) { int last = values->len - 1; result->filter = array2string(g_ptr_array_index(values, last)); return; } if (!strcmp(name, "ad")) { int n = values->len; char **attrs = xalloc((n + 1) * sizeof(char *)); for (i = 0; i < n; i++) attrs[i] = array2string(g_ptr_array_index(values, i)); attrs[n] = 0; result->attrs = attrs; return; } for (i = 0; options[i].longName; i++) if (!strcmp(name, options[i].longName)) { o = &options[i]; break; } if (!o) { fprintf(stderr, "Error: unknown configuration option: '%s'\n", name); exit(1); } for (i = 0; i < values->len; i++) { char *value = array2string(g_ptr_array_index(values, i)); if (o->argInfo == 0) if (!strcmp(value, "no")) continue; else if (strcmp(value, "yes")) { fprintf(stderr, "invalid value '%s' to configuration" " option '%s', expected 'yes' or" " 'no'.\n", value, name); exit(1); } parse_argument(o->val, value, result, ctrls); } } static void parse_configuration(char *profile_name, cmdline *result, GPtrArray *ctrls) { struct stat st; char *profile_requested = profile_name; char *filename = home_filename(".ldapvirc"); FILE *s; tentry *p; tentry *profile_found = 0; int duplicate = 0; if (!profile_name) profile_name = "default"; if (!filename || stat(filename, &st)) { filename = "/etc/ldapvi.conf"; if (stat(filename, &st)) filename = 0; } if (!filename) { if (profile_requested) { fputs("Error: ldapvi configuration file not found.\n", stderr); exit(1); } return; } if ( !(s = fopen(filename, "r"))) syserr(); for (;;) { p = 0; if (read_profile(s, &p)) { fputs("Error in configuration file, giving up.\n", stderr); exit(1); } if (!p) break; if (strcmp(entry_dn(p), profile_name)) entry_free(p); else if (profile_found) duplicate = 1; else profile_found = p; } if (duplicate) { fprintf(stderr, "Error: Duplicate configuration profile '%s'.\n", profile_name); exit(1); } if (profile_found) { result->profileonlyp = 1; GPtrArray *attributes = entry_attributes(profile_found); int i; for (i = 0; i < attributes->len; i++) { tattribute *a = g_ptr_array_index(attributes, i); parse_profile_line(a, result, ctrls); } entry_free(profile_found); } else if (profile_requested) { fprintf(stderr, "Error: Configuration profile not found: '%s'.\n", profile_name); exit(1); } if (fclose(s) == EOF) syserr(); } void parse_arguments(int argc, const char **argv, cmdline *result, GPtrArray *ctrls) { int c; poptContext ctx; char *profile = 0; ctx = poptGetContext( 0, argc, argv, options, POPT_CONTEXT_POSIXMEHARDER); while ( (c = poptGetNextOpt(ctx)) > 0) { char *arg = (char *) poptGetOptArg(ctx); if (c != 'p') continue; if (profile) { fputs("Multiple profile options given.\n", stderr); usage(2, 1); } profile = arg; } parse_configuration(profile, result, ctrls); poptResetContext(ctx); while ( (c = poptGetNextOpt(ctx)) > 0) { char *arg = (char *) poptGetOptArg(ctx); if (c != 'p') parse_argument(c, arg, result, ctrls); } if (c != -1) { fprintf(stderr, "%s: %s\n", poptBadOption(ctx, POPT_BADOPTION_NOALIAS), poptStrerror(c)); usage(2, 1); } if (result->classes && result->mode != ldapvi_mode_edit && result->mode != ldapvi_mode_out) { fputs("Error: Conflicting options given;" " cannot use --class in this mode.\n", stderr); exit(1); } switch (result->mode) { case ldapvi_mode_edit: /* fall through */ case ldapvi_mode_out: if (!result->filter) result->filter = (char *) poptGetArg(ctx); if (!result->attrs) result->attrs = (char **) poptGetArgs(ctx); break; case ldapvi_mode_delete: result->delete_dns = (char **) poptGetArgs(ctx); break; case ldapvi_mode_rename: /* fall through */ case ldapvi_mode_modrdn: result->rename_old = (char *) poptGetArg(ctx); result->rename_new = (char *) poptGetArg(ctx); if (poptGetArg(ctx)) { fputs("Error: Too many command line arguments.\n", stderr); exit(1); } break; case ldapvi_mode_in: result->in_file = (char *) poptGetArg(ctx); if (poptGetArg(ctx)) { fputs("Error: Too many command line arguments.\n", stderr); exit(1); } break; default: abort(); } if (result->profileonlyp) if (setenv("LDAPNOINIT", "thanks", 1)) syserr(); /* don't free! */ /* poptFreeContext(ctx); */ } ldapvi-1.7/error.c0000644000175000017500000000257610617054666013122 0ustar daviddavid/* Copyright (c) 2003,2004,2005 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include void do_syserr(char *file, int line) { char buf[32]; snprintf(buf, sizeof(buf), "error (%s line %d)", file, line); perror(buf); exit(1); } void yourfault(char *str) { fprintf(stderr, "%s\n", str); exit(1); } void ldaperr(LDAP *ld, char *str) { ldap_perror(ld, str); exit(1); } ldapvi-1.7/manual/0000755000175000017500000000000010617054666013070 5ustar daviddavidldapvi-1.7/manual/manual.xml0000644000175000017500000013636310617054666015103 0ustar daviddavid

ldapvi is an interactive LDAP client for Unix terminals. Using it, you can update LDAP entries with a text editor.

Think of it as vipw(1) for LDAP.

ldapvi was written by David Lichteblau and is available at http://www.lichteblau.com/ldapvi/.

ldapvi uses autoconf and should be rather easy to install.

It used to work on Linux, Solaris, FreeBSD, IRIX, and Cygwin for me and seems to work on MacOS X and NetBSD for others. Current versions are only really tested on Linux though, so please send a bug report if a port is broken.

$ ./configure && make # make install

  • Recent OpenLDAP client library (>= 2.2 preferred, 2.1 tolerated)
  • glib-2.0
  • popt
  • curses
  • GNU make
  • OpenSSL or GnuTLS, choose using ./configure --with-libcrypto
  • GNU readline
  • Build dependency: Cyrus SASL. SASL support is disabled in ldapvi if Cyrus SASL headers cannot be found at compilation time. (Whether libldap was compiled with SASL support is only relevant at run time.)

Note that binaries compiled for libldap 2.1 will crash when ran with libldap 2.2.

The choice of GnuTLS over OpenSSL affects only the use of hashing routines for the userPassword convenience encodings md5, smd5, sha, and ssha. GnuTLS support is offered because, according to Debian, OpenSSL is not GPL compatible.

The quickest way to try ldapvi is using this:

$ ldapvi -d --host HOSTNAME

This will bind anonymously to hostname, read all entries the server has and open them in the editor.

--host is the one option you really need to give. It can be one of:

  • A domain name.
  • ldap://hostname[:port]
  • ldaps://hostname[:port]

-d is short for --discover and lets ldapvi search all of the server's naming contexts. Without -d, you would have had to specify the base DN yourself using --base, and you know how inconvenient those LDAP DNs are to type.

As easy as that was, you might want to put the hostname and other search options like the precise base DN to use into a configuration file.

To do that, you might like

$ ldapvi --config --discover --host HOSTNAME

This will ask the server for its naming contexts and print sample contents for ~/.ldaprc (or /etc/ldap.conf).

(Note that ldapvi also has its own configuration file format which supports multiple configuration profiles and all of its options.)

# ldap.conf(5) # edit this as needed and paste into ~/.ldaprc # server name # (for parameterless operation, make sure to include at least this line) HOST localhost # default search base ### multiple namingcontexts found (uncomment one of these lines): #BASE dc=lichteblau,dc=com #BASE dc=acme,dc=com # user to bind as #BINDDN <dn> # search parameters (uncomment as needed) #DEREF never #SIZELIMIT 0 #TIMELIMIT 0

Adjust to taste.

After quitting from the editor, one of three things can happen:

  • If ldapvi detects that nothing in the file has changed, it will quit. No changes.
  • Syntax error: Oops. In this case you only have two options:
    You can either re-edit the file and fix the error (type e) or give up and quit (type Q). As in all menus, type ? for interactive help. Error: Space at beginning of line. What now? [eQ?]
  • Regular usage: ldapvi has compared your changed file with the original contents and reports on the changes found: add: 2, rename: 1, modify: 0, delete: 1 Action? [yYqQvVebB*rsf+?]

If all is well, you are now in the main loop. Your options are:

To continue, type y.

  • y -- commit changes

ldapvi will contact the LDAP server apply all changes. First, entries are processed in order of the changed file, then all entries missing from the file are deleted.

  • e -- open editor again

If any LDAP operation fails while processing the file, ldapvi will stop, report the error, and wait for your choice. To correct such an error, go back to the editor. Your will find all previously processed entries removed from the file, with the failing change at the top. After changing the file, you will be back at the prompt.

Action? [yYqQvVebB*rsf+?] y ldap_modify: Strong(er) authentication required (8) additional info: modifications require authentication Error at: cn=blub4,dc=lichteblau,dc=com add: 0, rename: 0, modify: 1, delete: 0 Action? [yYqQvVebB*rsf+?]
  • Y -- commit, ignoring errors

Apply all changes as if invoked with --continue ignoring all errors without further warning. (Make sure to save changes to an external file before using this option if they were important. Invalid changes will be lost otherwise.)

Before applying the changes, you can inspect them in either LDIF syntax or ldapvi's special changerecord syntax.

  • v -- view changes as LDIF change records
  • V -- view changes as ldapvi change records

LDIF syntax is useful if you want to copy and paste changes into a file for later processing with other LDAP tools. ldapvi syntax is usually easier to read (less Base 64) and can also be entered directly into the editor.

  • + -- rewrite file to include schema comments

This will update the file to include schema comments and re-enter the editor afterwards. This works like the --may command line option, but is based on the current contents of the file rather than the original entries, useful when changing the class of an entry.

Note that this command will rewrite the entire file and wipe out all comments present before invoking it.

One way to bind to the LDAP server is to specify user name and credentials at startup using command line options or configuration files. The other is to simply start without authentication and login later.

When relying on binding after editing, keep in mind that some information will not be returned by the LDAP server unless user authorization permits it in the first place. For example, a userPassword can usually only be displayed and edited if you are bound as that user or root upon startup.

  • b -- show login dialog and rebind

This option will ask for your user name and password (in the case of simple authentication) or various SASL parameters (as requested by the SASL library).

For simple authentication, the user name can be either an DN or a search filter. In the latter case, it must be written with parentheses around it.

Action? [yYqQvVebB*rsf+?] b --- Login Type M-h for help on key bindings. Filter or DN: (cn=admin) Password: ******** OK, bound as cn=admin,dc=lichteblau,dc=com.

Same example with SASL:

Action? [yYqQvVebB*rsf+?] b SASL/DIGEST-MD5 authentication started --- SASL login Type M-h for help on key bindings. authorization name: authentication name: admin password: ******** SASL username: admin SASL SSF: 128 SASL installing layers Bound as authzid=, authcid=admin.

Note that all non-password values are saved into ~/.ldapvi_history, so after entering them once, "cursor up" or incremental search (C-r) will save you from having to type them again.

  • B -- toggle SASL

Use this key to switch between simple authentication and SASL at run time:

Action? [yYqQvVebB*rsf+?] B SASL authentication enabled. SASL mechanism: DIGEST-MD5 (use '*' to change) Type 'b' to log in.
  • * -- set SASL mechanism

When the SASL dialog is shown, it is too late to switch the SASL mechanism. Type * to set it at run time.

Action? [yYqQvVebB*rsf+?] * SASL mechanism: DIGEST-MD5 Type 'b' to log in.

You can skip one change to proceed with the rest.

  • s -- skip one entry

Removes the topmost entry from the data file.

  • f -- forget all deletions

This is useful if you have deleted entries from the file accidentally (or intentionally) and still want to commit other change records in the same file.

This option does not affect explicit deletion records.

There is a gentle way to quit and a hard one.

  • q -- save changes as LDIF and quit
  • Q -- discard changes and quit

q will save your changes to a new file, print the file name, and quit only then. This way your changes do not get lost and you can feed them into ldapmodify at a later time.

Action? [yYqQvVebB*rsf+?] q Your changes have been saved to ,ldapvi-xenon-20094.ldif.

Normal ldapvi invocations look similar to ldapsearch(1), taking an optional search filter and zero or more attribute descriptions as unnamed arguments.

ldapvi [OPTION]... [FILTER] [AD]...

In addition, ldapvi can also simulate behaviour of other LDAP command line tools, e.g. as an interactive substitute for ldapmodify or even for a simple non-interactive usage. See below under command line tool compatibility.

The host option specifies the LDAP server to connect to. It is required for startup (unless specified in a configuration file).

Three styles of host name are recognized.
  • A domain name.
  • ldap://hostname[:port]
  • ldaps://hostname[:port]
To specify a port number or tunnelling through SSL, the URL form must be used.

Note that you can also bind to the server interactively after performing the search using the b command.

Initially, ldapvi defaults to simple authentication. If any SASL parameter is given, the mode is set to sasl. Conversely, -D sets it to simple.

This parameter sets it explicitly.

This option controls whether ldapvi will ask for authentication parameters interactively.

The default is auto, which means that simple binds will be done interactively if a user name is provided but no password, and similarly for SASL.

always forces display of a login dialog even if defaults are known. never skips the login dialog completely.

Note that this option has effect only for the initial bind operation. In the main loop, all binds are done interactively.

See also: -Q and -I.

The user name can be specified as a distinguished name uid=foo,ou=bar,dc=acme,dc=com or as a search filter (uid=foo)

Note the use of parenthesis, which can be omitted from search filters usually but are required here. For this searching bind to work, your client library must be configured with appropriate default search parameters.

Exactly one entry must match.

Beware that passwords in a simple bind are transmitted in clear text unless the connection is encrypted through SSL.

This option is valid for both simple authorization and SASL.

If any of the SASL arguments is specified, ldapvi uses SASL by default.

If you are unsure which SASL parameters to try for your server, start with -Y DIGEST-MD5 -U username.

Always ask for SASL parameters interactively.

This option is an alias for --bind-dialog always and --bind sasl.

Never ask for SASL parameters interactively at all.

This option is an alias for --bind-dialog never and --bind sasl.

OpenLDAP's slapd.conf(5) manual page has some information on these (search for sasl-secprops). The SASL realm [Cyrus SASL documentation]. The authentication ID [Cyrus SASL documentation].

(Basically, your username.)

The authorization ID [Cyrus SASL documentation].

(See SASL Proxy Authorization [openldap.org] in the OpenLDAP Administrator's Guide.)

The SASL mechanism to use. Possible values depend on the server, but DIGEST-MD5 support is mandated by RFC 2829 for all servers using passwords.

Where and how to look for entries.

The entry at which to start the search.

Conflicts with --discover.

  • base: Retrieve at most the entry at base.
  • one: Search for entries exactly one level below base.
  • sub: Search the entire subtree starting at base.
Use the search control to instruct the server to sort results on keys. ldapvi will fail if the server does not support the control. Unfortunately, few servers do.
With this option, ldapvi will first read the root DSE, then repeat the search for each naming context found and present the concatenation of all search results.

Conflicts with --base.

With --config, show a BASE configuration line for each context.

Read the server's schema for the specified objectclass to find out which attributes an entry of this class must have and can have. Then open the editor with an entry template containing one line for each such attribute the user needs to fill out. Optional attributes are included as comments.

The option can be repeated to include additional, auxiliary classes.

A distinguished name for the entry template can be specified using --base.

Show schema comments for existing entries. Specificially, show optional attributes as comments, if not present.

This option applies only to the --in/--ldapmodify mode:

Add new entries (default would be to replace existing attributes).

Do not search, start with an empty file instead.

This is the little brother of the --class parameter, which is more interesting for the original use case of this option, adding new entries.

However, it is still useful because allows the interactive entry of delete, modify, or rename changerecords.

Default is never. Print a configuration file in standard ldap.conf syntax which reflects current command line arguments. The file is written to standard output. Use this option to create an initial configuration file after experimenting with search parameters. Useful in conjunction with --discover. When LDAP errors occur while applying changes, print the messages but continue processing. This mode can also be specified interactively using the 'Y' key. This option controls how ldapvi deals with non-ASCII bytes in attribute values.
  • ASCII: If an attribute value contains any non-ASCII character, use Base 64 encoding for this value
  • UTF-8: Use auto-detection. If an attribute value parses as correct UTF-8, pass it through to the file or terminal unchanged. Otherwise, fall back to Base 64. Mark the file's encoding as UTF-8 for Emacs and VIM.
  • binary: Do not inspect attribute values at all, let arbitrary data through, including zero bytes. Do not use Base 64.

The default is UTF-8.

Use this option to edit referral entries. After opening an unencrypted LDAP connection, use startTLS to enable SSL. (This is an alternative to LDAP connections tunnelled through SSL, specified using ldaps:// URLs.) This option controls the level of certificate checking strictness. Default is try.

fixme: If anyone has a concise description of what these values mean rather than the wishy-washy explanations I can find right now, please tell. Thanks.

(Basically, if you want to use SSL but your certificate is self-signed, you might want to experiment with something less than try.)

A rather trivial option. It means the same as: -b DN -s base '(objectclass=*)' + * Print the distinguished name of every entry as it is being processed. Print help on command line arguments. When changing the relative distinguished name to a new attribute value, delete the old attribute value instead of keeping it.

This option applies only to the --rename mode.

Use standard LDIF syntax in the editor. The default is to use ldapvi syntax. Use ldapvi syntax when reading and writing files. The default is to use LDIF syntax.

ldapvi invocation modes inspired by LDAP command line tools:

ldapvi --out [OPTION]... [FILTER] [AD]... ldapvi --in [OPTION]... [FILENAME] ldapvi --delete [OPTION]... DN... ldapvi --rename [OPTION]... DN1 DN2

All of these are more verbose and interactive than the standard command line tools. There are additional aliases for closer compatibility:

--ldapsearch --ldapmodify --ldapdelete --ldapmoddn

Please keep in mind that all these invocation modes are only meant to imitate LDAP command line tools as far as possible while still working within the design of ldapvi. An option-by-option emulation of the OpenLDAP command line tools is not a goal, and minor differences in look and feel are to be expected.

ldapvi --in | cat ldapvi --in --ldif --ldapvi | cat

The are two ways to configure ldapvi. It has its own configuration files ~/.ldapvirc (or /etc/ldapvi.conf) which support multiple configuration profiles and all of its custom options. Alternatively, it can fall back to libldap's standard configuration files, /etc/ldap.conf and ~/.ldaprc.

On startup, ldapvi will first look for ~/.ldapvirc, or /etc/ldapvi.conf if the former does not exist.

  • If --profile name is specified at the command line, one of these configuration files must exist and it must contain the named profile. Otherwise ldapvi quits with an error.
  • If no --profile was given, ldapvi looks for a profile called default. If no such profile can be found or the files do not exist, ldapvi falls back to libldap configuration files.
  • By default, if a profile is used, it suppresses loading of the libldap configuration files /etc/ldap.conf and ~/.ldaprc. If you want these files to take effect anyway, you can set ldaprc: yes in the profile.

The choice of text editor is made using environment variables. $VISUAL and $EDITOR are looked up in this order. If neither is set, ldapvi falls back to vi.

The configuration file has ldapvi syntax, except with header lines of the form profile name.

Every configuration file option corresponds to a command line parameter.

For the named command line parameters, the long name is used in the configuration. For details, refer to the documentation of each parameter:

The two unnamed kinds of command line arguments are the search filter and the list of attribute descriptions to be returned. The former is named ➙ filter in the configuration file. The latter are given as ➙ ad, one line each.

For boolean flags, given without a value at the command line, use yes as their value in the configuration file. (no is also allowed and has no effect.)

With the following configuration file, ldapvi ignores libldap configuration, because a default profile is given.

  • The default profile falls back to libldap configuration, but enables schema comments.
  • ldapvi -p otherhost profile reads all entries from otherhost.
  • ldapvi -p adduser will open a template for a new user entry to be filled in.
  • ldapvi -p root will retrieve the root DSE with its operational attributes.
profile default ldaprc: yes may: yes profile otherhost host: ldap://otherhost discover: yes profile adduser host: ldap://localhost base: uid=FILLMEIN,ou=passwd,dc=lichteblau,dc=com class: person class: posixAccount profile root host: ldap://localhost base: scope: base filter: (objectclass=*) ad: +

ldapvi syntax is somewhat LDIF-like, but not the same as standard LDIF. This chapter includes examples explaining the difference between the two formats. (A precise, technical definition of ldapvi syntax is given in the next section.)

➙ In interactive editing, the default is ldapvi syntax, explained below, unless overridden using --ldif.

➙ For external input and output (see --in, --out), the default is standard LDIF syntax, unless overridden using --ldapvi.

Comments are lines starting with a sharpsign:

# like this

They are allowed both between entries and in the middle of entries (but not in the middle of an attribute value).

Empty lines are used to separate entries:

0 dc=lichteblau,dc=com # don't touch the number! objectClass: top objectClass: dcObject objectClass: organization o: lichteblau dc: lichteblau # more than one empty line would be OK here, too add cn=admin,dc=lichteblau,dc=com objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator

So far this looks pretty much like LDIF, except for the record key that appears instead of the dn: LDIF uses to start an entry.

  • Numbers as keys reference entries read from the server. ldapvi uses them to find the original entry when comparing your changed file with its unchanged copy.
  • Special key add is used for new entries that are to be added to the tree. Except for not having a number key, its syntax is the same as for normal entries.
  • In addition, there are special keys for change records: rename, delete, and modify. Change records have special syntax and are explained below in detail.

First though, more on low-level syntax issues.

All non-empty, non-comment "lines" have the same base syntax: A left-hand and a right-hand side, separated by an optional encoding marker and a space. (Depending on the encoding used, a such a logical line may include newline characters.)

The syntax of the right-hand side depends on the encoding marker. For simple ASCII text without special characters, there are multiple valid encodings that can be used.

This includes the first line of a record with the distinguished name, its base syntax is the same as for the attribute lines. For traditional reasons, ldapvi prints this line without a colon, but that is not a requirement:

# rather than writing this: add cn=admin,dc=lichteblau,dc=com # we could have included a colon: add: cn=admin,dc=lichteblau,dc=com # or actually, this: add:; cn=admin,dc=lichteblau,dc=com

Or, vice versa, we could have omitted the colon from those attribute values. ldapvi prints it only so that entries looks for familiar to eyes used to LDIF.

Value encodings are:

  • ad: value: LDIF-compatible
  • ad:: value: Base 64
  • ad value: backslashed (short form)
  • ad:; value: backslashed (long form)
  • ad:n value: binary
  • ad:< value: input from file
  • ad:crypt value: userPassword {CRYPT}-hash
  • ad:cryptmd5 value: userPassword {CRYPT}-hash
  • ad:md5 value: userPassword {MD5}-hash
  • ad:smd5 value: userPassword {SMD5}-hash
  • ad:sha value: userPassword {SHA}-hash
  • ad:ssha value: userPassword {SSHA}-hash

Lines with just a colon and a space are parsed according to normal LDIF rules. Values must be ASCII-only and must not contain zero bytes, LF, or CR. In addition, they must not start with a space, a colon, or a less-than sign.

This encoding allows LDIF-style line folding: If a line ends, and the first character of the next line, if any, is a space, the nextline and the space are elided and parsing continues on the next line.

Note: The language for attribute value lines described above is the common subset of LDIF's attrval-spec and the actual syntax accepted by ldapvi for this value encoding. ldapvi will only ever print out values in this encoding if they follow these rules and hence are valid LDIF, but is more liberal in parsing them. It accepts space, colon, or less-than sign as the first character. It can allow them without ambiguity because, in contrast to LDIF, it does not ignore an arbitrary number of space characters after the colon.

Examples of valid LDIF values:

# normally, one would write: objectClass: posixAccount # but with line folding, the same value can be broken into two lines: objectClass: posix Account # in contrast to ldapvi backslashed format, this encoding does not # interpret backslashes specially at all: cn: this is a value containing a backslash\ but no newline

Examples of attribute values not representable in LDIF-compatible encoding:

# must not start with '<': # [accepted by ldapvi but not LDIF] document: <?xml version="1.0" encoding="UTF-8"><foo/> # cannot start with a space: # [LDIF would ignore the space] foo: ... # must not start with a colon: # [accepted by ldapvi but not LDIF] foo: :::::::: # must not contain non-ASCII bytes: surname: Müller # cannot represent newlines: mail: From david@lichteblau.com Mon Apr 1 00:11:22 2006 Return-path: <david@lichteblau.com> Envelope-to: lists@mail.askja.de

Base 64 can be used just as in LDIF.

# This is what the XML from above looks like in strict LDIF: document:: PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPjxmb28vPg==

This is the format ldapvi falls back to if a value cannot be represented in LDIF-compatible encoding without resorting to Base 64. Any character is valid in this encoding, except for two characters with a special meaning:

  • newline terminates the value unless escaped with a backslash
  • backslash escapes the following character

Examples of valid backslashed attributes:

# any funny characters are OK document:; <?xml version="1.0" encoding="UTF-8"> foo:; ... foo:; :::::::: surname:; Müller # backslash escapes newline mail:; From david@lichteblau.com Mon Apr 1 00:11:22 2006\ Return-path: <david@lichteblau.com>\ Envelope-to: lists@mail.askja.de # No LDIF line folding, however, so this value contains a space: cn:; David\ Lichteblau

Counter-example:

# Parsable first line, followed by garbage on the second: cn:; David Lichteblau

Finally, in most situations :; can be omitted, leaving just a space between the left-hand and right-hand side of the line. The only exception is a line with an empty left-hand side, which occurs in modify records.

foo:; bar # is the same as: foo bar

Decimal numbers are valid as encoding markers and specify the number of bytes to read after the separating space. No special characters exist in this syntax. This encoding is not meant for interactive use, but for the sake of completeness, here is an example:

# This entry has two attributes, givenname and cn: add cn=admin,ou=passwd,dc=blubba givenname:5 Davidcn: admin

The less-than sign tells LDAP to read the contents of another file and use them as the attribute value. This is another LDIF compatibility feature.

# oops add cn=haxor,ou=passwd,dc=blubba comment:< file:///etc/passwd

The encodings crypt, cryptmd5, md5, smd5, sha, and ssha are designed for the userPassword attribute. ldapvi takes the right-hand side as the password, hashes it, and prepends {ENCODING} as appropriate.

userPassword:crypt foo # ...could result in: userPassword: {CRYPT}KgJTUDs14z57Q # ...or: userPassword: {CRYPT}UoILyHlM1bPYU # cryptmd5 gives $1$ notation userPassword:cryptmd5 foo userPassword: {CRYPT}$1$iKeAY9mQ$vmo/m/6EoDqRuVtjSqLPr0 # while the other encodings prepend the marker of the same name: userPassword:md5 foo userPassword: {MD5}AQ3GmMeoPXozyRU4wsEDXA==
Aside from the obvious add records mentioned above, there are three change record formats: rename, modify, and delete.

Like every other record, rename states the (original) distinguished name of the name in the header line. Next is one additional line stating the new distinguished name.

The complication is that LDAP's moddn operation needs to be told what to do with the old relative DN if there is a new one. The old one can be kept as an additional attribute value or deleted in favour of the new one.

In ldapvi, this choice is made using the left-hand side of the second line. It is either "add" or "replace".

# example for "deleteoldrdn" behaviour: rename: cn=blub4,dc=lichteblau,dc=com replace: cn=blub3,dc=neu,dc=com # alternatively, the old RDN can be kept: rename: cn=blub3,dc=lichteblau,dc=com add: cn=blub4,dc=neu,dc=com

In LDIF, the same changes would be written as:

# this is LDIF, not ldapvi syntax! dn: cn=blub4,dc=lichteblau,dc=com changetype: modrdn newrdn: cn=blub3 deleteoldrdn: 1 newsuperior: dc=neu,dc=com dn: cn=blub3,dc=lichteblau,dc=com changetype: modrdn newrdn: cn=blub4 deleteoldrdn: 0 newsuperior: dc=neu,dc=com

These records state changes to attributes, processed in order. Attributes can be changed by replacing their existing values with a new set of values, adding those values to the existing ones, or removing only selected old values.

Example:

# Let's add classes, delete a comment and remove cn entirely: modify: dc=bar,dc=lichteblau,dc=com add: objectClass : posixAccount : specialAccount delete: comment : dummy user replace: cn

In LDIF, this would be:

# this is LDIF, not ldapvi syntax! dn: dc=bar,dc=lichteblau,dc=com changetype: modify add: objectClass objectClass: posixAccount objectClass: specialAccount - delete: comment comment: dummy user - replace: cn -

These are rather simple, they consist just of the header line.

delete: dc=acme,dc=com

In LDIF, this would be:

# this is LDIF, not ldapvi syntax! dn: dc=acme,dc=com changetype: delete

When invoked using --ldif, ldapvi will use RFC 2849 syntax instead of its own special syntax.

However, there is a special marker in each entry:

Existing entries are presented for editing with an additional marker on the second line, just after the dn: line. This line states the (numeric) key that would appear in the header line if the entry had been printed in ldapvi syntax.

(New entries can have the same line, with add as their key, but records with neither ldapvi-key nor changetype are automatically assumed to be new entries to add.)

Also, control: is not supported.

Examples:

# Existing entry dn: dc=lichteblau,dc=com ldapvi-key: 0 objectClass: top objectClass: dcObject objectClass: organization o: lichteblau dc: lichteblau # New entry dn: cn=admin,dc=lichteblau,dc=com # next line is optional ldapvi-key: add objectClass: simpleSecurityObject objectClass: organizationalRole cn: admin description: LDAP administrator # Changerecord (standard LDIF syntax) dn: cn=blub4,dc=lichteblau,dc=com changetype: modify delete: seeAlso seeAlso: cn=dort -

As explained above, ldapvi has its own, vaguely LDIF-inspired syntax. For a precise definition, see ldapvi-file below.

LDIF is defined in RFC 2849.

RFC 2849 modifies the language generated by its BNF grammar with the "Notes on LDIF Syntax" (2) and (3) presented there. These notes do not apply to ldapvi syntax as stated: Line folding and comments can be used, but are allowed specificially by our modified BNF, not hacked into the rules later. Line folding is allowed only in LDIF-compatible attribute values and comments. ldapvi files cannot be read line-by-line without knowing the encoding of those lines, since newlines are permitted in certain attribute value representations.

The following rules are used as defined in RFC 2849 and not reproduced here: AttributeDescription, SAFE-STRING, BASE64-STRING, SPACE.

ldapvi-file = vspace ldapvi-record *(vspace SEP vspace ldapvi-record) vspace ldapvi-record = ldapvi-attrval-record / ldapvi-rename-record / ldapvi-modify-record ldapvi-attrval-record = *(comment) dn-spec 1*(*(comment) attrval-spec) ldapvi-rename-record = *(comment) "rename" distinguishedName SEP ("add" / "replace") value-spec SEP ldapvi-modify-record = *(comment) "modify" distinguishedName SEP 1*(*(comment) mod-spec) mod-spec = ("delete" / "add" / "replace") ad-value SEP *(value-enc SEP) vspace = *(comment / sep) comment = "#" *(ldif-char) *(SEP " " *(ldif-char)) SEP dn-spec = key distinguishedName SEP key = number / "add" distinguishedName = value-spec ;encoding an RFC 2253 DN attrval-spec = AttributeDescription value-spec SEP value-spec = value-simple / value-enc value-simple = SPACE escaped-string ;escape CR/LF with '\\\\' value-enc = (":;" SPACE escaped-string / ;ditto ":" SPACE 0*1(SAFE-STRING ;LDIF compatible *(SEP " " *SAFE-CHAR)) / "::" SPACE BASE64-STRING / ;ditto ":" number SPACE 0*1(octet) / ;exactly `number' octets ":<" SPACE url / ;only file:// supported ":crypt" SPACE password / ;for userPassword ":cryptmd5" SPACE password / ":md5" SPACE password / ":smd5" SPACE password / ":sha" SPACE password / ":ssha" SPACE password / ;; other encoding markers reserved ) octet = %x00-ff number = 1*(%x30-39) ;any decimal number ldif-char = unescaped-char / %5c ;any except for CR/LF. unescaped-char = %x00-%x09 / %x0a-%x0c / %x0d-%5b / %x5d-%ff escaped-string = *(unescaped-char / %x5c %x0a / %x5c %x0d / %x5c %x5c) password = 0*ldif-char SEP = LF ;this is a unix program! ad-value = value-spec ;parsing as an AttributeDescription

Please report bugs to the ldapvi mailing list for archival purposes.

Address: ldapvi@lists.askja.de

ldapvi-1.7/manual/manual.css0000644000175000017500000000330610617054666015061 0ustar daviddaviddiv.sidebar { float: right; min-width: 15%; padding: 0pt 5pt 5pt 5pt; font-family: verdana, arial; } a { text-decoration: none; color: #000000; border-bottom: 1px dotted black; border-top: 1px solid white; border-left: 1px solid white; border-right: 1px solid white; } .sidebar a { border-top: 1px solid #eeeeee; border-left: 1px solid #eeeeee; border-right: 1px solid #eeeeee; } a:hover { color: #000000; border: 1px solid black; } div.sidebar-title { font-weight: bold; color: #ffffff; background-color: #000000; /* #0000aa */ border: solid #000000; border-top-width: 1px; border-bottom-width: 2px; border-left-width: 4px; border-right-width: 0px; padding-left: 1px; margin: 0em 2pt 0px 2em; } div.sidebar-title a { color: #ffffff; } div.sidebar-main { background-color: #eeeeee; border: solid #000000; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 4px; border-right-width: 0px; margin: 0em 2pt 1em 2em; padding: 1em; } div.sidebar ul { list-style-type: square; padding: 0pt 0pt 0pt 1em; margin: 0 0 1em; } div.sidebar ul.sub { list-style-type: disc; padding: 0pt 0pt 0pt 1em; margin: 0 0 1em; } body { color: #000000; background-color: #ffffff; margin-right: 0pt; margin-bottom: 10%; margin-left: 40px; padding-left: 30px; font-family: verdana, arial; background-image: url(bg.png); background-position: top left; background-attachment: fixed; background-repeat: no-repeat; } h1,h2 { margin-left: -30px; } .code { border: solid 1px #d0d0d0; padding: 1em; margin-right: 10%; } .def { background-color: #ddddff; font-weight: bold; } .nomargin { margin-bottom: 0; margin-top: 0; } ldapvi-1.7/manual/html.xsl0000644000175000017500000001644310617054666014574 0ustar daviddavid <xsl:value-of select="@title"/>

  • #
  • # -
  • parameter-



    -


          
        
          
        

    parameter- - --      
     
      -   --   #parameter-  ➙  #parameter-
          Short for
    ldapvi-1.7/manual/bg.png0000644000175000017500000000147410617054666014174 0ustar daviddavid‰PNG  IHDRø–“ÚbKGDùC» pHYs  šœtIMEÖ(*=’\¿ÉIDATxÚí×ÁJ*Qð3WJª -(h‘-£…ÑÂU‹Pdž#𢈞 fÓ¶•Ô*sÙ ´H‚ÈÂXÌ¢MSQ©3|w1Ül¨cr¯]¾ßJg<ç çþ£DDDDDDDDDDDDDDDDDDDDDDDDýKiÿ@¡(ÊÛgßaŠÒyñ×O[üÀÀ€ì€ß›››‰‰ ˲noo¿;¯‡‡J¥R:î>KUÕååå³³3/ñùùywwwqqñ[ŒÅbÛÛÛ^¨išßJJ§Óççç^⇿ùêþj4¦i–Ëe×u»ŸÑìììææf½^÷fT«ÕÖ××å"&''WVV...¼×us¹\"‘ø°z>ñúúúö°×ÖÖÆÇÇ»_šã8Ùlvii©5466ÖË’ ‡Ã†aT*•V«Õjµ*•ŠaápX:hzzÚ²,t°,+Êeåóy××׺®«ªªªª®ëWWW …‚\ÖÓÓ€x<Þ~1{µ)—eÛ6€ÁÁÁw‡€»»;¹ò‹ÅÚ/ÎÏÏ{Ë—›—¦iÅbñòò2•J…B¡P(”J¥jµÚññ±¦iŸ÷¡Îžô¥Vö§ª~\êc {{{õzÝuÝw•$”H$^^^àC.ëôô@6›õÆŒŒìïïùí/_ÍfÀÔÔ”·×(Š233`gg§›¾íÕc£Ñ iZ0p/W'''Bˆ¹¹9!„išB]×u]B¼+øÏ%“I¹\N±ººÚþàºß@`kk˶íf³™Ïç{Ü þÅ»¯Ô9ó×ß}½sµ³‹Eé}ŸÉdüúP&“éY²m[n߃A¿>äÝ’P(tö!‡‡‡rYÑh´gïBˆH$bFµZuÇqœjµjF$ùþ?öw Qßû  ÑódZóIEND®B`‚ldapvi-1.7/manual/GNUmakefile0000644000175000017500000000031310617054666015137 0ustar daviddavidmanual.html: html.xsl manual.xml xsltproc $^ >$@ .PHONY: push push: manual.html rsync -av manual.xml bob.askja.de:html/ldapvi/manual/ rsync -av manual.html bob.askja.de:html/ldapvi/manual/index.html ldapvi-1.7/sasl.c0000644000175000017500000001250310617054666012722 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * * Copyright (c) 2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "config.h" #ifdef HAVE_SASL #include #endif #include "common.h" tsasl_defaults * sasl_defaults_new(bind_options *bind_options) { struct sasl_defaults *result = xalloc(sizeof(tsasl_defaults)); result->bind_options = bind_options; result->scratch = g_ptr_array_new(); result->fd = -1; return result; } void sasl_defaults_free(tsasl_defaults *sd) { GPtrArray *scratch = sd->scratch; int i; for (i = 0; i < scratch->len; i++) free(g_ptr_array_index(scratch, i)); g_ptr_array_free(sd->scratch, 1); free(sd); } void init_sasl_redirection(tsasl_defaults *defaults, char *pathname) { int fd = open(pathname, O_RDWR | O_CREAT | O_TRUNC, 0600); if (fd == -1) syserr(); fflush(stdout); defaults->out = dup(1); defaults->err = dup(2); defaults->fd = fd; defaults->pathname = pathname; dup2(defaults->fd, 1); dup2(defaults->fd, 2); } void finish_sasl_redirection(tsasl_defaults *defaults) { dup2(defaults->out, 1); dup2(defaults->err, 2); close(defaults->out); close(defaults->err); if (lseek(defaults->fd, 0, SEEK_SET) != 0) syserr(); fdcp(defaults->fd, 2); close(defaults->fd); defaults->fd = -1; } #ifndef HAVE_SASL #warning SASL support disabled int ldapvi_sasl_interact(LDAP *ld, unsigned flags, void *de, void *in) { fputs("Error: ldapvi compiled without SASL support.\n", stderr); return LDAP_OTHER; } #else static int process_default(sasl_interact_t *interact, tsasl_defaults *defaults) { char *result; switch (interact->id) { case SASL_CB_GETREALM: result = defaults->bind_options->sasl_realm; break; case SASL_CB_AUTHNAME: result = defaults->bind_options->sasl_authcid; break; case SASL_CB_PASS: result = defaults->bind_options->password; break; case SASL_CB_USER: result = defaults->bind_options->sasl_authzid; break; default: result = (char *) interact->defresult; break; } if (result && *result) { interact->result = result; interact->len = strlen(result); return 1; } else { interact->result = ""; return interact->id == SASL_CB_USER; } } static int process_result(int id, char *result, tsasl_defaults *defaults) { switch (id) { case SASL_CB_GETREALM: defaults->bind_options->sasl_realm = result; break; case SASL_CB_AUTHNAME: defaults->bind_options->sasl_authcid = result; break; case SASL_CB_PASS: defaults->bind_options->password = result; break; case SASL_CB_USER: defaults->bind_options->sasl_authzid = result; break; default: g_ptr_array_add(defaults->scratch, result); } } static int challengep(int id) { return id == SASL_CB_ECHOPROMPT || id == SASL_CB_NOECHOPROMPT; } static int interact_mode(int id) { if (id == SASL_CB_PASS || id == SASL_CB_NOECHOPROMPT) return DIALOG_PASSWORD; return DIALOG_DEFAULT; } int ldapvi_sasl_interact(LDAP *ld, unsigned flags, void *de, void *in) { tsasl_defaults *defaults = de; sasl_interact_t *interact = in; tdialog *d; int redirected = defaults->fd != -1; int force_interactive = 0; int i, j, start; int n = 0, m = 0; while (interact[n].id != SASL_CB_LIST_END) { n++; if (challengep(interact[n].id)) m++; } for (i = 0; i < n; i++) if (!process_default(&interact[i], defaults)) force_interactive = 1; if (force_interactive) { if (flags == LDAP_SASL_QUIET) return LDAP_OTHER; } else if (flags != LDAP_SASL_INTERACTIVE) return LDAP_SUCCESS; if (redirected) finish_sasl_redirection(defaults); d = xalloc(sizeof(tdialog) * (n + m)); start = -1; /* authcid if unset, else password if any, else first */ j = 0; for (i = 0; i < n; i++) { char *value = (char *) interact[i].result; char *prompt = (char *) interact[i].prompt; if (!strncmp(prompt, "Please enter your ", 18)) prompt += 18; if (challengep(interact[i].id)) init_dialog(&d[j++], DIALOG_CHALLENGE, "Challenge", (char *) interact[i].challenge); switch (interact[i].id) { case SASL_CB_AUTHNAME: if (!value || !*value) start = j; break; case SASL_CB_PASS: if (start == -1) start = j; break; } init_dialog(&d[j++], interact_mode(interact[i].id), prompt, value); } dialog("--- SASL login", d, n + m, start == -1 ? 0 : start); j = 0; for (i = 0; i < n; i++) { char *value; while (d[j].mode == DIALOG_CHALLENGE) j++; if ( (value = d[j++].value)) process_result(interact[i].id, value, defaults); else value = ""; interact[i].result = value; interact[i].len = strlen(value); } free(d); if (redirected) init_sasl_redirection(defaults, defaults->pathname); return LDAP_SUCCESS; } #endif ldapvi-1.7/test/0000755000175000017500000000000010617054666012572 5ustar daviddavidldapvi-1.7/test/utf8.broken0000644000175000017500000000607210617054666014667 0ustar daviddavidadd: dc=test test: 3.1.1 First continuation byte 0x80: "€" test: 3.1.2 Last continuation byte 0xbf: "¿" test: 3.1.3 2 continuation bytes: "€¿" test: 3.1.4 3 continuation bytes: "€¿€" test: 3.1.5 4 continuation bytes: "€¿€¿" test: 3.1.6 5 continuation bytes: "€¿€¿€" test: 3.1.7 6 continuation bytes: "€¿€¿€¿" test: 3.1.8 7 continuation bytes: "€¿€¿€¿€" test: "€‚ƒ„…†‡ˆ‰Š‹ŒŽ test: ‘’“”•–—˜™š›œžŸ test:  ¡¢£¤¥¦§¨©ª«¬­®¯ test: °±²³´µ¶·¸¹º»¼½¾¿" test: "À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï test: Ð Ñ Ò Ó Ô Õ Ö × Ø Ù Ú Û Ü Ý Þ ß " test: "à á â ã ä å æ ç è é ê ë ì í î ï " test: "ð ñ ò ó ô õ ö ÷ " test: "ø ù ú û " test: "ü ý " test: 3.3.1 2-byte sequence with last byte missing (U+0000): "À" test: 3.3.2 3-byte sequence with last byte missing (U+0000): "à€" test: 3.3.3 4-byte sequence with last byte missing (U+0000): "ð€€" test: 3.3.4 5-byte sequence with last byte missing (U+0000): "ø€€€" test: 3.3.5 6-byte sequence with last byte missing (U+0000): "ü€€€€" test: 3.3.6 2-byte sequence with last byte missing (U-000007FF): "ß" test: 3.3.7 3-byte sequence with last byte missing (U-0000FFFF): "ï¿" test: 3.3.8 4-byte sequence with last byte missing (U-001FFFFF): "÷¿¿" test: 3.3.9 5-byte sequence with last byte missing (U-03FFFFFF): "û¿¿¿" test: 3.3.10 6-byte sequence with last byte missing (U-7FFFFFFF): "ý¿¿¿¿" test: "Àà€ð€€ø€€€ü€€€€ßï¿÷¿¿û¿¿¿ý¿¿¿¿" test: 3.5.1 fe = "þ" test: 3.5.2 ff = "ÿ" test: 3.5.3 fe fe ff ff = "þþÿÿ" test: 4 Overlong sequences test: 4.1.1 U+002F = c0 af = "À¯" test: 4.1.2 U+002F = e0 80 af = "à€¯" test: 4.1.3 U+002F = f0 80 80 af = "ð€€¯" test: 4.1.4 U+002F = f8 80 80 80 af = "ø€€€¯" test: 4.1.5 U+002F = fc 80 80 80 80 af = "ü€€€€¯" test: 4.2.1 U-0000007F = c1 bf = "Á¿" test: 4.2.2 U-000007FF = e0 9f bf = "àŸ¿" test: 4.2.3 U-0000FFFF = f0 8f bf bf = "ð¿¿" test: 4.2.4 U-001FFFFF = f8 87 bf bf bf = "ø‡¿¿¿" test: 4.2.5 U-03FFFFFF = fc 83 bf bf bf bf = "üƒ¿¿¿¿" test: 4.3.1 U+0000 = c0 80 = "À€" test: 4.3.2 U+0000 = e0 80 80 = "à€€" test: 4.3.3 U+0000 = f0 80 80 80 = "ð€€€" test: 4.3.4 U+0000 = f8 80 80 80 80 = "ø€€€€" test: 4.3.5 U+0000 = fc 80 80 80 80 80 = "ü€€€€€" test: 5 Illegal code positions test: 5.1.1 U+D800 = ed a0 80 = "í €" test: 5.1.2 U+DB7F = ed ad bf = "í­¿" test: 5.1.3 U+DB80 = ed ae 80 = "í®€" test: 5.1.4 U+DBFF = ed af bf = "í¯¿" test: 5.1.5 U+DC00 = ed b0 80 = "í°€" test: 5.1.6 U+DF80 = ed be 80 = "í¾€" test: 5.1.7 U+DFFF = ed bf bf = "í¿¿" test: 5.2.1 U+D800 U+DC00 = ed a0 80 ed b0 80 = "𐀀" test: 5.2.2 U+D800 U+DFFF = ed a0 80 ed bf bf = "𐏿" test: 5.2.3 U+DB7F U+DC00 = ed ad bf ed b0 80 = "í­¿í°€" test: 5.2.4 U+DB7F U+DFFF = ed ad bf ed bf bf = "í­¿í¿¿" test: 5.2.5 U+DB80 U+DC00 = ed ae 80 ed b0 80 = "󰀀" test: 5.2.6 U+DB80 U+DFFF = ed ae 80 ed bf bf = "󰏿" test: 5.2.7 U+DBFF U+DC00 = ed af bf ed b0 80 = "􏰀" test: 5.2.8 U+DBFF U+DFFF = ed af bf ed bf bf = "􏿿" test: 5.3.1 U+FFFE = ef bf be = "￾" test: 5.3.2 U+FFFF = ef bf bf = "ï¿¿" ldapvi-1.7/test/try0000644000175000017500000000051410617054666013333 0ustar daviddavid#!/bin/sh -e doit() { echo "* $1" ../ldapvi --diff $1.a $1.b >$1.out || echo FAILED if test -f $1.wanted; then diff -u $1.wanted $1.out || echo FAILED else echo creating $1.wanted mv $1.out $1.wanted cat $1.wanted fi } if test x$1 = x; then ls -1 ???.a | cut -d. -f1 | while read t; do doit $t; done else doit $1 fi ldapvi-1.7/test/utf8.ok0000644000175000017500000000150510617054666014014 0ustar daviddavidadd: dc=test test: You should see the Greek word 'kosme': "κόσμε" test: 2.1.2 2 bytes (U-00000080): "€" test: 2.1.3 3 bytes (U-00000800): "à €" test: 2.1.4 4 bytes (U-00010000): "ð€€" test: 2.1.5 5 bytes (U-00200000): "øˆ€€€" test: 2.1.6 6 bytes (U-04000000): "ü„€€€€" test: 2.2.1 1 byte (U-0000007F): "" test: 2.2.2 2 bytes (U-000007FF): "ß¿" test: 2.2.3 3 bytes (U-0000FFFF): "ï¿¿" test: 2.2.4 4 bytes (U-001FFFFF): "÷¿¿¿" test: 2.2.5 5 bytes (U-03FFFFFF): "û¿¿¿¿" test: 2.2.6 6 bytes (U-7FFFFFFF): "ý¿¿¿¿¿" test: 2.3.1 U-0000D7FF = ed 9f bf = "퟿" test: 2.3.2 U-0000E000 = ee 80 80 = "" test: 2.3.3 U-0000FFFD = ef bf bd = "�" test: 2.3.4 U-0010FFFF = f4 8f bf bf = "ô¿¿" test: 2.3.5 U-00110000 = f4 90 80 80 = "ô€€" ldapvi-1.7/common.h0000644000175000017500000002506510617054666013264 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * * Copyright (c) 2003,2004,2005,2006 David Lichteblau * Copyright (c) 2006 Perry Nguyen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include /* fixme: */ #define LDAP_DEPRECATED 1 #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define MANUAL_SYNTAX_URL "http://www.lichteblau.com/ldapvi/manual#syntax" #define MANUAL_LDIF_URL "http://www.lichteblau.com/ldapvi/manual#syntax-ldif" #define RFC_2849_URL "http://www.rfc-editor.org/rfc/rfc2849.txt" typedef struct tschema { GHashTable *classes; GHashTable *types; } tschema; typedef struct tentroid { tschema *schema; GPtrArray *classes; GPtrArray *must; GPtrArray *may; LDAPObjectClass *structural; GString *comment; GString *error; } tentroid; /* * error.c */ #define syserr() do_syserr(__FILE__, __LINE__) void do_syserr(char *file, int line); void yourfault(char *str); void ldaperr(LDAP *ld, char *str); /* * arguments.c */ enum ldapvi_mode { ldapvi_mode_edit, ldapvi_mode_in, ldapvi_mode_out, ldapvi_mode_delete, ldapvi_mode_rename, ldapvi_mode_modrdn }; enum bind_dialog { BD_NEVER = LDAP_SASL_QUIET, BD_AUTO = LDAP_SASL_AUTOMATIC, BD_ALWAYS = LDAP_SASL_INTERACTIVE }; /* FIXME (?): For now, we recklessly leak all strings stored in * bind_options when reauthentication is performed and new values are * stored. */ typedef struct bind_options { ber_tag_t authmethod; /* LDAP_AUTH_SASL or LDAP_AUTH_NONE */ enum bind_dialog dialog; char *user; /* DN or user search filter */ char *password; /* Simple or SASL passwd */ char *sasl_authcid; char *sasl_authzid; char *sasl_mech; char *sasl_realm; char *sasl_secprops; } bind_options; typedef struct cmdline { char *server; GPtrArray *basedns; int scope; char *filter; char **attrs; bind_options bind_options; int quiet; int referrals; GPtrArray *classes; int ldapmodify_add; int managedsait; char *sortkeys; int starttls; int tls; int deref; int verbose; int noquestions; int noninteractive; int discover; int config; int ldif; int ldapvi; int mode; char **delete_dns; char *rename_old; char *rename_new; int rename_dor; char *in_file; int schema_comments; int continuous; int profileonlyp; } cmdline; void init_cmdline(cmdline *cmdline); void parse_arguments( int argc, const char **argv, cmdline *result, GPtrArray *ctrls); void usage(int fd, int rc); /* * data.c */ typedef struct named_array { char *name; GPtrArray *array; } named_array; typedef struct tentry { struct named_array e; } tentry; #define entry_dn(entry) ((entry)->e.name) #define entry_attributes(entry) ((entry)->e.array) typedef struct tattribute { struct named_array a; } tattribute; #define attribute_ad(attribute) ((attribute)->a.name) #define attribute_values(attribute) ((attribute)->a.array) tentry *entry_new(char *dn); void entry_free(tentry *e); int entry_cmp(tentry *e, tentry *f); tattribute *attribute_new(char *ad); void attribute_free(tattribute *a); int attribute_cmp(tattribute *a, tattribute *b); int named_array_ptr_cmp(const void *aa, const void *bb); LDAPMod *attribute2mods(tattribute *attribute); LDAPMod **entry2mods(tentry *entry); tattribute *entry_find_attribute(tentry *entry, char *ad, int createp); void attribute_append_value(tattribute *attribute, char *data, int n); int attribute_find_value(tattribute *attribute, char *data, int n); int attribute_remove_value(tattribute *a, char *data, int n); struct berval *string2berval(GArray *s); struct berval *gstring2berval(GString *s); char *array2string(GArray *av); void xfree_berval(struct berval *bv); /* * parse.c */ typedef int (*parser_entry)(FILE *, long, char **, tentry **, long *); typedef int (*parser_peek)(FILE *, long, char **, long *); typedef int (*parser_skip)(FILE *, long, char **); typedef int (*parser_rename)(FILE *, long, char **, char **, int *); typedef int (*parser_delete)(FILE *, long, char **); typedef int (*parser_modify)(FILE *, long, char **, LDAPMod ***); typedef void (*print_entry)(FILE *, tentry *, char *, tentroid *); typedef struct tparser { parser_entry entry; parser_peek peek; parser_skip skip; parser_rename rename; parser_delete delete; parser_modify modify; print_entry print; /* ja, das muss so sein */ } tparser; extern tparser ldif_parser; extern tparser ldapvi_parser; int peek_entry(FILE *s, long offset, char **key, long *pos); int read_entry(FILE *s, long offset, char **key, tentry **entry, long *pos); int read_rename(FILE *s, long offset, char **dn1, char **dn2, int *); int read_modify(FILE *s, long offset, char **dn, LDAPMod ***mods); int read_delete(FILE *s, long offset, char **dn); int skip_entry(FILE *s, long offset, char **key); int read_profile(FILE *s, tentry **entry); /* * diff.c */ typedef int (*handler_change)(int, char *, char *, LDAPMod **, void *); typedef int (*handler_rename)(int, char *, tentry *, void *); typedef int (*handler_add)(int, char *, LDAPMod **, void *); typedef int (*handler_delete)(int, char *, void *); typedef int (*handler_rename0)(int, char *, char *, int, void *); typedef struct thandler { handler_change change; handler_rename rename; handler_add add; handler_delete delete; handler_rename0 rename0; } thandler; int compare_streams( tparser *parser, thandler *handler, void *userdata, GArray *offsets, FILE *clean, FILE *data, long *error_position, long *syntax_error_position); enum frob_rdn_mode { FROB_RDN_CHECK, FROB_RDN_REMOVE, FROB_RDN_ADD, FROB_RDN_CHECK_NONE }; int frob_rdn(tentry *entry, char *dn, int mode); int process_immediate(tparser *, thandler *, void *, FILE *, long, char *); /* * misc.c */ enum dialog_mode { DIALOG_DEFAULT, DIALOG_PASSWORD, DIALOG_CHALLENGE }; typedef struct dialog { enum dialog_mode mode; char *prompt; char *value; } tdialog; int carray_cmp(GArray *a, GArray *b); int carray_ptr_cmp(const void *aa, const void *bb); void cp(char *src, char *dst, off_t skip, int append); void fcopy(FILE *src, FILE *dst); char choose(char *prompt, char *charbag, char *help); void edit_pos(char *pathname, long pos); void edit(char *pathname, long line); void view(char *pathname); int pipeview(int *fd); void pipeview_wait(int pid); char *home_filename(char *name); void read_ldapvi_history(void); void write_ldapvi_history(void); char *getline(char *prompt, char *value); char *get_password(); char *append(char *a, char *b); void *xalloc(size_t size); char *xdup(char *str); int adjoin_str(GPtrArray *, char *); int adjoin_ptr(GPtrArray *, void *); void init_dialog(tdialog *, enum dialog_mode, char *, char *); void dialog(char *header, tdialog *, int, int); /* * schema.c */ char *objectclass_name(LDAPObjectClass *); char *attributetype_name(LDAPAttributeType *); tschema *schema_new(LDAP *ld); void schema_free(tschema *schema); LDAPObjectClass *schema_get_objectclass(tschema *, char *); LDAPAttributeType *schema_get_attributetype(tschema *, char *); tentroid *entroid_new(tschema *); void entroid_reset(tentroid *); void entroid_free(tentroid *); LDAPObjectClass *entroid_get_objectclass(tentroid *, char *); LDAPAttributeType *entroid_get_attributetype(tentroid *, char *); LDAPObjectClass *entroid_request_class(tentroid *, char *); int entroid_remove_ad(tentroid *, char *); int compute_entroid(tentroid *); /* * print.c */ typedef enum t_print_binary_mode { PRINT_ASCII, PRINT_UTF8, PRINT_JUNK } t_print_binary_mode; extern t_print_binary_mode print_binary_mode; void print_ldapvi_entry(FILE *s, tentry *entry, char *key, tentroid *); void print_ldapvi_modify(FILE *s, char *dn, LDAPMod **mods); void print_ldapvi_rename(FILE *s, char *olddn, char *newdn, int deleteoldrdn); void print_ldapvi_add(FILE *s, char *dn, LDAPMod **mods); void print_ldapvi_delete(FILE *s, char *dn); void print_ldapvi_modrdn(FILE *s, char *olddn, char *newrdn, int deleteoldrdn); void print_ldapvi_message(FILE *, LDAP *, LDAPMessage *, int key, tentroid *); void print_ldif_entry(FILE *s, tentry *entry, char *key, tentroid *); void print_ldif_modify(FILE *s, char *dn, LDAPMod **mods); void print_ldif_rename(FILE *s, char *olddn, char *newdn, int deleteoldrdn); void print_ldif_add(FILE *s, char *dn, LDAPMod **mods); void print_ldif_delete(FILE *s, char *dn); void print_ldif_modrdn(FILE *s, char *olddn, char *newrdn, int deleteoldrdn); void print_ldif_message(FILE *, LDAP *, LDAPMessage *, int key, tentroid *); /* * search.c */ void discover_naming_contexts(LDAP *ld, GPtrArray *basedns); GArray *search( FILE *s, LDAP *ld, cmdline *cmdline, LDAPControl **ctrls, int notty, int ldif); LDAPMessage *get_entry(LDAP *ld, char *dn, LDAPMessage **result); /* * port.c */ typedef void (*on_exit_function)(int, void *); int g_string_append_sha(GString *string, char *key); int g_string_append_ssha(GString *string, char *key); int g_string_append_md5(GString *string, char *key); int g_string_append_smd5(GString *string, char *key); /* * base64.c */ void print_base64(unsigned char const *src, size_t srclength, FILE *s); void g_string_append_base64( GString *string, unsigned char const *src, size_t srclength); int read_base64(char const *src, unsigned char *target, size_t targsize); /* * sasl.c */ typedef struct sasl_defaults { bind_options *bind_options; GPtrArray *scratch; char *pathname; int fd, out, err; } tsasl_defaults; void init_sasl_redirection(tsasl_defaults *, char *); void enable_sasl_redirection(tsasl_defaults *); void disable_sasl_redirection(tsasl_defaults *); void finish_sasl_redirection(tsasl_defaults *); tsasl_defaults *sasl_defaults_new(bind_options *bind_options); void sasl_defaults_free(tsasl_defaults *sd); int ldapvi_sasl_interact(LDAP *ld, unsigned flags, void *defaults, void *p); ldapvi-1.7/configure.in0000644000175000017500000000533110617054666014126 0ustar daviddavidAC_INIT(,, BUG-REPORT-ADDRESS) dnl FIXME: With --enable-debug, quite some warnings about missing dnl function prototypes are printed. Most (but not all?) of them go dnl away with -D_BSD_SOURCE. However, _BSD_SOURCE appear to be some dnl kind of Linuxism, and I am not at all sure why we need it in dnl this case. AC_ARG_ENABLE([debug],[ --enable-debug enable debugging], [ if test -n "$CFLAGS"; then AC_MSG_WARN([ignoring CFLAGS because of --debug]) fi CFLAGS="-std=c89 -pedantic -g -Wall -Wno-parentheses" ]) if test -z "$CFLAGS"; then CFLAGS=-Wno-parentheses fi AC_PROG_INSTALL # port.c AC_CHECK_FUNCS([mkdtemp]) AC_CHECK_FUNCS([on_exit]) # solaris AC_CHECK_LIB([socket],[main]) AC_CHECK_LIB([resolv],[main]) # traditional libldap isn't enough AC_CHECK_LIB([lber],[main]) AC_CHECK_LIB([ldap],[main],:,AC_MSG_ERROR([libldap not found])) AC_CHECK_LIB([ldap],[ldap_initialize],,AC_MSG_ERROR([libldap present but obsolete])) AC_CHECK_LIB([ldap],[ldap_bv2dn_x],AC_DEFINE(LIBLDAP22),AC_DEFINE(LIBLDAP21)) # sasl AC_CHECK_HEADER([sasl/sasl.h],AC_DEFINE(HAVE_SASL),AC_MSG_WARN([SASL support disabled])) # terminfo AC_SEARCH_LIBS([tigetstr],[curses ncurses],,AC_MSG_ERROR([libcurses not found])) AC_CHECK_HEADER([curses.h],,AC_MSG_ERROR([curses.h not found])) # popt AC_CHECK_LIB([popt],[poptGetContext],,AC_MSG_ERROR([libpopt not found])) # readline AC_CHECK_LIB([readline],[readline],,AC_MSG_ERROR([libreadline not found])) # pkg-config AC_PATH_PROG(PKG_CONFIG, pkg-config, no) if test "x$PKG_CONFIG" = "xno"; then AC_MSG_ERROR([pkg-config not found]); fi # glib LIBS="`$PKG_CONFIG --libs glib-2.0` $LIBS" CFLAGS="`$PKG_CONFIG --cflags glib-2.0` $CFLAGS" AC_CHECK_LIB([glib-2.0],[main],:,AC_MSG_ERROR([libglib2.0 not found])) # libcrypto AC_ARG_WITH(libcrypto, [ --with-libcrypto=(openssl|gnutls) default is openssl],,with_libcrypto=openssl) case $with_libcrypto in openssl) LIBS="`$PKG_CONFIG --libs openssl` $LIBS" CFLAGS="`$PKG_CONFIG --cflags openssl` $CFLAGS" AC_CHECK_LIB([ssl],[main],,AC_MSG_ERROR([OpenSSL not found])) AC_DEFINE(HAVE_OPENSSL) ;; gnutls) LIBS="`$PKG_CONFIG --libs gnutls` $LIBS" CFLAGS="`$PKG_CONFIG --cflags gnutls` $CFLAGS" AC_CHECK_LIB([gnutls],[main],,AC_MSG_ERROR([GnuTLS not found])) AC_CHECK_LIB([gnutls-openssl],[main],,AC_MSG_ERROR([libgnutls-openssl not found])) AC_DEFINE(HAVE_GNUTLS) AC_DEFINE(SHA_DIGEST_LENGTH,20) ;; *) AC_MSG_ERROR([invalid value --with-libcrypto=$with_libcrypto, expected openssl or gnutls]) ;; esac AC_CHECK_FUNCS([SHA1]) AC_CHECK_FUNCS([RAND_pseudo_bytes]) AC_CHECK_LIB([crypt],[main]) AC_ARG_WITH(dummy,[ Set PKG_CONFIG_PATH to choose a glib installation.]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_FILES([GNUmakefile]) AC_OUTPUT ldapvi-1.7/config.h.in0000644000175000017500000000025410617054666013637 0ustar daviddavid#undef HAVE_MKDTEMP #undef HAVE_ON_EXIT #undef LIBLDAP21 #undef LIBLDAP22 #undef HAVE_OPENSSL #undef HAVE_GNUTLS #undef HAVE_SHA1 #undef RAND_PSEUDO_BYTES #undef HAVE_SASL ldapvi-1.7/ldapvi.10000644000175000017500000001165710617054666013166 0ustar daviddavid.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.36. .TH LDAPVI "1" "May 2007" "ldapvi 1.7" "User Commands" .SH NAME ldapvi \- LDAP client .SH SYNOPSIS .B ldapvi [\fIOPTION\fR]... [\fIFILTER\fR] [\fIAD\fR]... .SH DESCRIPTION .SS "Quickstart:" .IP ldapvi \fB\-\-discover\fR \fB\-\-host\fR HOSTNAME .PP Perform an LDAP search and update results using a text editor. .SS "Other usage:" .TP ldapvi \fB\-\-out\fR [OPTION]... [FILTER] [AD]... Print entries .TP ldapvi \fB\-\-in\fR [OPTION]... [FILENAME] Load change records .TP ldapvi \fB\-\-delete\fR [OPTION]... DN... Edit a delete record .TP ldapvi \fB\-\-rename\fR [OPTION]... DN1 DN2 Edit a rename record .SS "Connection options:" .TP \fB\-h\fR, \fB\-\-host\fR URL Server. .TP \fB\-D\fR, \fB\-\-user\fR USER Search filter or DN: User to bind as. [1] Sets \fB\-\-bind\fR simple. .TP \fB\-w\fR, \fB\-\-password\fR SECRET Password (also valid for SASL). .TP \fB\-\-bind\fR [simple,sasl] Disable or enable SASL. .TP \fB\-\-bind\-dialog\fR [never,auto,always] Interactive login dialog. .SS "SASL options (these parameters set --bind sasl):" .HP \fB\-I\fR, \fB\-\-sasl\-interactive\fR Set \fB\-\-bind\-dialog\fR always. .TP \fB\-O\fR, \fB\-\-sasl\-secprops\fR P SASL security properties. .TP \fB\-Q\fR, \fB\-\-sasl\-quiet\fR Set \fB\-\-bind\-dialog\fR never. .TP \fB\-R\fR, \fB\-\-sasl\-realm\fR R SASL realm. .TP \fB\-U\fR, \fB\-\-sasl\-authcid\fR AC SASL authentication identity. .TP \fB\-X\fR, \fB\-\-sasl\-authzid\fR AZ SASL authorization identity. .TP \fB\-Y\fR, \fB\-\-sasl\-mech\fR MECH SASL mechanism. .SS "Search parameters:" .TP \fB\-b\fR, \fB\-\-base\fR DN Search base. .TP \fB\-s\fR, \fB\-\-scope\fR SCOPE Search scope. One of base|one|sub. .TP \fB\-S\fR, \fB\-\-sort\fR KEYS Sort control (critical). .SS "Miscellaneous options:" .TP \fB\-\-add\fR (Only with \fB\-\-in\fR, \fB\-\-ldapmodify\fR:) Treat attrval records as new entries to add. .TP \fB\-o\fR, \fB\-\-class\fR OBJCLASS Class to add. Can be repeated. Implies \fB\-A\fR. .TP \fB\-\-config\fR Print parameters in ldap.conf syntax. .TP \fB\-c\fR \fB\-\-continue\fR Ignore LDAP errors and continue processing. .TP \fB\-\-deleteoldrdn\fR (Only with \fB\-\-rename\fR:) Delete the old RDN. .TP \fB\-a\fR, \fB\-\-deref\fR never|searching|finding|always .TP \fB\-d\fR, \fB\-\-discover\fR Auto\-detect naming contexts. [2] .TP \fB\-A\fR, \fB\-\-empty\fR Don't search, start with empty file. See \fB\-o\fR. .TP \fB\-\-encoding\fR [ASCII|UTF\-8|binary] The encoding to allow. Default is UTF\-8. .TP \fB\-H\fR, \fB\-\-help\fR This help. .TP \fB\-\-ldap\-conf\fR Always read libldap configuration. .TP \fB\-m\fR, \fB\-\-may\fR Show missing optional attributes as comments. .TP \fB\-M\fR, \fB\-\-managedsait\fR manageDsaIT control (critical). .TP \fB\-\-noquestions\fR Commit without asking for confirmation. .TP \-!, \fB\-\-noninteractive\fR Never ask any questions. .TP \fB\-q\fR, \fB\-\-quiet\fR Disable progress output. .TP \fB\-R\fR, \fB\-\-read\fR DN Same as \fB\-b\fR DN \fB\-s\fR base '(objectclass=*)' + * .TP \fB\-Z\fR, \fB\-\-starttls\fR Require startTLS. .TP \fB\-\-tls\fR [never|allow|try|strict] Level of TLS strictess. .TP \fB\-v\fR, \fB\-\-verbose\fR Note every update. .SS "Shortcuts:" .TP \fB\-\-ldapsearch\fR Short for \fB\-\-quiet\fR \fB\-\-out\fR .TP \fB\-\-ldapmodify\fR Short for \fB\-\-noninteractive\fR \fB\-\-in\fR .TP \fB\-\-ldapdelete\fR Short for \fB\-\-noninteractive\fR \fB\-\-delete\fR .TP \fB\-\-ldapmoddn\fR Short for \fB\-\-noninteractive\fR \fB\-\-rename\fR .PP Environment variables: VISUAL, EDITOR, PAGER. .SS "[1] User names can be specified as distinguished names:" .IP uid=foo,ou=bar,dc=acme,dc=com .IP or search filters: .IP (uid=foo) .IP Note the use of parenthesis, which can be omitted from search filters usually but are required here. For this searching bind to work, your client library must be configured with appropriate default search parameters. .PP [2] Repeat the search for each naming context found and present the .TP concatenation of all search results. Conflicts with \fB\-\-base\fR. .IP With \fB\-\-config\fR, show a BASE configuration line for each context. .PP A special (offline) option is \fB\-\-diff\fR, which compares two files and writes any changes to standard output in LDIF format. .SH "REPORTING BUGS" Report bugs to "ldapvi@lists.askja.de". .SH GETTING STARTED Assuming a suitably configured LDAP library, run ldapvi without arguments to see all entries available. Otherwise, try `ldapvi -h HOSTNAME --discover' to query the ROOT DSE for available naming contexts. Once that works, run `ldapvi -h HOSTNAME --discover --config' to generate sample configuration that can be pasted into ~/.ldaprc or /etc/ldap/ldap.conf. .SH FILE FORMAT ldapvi uses an LDIF-like syntax, but not standard LDIF. Please refer to http://www.lichteblau.com/ldapvi/manual.xml#syntax .SH BUGS Please report bugs to . .SH SEE ALSO http://www.lichteblau.com/ldapvi/manual.xml .SH AUTHOR David Lichteblau ldapvi-1.7/search.c0000644000175000017500000001604410617054666013231 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "common.h" static int get_ws_col(void) { struct winsize ws; if (ioctl(1, TIOCGWINSZ, &ws) == -1) return 80; return ws.ws_col; } static void update_progress(LDAP *ld, int n, LDAPMessage *entry) { int cols = get_ws_col(); static struct timeval tv; static int usec = 0; int i; if (gettimeofday(&tv, 0) == -1) syserr(); if (!entry) usec = 0; else if (!usec) usec = tv.tv_usec; else { if (tv.tv_usec < usec) usec -= 1000000; if (tv.tv_usec - usec < 200000) return; usec = tv.tv_usec; } putchar('\r'); for (i = 0; i < cols; i++) putchar(' '); printf((n == 1) ? "\r%7d entry read " :"\r%7d entries read", n); if (entry) { char *dn = ldap_get_dn(ld, entry); if (strlen(dn) < cols - 28) printf(" %s", dn); ldap_memfree(dn); } fflush(stdout); } void handle_result(LDAP *ld, LDAPMessage *result, int start, int n, int progress, int noninteractive) { int rc; int err; char *matcheddn; char *text; rc = ldap_parse_result(ld, result, &err, &matcheddn, &text, 0, 0, 0); if (rc) ldaperr(ld, "ldap_parse_result"); if (err) { fprintf(stderr, "Search failed: %s\n", ldap_err2string(err)); if (text && *text) fprintf(stderr, "\t%s\n", text); if ((err != LDAP_NO_SUCH_OBJECT && err != LDAP_TIMELIMIT_EXCEEDED && err != LDAP_SIZELIMIT_EXCEEDED && err != LDAP_ADMINLIMIT_EXCEEDED) || noninteractive) { exit(1); } if (n > start /* otherwise there is only point in continuing * if other searches find results, and we check * that later */ && choose("Continue anyway?", "yn", 0) != 'y') exit(0); } if (n == start && progress) { fputs("No search results", stderr); if (matcheddn && *matcheddn) fprintf(stderr, " (matched: %s)", matcheddn); fputs(".\n", stderr); } if (matcheddn) ldap_memfree(matcheddn); if (text) ldap_memfree(text); } void log_reference(LDAP *ld, LDAPMessage *reference, FILE *s) { char **refs; char **ptr; if (ldap_parse_reference(ld, reference, &refs, 0, 0)) ldaperr(ld, "ldap_parse_reference"); fputc('\n', s); for (ptr = refs; *ptr; ptr++) fprintf(s, "# reference to: %s\n", *ptr); ldap_value_free(refs); } static tentroid * entroid_set_message(LDAP *ld, tentroid *entroid, LDAPMessage *entry) { struct berval **values = ldap_get_values_len(ld, entry, "objectClass"); struct berval **ptr; if (!values || !*values) return 0; entroid_reset(entroid); for (ptr = values; *ptr; ptr++) { struct berval *value = *ptr; LDAPObjectClass *cls = entroid_request_class(entroid, value->bv_val); if (!cls) { g_string_append(entroid->comment, "# ERROR: "); g_string_append(entroid->comment, entroid->error->str); ldap_value_free_len(values); return entroid; } } ldap_value_free_len(values); if (compute_entroid(entroid) == -1) { g_string_append(entroid->comment, "# ERROR: "); g_string_append(entroid->comment, entroid->error->str); return entroid; } return entroid; } static void search_subtree(FILE *s, LDAP *ld, GArray *offsets, char *base, cmdline *cmdline, LDAPControl **ctrls, int notty, int ldif, tschema *schema) { int msgid; LDAPMessage *result, *entry; int start = offsets->len; int n = start; long offset; tentroid *entroid; tentroid *e; if (schema) entroid = entroid_new(schema); else entroid = 0; if (ldap_search_ext( ld, base, cmdline->scope, cmdline->filter, cmdline->attrs, 0, ctrls, 0, 0, 0, &msgid)) ldaperr(ld, "ldap_search"); while (n >= 0) switch (ldap_result(ld, msgid, 0, 0, &result)) { case -1: case 0: ldaperr(ld, "ldap_result"); case LDAP_RES_SEARCH_ENTRY: entry = ldap_first_entry(ld, result); offset = ftell(s); if (offset == -1 && !notty) syserr(); g_array_append_val(offsets, offset); if (entroid) e = entroid_set_message(ld, entroid, entry); else e = 0; if (ldif) print_ldif_message( s, ld, entry, notty ? -1 : n, e); else print_ldapvi_message(s, ld, entry, n, e); n++; if (!cmdline->quiet && !notty) update_progress(ld, n, entry); ldap_msgfree(entry); break; case LDAP_RES_SEARCH_REFERENCE: log_reference(ld, result, s); ldap_msgfree(result); break; case LDAP_RES_SEARCH_RESULT: if (!notty) { update_progress(ld, n, 0); putchar('\n'); } handle_result(ld, result, start, n, !cmdline->quiet, notty); n = -1; ldap_msgfree(result); break; default: abort(); } if (entroid) entroid_free(entroid); } GArray * search(FILE *s, LDAP *ld, cmdline *cmdline, LDAPControl **ctrls, int notty, int ldif) { GArray *offsets = g_array_new(0, 0, sizeof(long)); GPtrArray *basedns = cmdline->basedns; int i; tschema *schema; if (cmdline->schema_comments) { schema = schema_new(ld); if (!schema) { fputs("Error: Failed to read schema, giving up.", stderr); exit(1); } } else schema = 0; if (basedns->len == 0) search_subtree(s, ld, offsets, 0, cmdline, ctrls, notty, ldif, schema); else for (i = 0; i < basedns->len; i++) { char *base = g_ptr_array_index(basedns, i); if (!cmdline->quiet && (basedns->len > 1)) fprintf(stderr, "Searching in: %s\n", base); search_subtree(s, ld, offsets, base, cmdline, ctrls, notty, ldif, schema); } if (!offsets->len) { if (!cmdline->noninteractive) { if (cmdline->quiet) /* if not printed already... */ fputs("No search results. ", stderr); fputs("(Maybe use --add or --discover instead?)\n", stderr); } exit(0); } if (schema) schema_free(schema); return offsets; } LDAPMessage * get_entry(LDAP *ld, char *dn, LDAPMessage **result) { LDAPMessage *entry; char *attrs[3] = {"+", "*", 0}; if (ldap_search_s(ld, dn, LDAP_SCOPE_BASE, 0, attrs, 0, result)) ldaperr(ld, "ldap_search"); if ( !(entry = ldap_first_entry(ld, *result))) ldaperr(ld, "ldap_first_entry"); return entry; } void discover_naming_contexts(LDAP *ld, GPtrArray *basedns) { LDAPMessage *result, *entry; char **values; entry = get_entry(ld, "", &result); values = ldap_get_values(ld, entry, "namingContexts"); if (values) { char **ptr = values; for (ptr = values; *ptr; ptr++) g_ptr_array_add(basedns, xdup(*ptr)); ldap_value_free(values); } ldap_msgfree(result); } ldapvi-1.7/misc.c0000644000175000017500000003344210617054666012720 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "common.h" #include #include int carray_cmp(GArray *a, GArray *b) { int d = memcmp(a->data, b->data, MIN(a->len, b->len)); if (d) return d; if (a->len < b->len) return -1; else if (a->len == b->len) return 0; else return 1; } int carray_ptr_cmp(const void *aa, const void *bb) { GArray *a = *((GArray **) aa); GArray *b = *((GArray **) bb); return carray_cmp(a ,b); } void fdcp(int fdsrc, int fddst) { int n; char buf[4096]; do { if ( (n = read(fdsrc, buf, sizeof(buf))) == -1) syserr(); if (write(fddst, buf, n) != n) syserr(); } while (n); } void cp(char *src, char *dst, off_t skip, int append) { int fdsrc, fddst; int flags = append ? O_WRONLY | O_APPEND : O_CREAT | O_EXCL | O_WRONLY; if ( (fdsrc = open(src, O_RDONLY)) == -1) syserr(); if (lseek(fdsrc, skip, SEEK_SET) == -1) syserr(); if ( (fddst = open(dst, flags, 0600)) == -1) syserr(); fdcp(fdsrc, fddst); if (close(fdsrc) == -1) syserr(); if (close(fddst) == -1) syserr(); } void fcopy(FILE *src, FILE *dst) { int n; char buf[4096]; for (;;) { if ( (n = fread(buf, 1, sizeof(buf), src)) == 0) { if (feof(src)) break; syserr(); } if (fwrite(buf, 1, n, dst) != n) syserr(); } } static void print_charbag(char *charbag) { int i; putchar('['); for (i = 0; charbag[i]; i++) { char c = charbag[i]; if (c > 32) putchar(c); } putchar(']'); } char choose(char *prompt, char *charbag, char *help) { struct termios term; int c; if (tcgetattr(0, &term) == -1) syserr(); term.c_lflag &= ~ICANON; term.c_cc[VMIN] = 1; term.c_cc[VTIME] = 0; for (;;) { if (tcsetattr(0, TCSANOW, &term) == -1) syserr(); fputs(prompt, stdout); putchar(' '); print_charbag(charbag); putchar(' '); if (strchr(charbag, c = getchar())) break; fputs("\nPlease enter one of ", stdout); print_charbag(charbag); putchar('\n'); if (help) printf(" %s", help); putchar('\n'); } term.c_lflag |= ICANON; if (tcsetattr(0, TCSANOW, &term) == -1) syserr(); putchar('\n'); return c; } static long line_number(char *pathname, long pos) { FILE *f; long line = 1; int c; if ( !(f = fopen(pathname, "r+"))) syserr(); while (pos > 0) { switch ( c = getc_unlocked(f)) { case EOF: goto done; case '\n': if ( (c = getc_unlocked(f)) != EOF) { ungetc(c, f); line++; } /* fall through */ default: pos--; } } done: if (fclose(f) == EOF) syserr(); return line; } void edit(char *pathname, long line) { int childpid; int status; char *vi; vi = getenv("VISUAL"); if (!vi) vi = getenv("EDITOR"); if (!vi) vi = "vi"; switch ( (childpid = fork())) { case -1: syserr(); case 0: if (line > 0) { char buf[20]; snprintf(buf, 20, "+%ld", line); execlp(vi, vi, buf, pathname, 0); } else execlp(vi, vi, pathname, 0); syserr(); } if (waitpid(childpid, &status, 0) == -1) syserr(); if (!WIFEXITED(status) || WEXITSTATUS(status)) yourfault("editor died"); } void edit_pos(char *pathname, long pos) { edit(pathname, pos > 0 ? line_number(pathname, pos) : -1); } static int invalidp(char *ti) { return ti == 0 || ti == (char *) -1; } void view(char *pathname) { int childpid; int status; char *pg; char *clear = tigetstr("clear"); pg = getenv("PAGER"); if (!pg) pg = "less"; if (!invalidp(clear)) putp(clear); switch ( (childpid = fork())) { case -1: syserr(); case 0: execlp(pg, pg, pathname, 0); syserr(); } if (waitpid(childpid, &status, 0) == -1) syserr(); if (!WIFEXITED(status) || WEXITSTATUS(status)) puts("pager died"); } int pipeview(int *fd) { int childpid; char *pg; char *clear = tigetstr("clear"); int fds[2]; pg = getenv("PAGER"); if (!pg) pg = "less"; if (!invalidp(clear)) putp(clear); if (pipe(fds) == -1) syserr(); switch ( (childpid = fork())) { case -1: syserr(); case 0: close(fds[1]); dup2(fds[0], 0); close(fds[0]); execlp(pg, pg, 0); syserr(); } close(fds[0]); *fd = fds[1]; return childpid; } void pipeview_wait(int childpid) { int status; if (waitpid(childpid, &status, 0) == -1) syserr(); if (!WIFEXITED(status) || WEXITSTATUS(status)) puts("pager died"); } char * home_filename(char *name) { char *home = getenv("HOME"); int n; char *result; if (!home) { fputs("Warning: You don't have a $HOME.\n", stderr); return 0; } n = strlen(home); result = xalloc(n + 1 + strlen(name) + 1); strcpy(result, home); result[n] = '/'; strcpy(result + n + 1, name); return result; } static char * history_filename() { return home_filename(".ldapvi_history"); } void read_ldapvi_history() { char *filename = history_filename(); using_history(); if (!filename) return; if (read_history(filename) && errno != ENOENT) perror("Oops, couldn't read history"); free(filename); } void write_ldapvi_history() { char *filename = history_filename(); if (!filename) return; if (write_history(filename)) perror("Oops, couldn't write history"); free(filename); } char * getline(char *prompt, char *value) { tdialog d; init_dialog(&d, DIALOG_DEFAULT, prompt, value); dialog(0, &d, 1, 0); return d.value ? d.value : xdup(""); } char * get_password() { tdialog d; init_dialog(&d, DIALOG_PASSWORD, "Password: ", ""); dialog(0, &d, 1, 0); return d.value ? d.value : xdup(""); } static char *readline_default; static int cb_set_readline_default() { rl_insert_text(readline_default); return 0; } void display_password(void) { int i; char *backup = xalloc(rl_end + 1); strncpy(backup, rl_line_buffer, rl_end); for (i = 0; i < rl_end; i++) rl_line_buffer[i] = '*'; rl_redisplay(); strncpy(rl_line_buffer, backup, rl_end); } static char * getline2(char *prompt, char *value, int password, int history) { char *str; if (password) rl_redisplay_function = display_password; readline_default = value; rl_startup_hook = cb_set_readline_default; str = readline(prompt); rl_startup_hook = 0; if (password) rl_redisplay_function = rl_redisplay; if (str && *str && history) add_history(str); return str; } void init_dialog(tdialog *d, enum dialog_mode mode, char *prompt, char *value) { d->mode = mode; d->prompt = prompt; d->value = value; } char * append(char *a, char *b) { int k = strlen(a); char *result = xalloc(k + strlen(b) + 1); strcpy(result, a); strcpy(result + k, b); return result; } void * xalloc(size_t size) { void *result = malloc(size); if (!result) { write(2, "\nmalloc error\n", sizeof("\nmalloc error\n") - 1); _exit(2); } return result; } char * xdup(char *str) { char *result; if (!str) return str; if (!(result = strdup(str))) { write(2, "\nstrdup error\n", sizeof("\nstrdup error\n") - 1); _exit(2); } return result; } int adjoin_str(GPtrArray *strs, char *str) { int i; for (i = 0; i < strs->len; i++) if (!strcmp(str, g_ptr_array_index(strs, i))) return -1; g_ptr_array_add(strs, str); return i; } int adjoin_ptr(GPtrArray *a, void *p) { int i; for (i = 0; i < a->len; i++) if (g_ptr_array_index(a, i) == p) return -1; g_ptr_array_add(a, p); return i; } void dumb_dialog(tdialog *d, int n) { GString *prompt = g_string_new(""); int i; for (i = 0; i < n; i++) { g_string_assign(prompt, d[i].prompt); g_string_append(prompt, ": "); switch (d[i].mode) { case DIALOG_DEFAULT: d[i].value = getline2(prompt->str, d[i].value, 0, 1); break; case DIALOG_PASSWORD: d[i].value = getline2(prompt->str, d[i].value, 1, 0); break; case DIALOG_CHALLENGE: printf("%s: %s\n", prompt->str, d[i].value); break; } } g_string_free(prompt, 1); } enum dialog_rc { dialog_continue, dialog_done, dialog_goto, dialog_relative, dialog_help, dialog_clear }; static Keymap dialog_keymap = 0; static Keymap dialog_empty_keymap = 0; static enum dialog_rc dialog_action; static int dialog_next; static int cb_view_pre_input() { rl_done = 1; return 0; } static int cb_dialog_done(int a, int b) { rl_done = 1; dialog_action = dialog_done; return 42; } static int cb_dialog_goto(int a, int b) { rl_done = 1; dialog_action = dialog_goto; dialog_next = a - 1; return 42; } static int cb_dialog_prev(int a, int b) { rl_done = 1; dialog_action = dialog_relative; dialog_next = - 1; return 42; } static int cb_dialog_next(int a, int b) { rl_done = 1; dialog_action = dialog_relative; dialog_next = 1; return 42; } static int cb_dialog_help(int a, int b) { rl_done = 1; dialog_action = dialog_help; return 42; } static int cb_dialog_clear(int a, int b) { rl_done = 1; dialog_action = dialog_clear; return 42; } #define DIALOG_HELP \ "\nEdit the lines above using standard readline commands.\n" \ "Use RET to edit each line in turn.\n" \ "\n" \ "Special keys:\n" \ " M-RET Finish the dialog immediately.\n" \ " C-p Go back to the previous line.\n" \ " C-n Go to the next line (alias for RET).\n" \ " M-g With numeric prefix, go to the specified line.\n" \ "\n" \ "Non-password lines are saved in the history. Standard readline\n" \ "bindings for history access include:\n" \ " C-r Incremental search through history.\n" \ " / Previous/next history entry.\n" static void dialog_rebuild(char *up, char *clreos, char *header, char **prompts, tdialog *d, int n, int target, int help) { int i; putp(clreos); if (header) { putchar('\n'); fputs(header, stdout); putchar('\n'); fputs("Type M-h for help on key bindings.", stdout); putchar('\n'); putchar('\n'); } rl_pre_input_hook = cb_view_pre_input; for (i = 0; i < n; i++) { int passwordp = d[i].mode == DIALOG_PASSWORD; free(getline2(prompts[i], d[i].value, passwordp, 0)); putchar('\n'); } rl_pre_input_hook = 0; if (help) { fputs(DIALOG_HELP, stdout); for (i = 0; DIALOG_HELP[i]; i++) if (DIALOG_HELP[i] == '\n') putp(up); } for (i = 0; i < n - target; i++) putp(up); } static Keymap set_meta_keymap(Keymap keymap, Keymap meta_keymap) { if (!meta_keymap) meta_keymap = rl_copy_keymap((Keymap) keymap[27].function); keymap[27].type = ISKMAP; keymap[27].function = (rl_command_func_t *) meta_keymap; } static void init_dialog_keymap(Keymap keymap) { Keymap meta_keymap = (Keymap) keymap[27].function; rl_bind_key_in_map('L' - '@', cb_dialog_clear, keymap); rl_bind_key_in_map('P' - '@', cb_dialog_prev, keymap); rl_bind_key_in_map('N' - '@', cb_dialog_next, keymap); rl_bind_key_in_map('\r', cb_dialog_done, meta_keymap); rl_bind_key_in_map('g', cb_dialog_goto, meta_keymap); rl_bind_key_in_map('h', cb_dialog_help, meta_keymap); } void dialog(char *header, tdialog *d, int n, int start) { int i; char *up = tigetstr("cuu1"); char *clreos = tigetstr("ed"); char *clear = tigetstr("clear"); #if 0 char *hsm = rl_variable_value("horizontal-scroll-mode"); #endif char *hsm = "off"; Keymap original_keymap = rl_get_keymap(); int max = 0; char **prompts; if (n == 0) return; if (invalidp(up) || invalidp(clreos) || invalidp(clear)) { puts("Dumb terminal. Using fallback dialog."); dumb_dialog(d, n); return; } if (!dialog_keymap) { rl_initialize(); dialog_keymap = rl_copy_keymap(original_keymap); dialog_empty_keymap = rl_make_bare_keymap(); set_meta_keymap(dialog_keymap, 0); set_meta_keymap(dialog_empty_keymap, rl_make_bare_keymap()); init_dialog_keymap(dialog_keymap); init_dialog_keymap(dialog_empty_keymap); } rl_variable_bind("horizontal-scroll-mode", "on"); rl_inhibit_completion = 1; /* fixme */ for (i = 0; i < n; i++) max = MAX(max, strlen(d[i].prompt)); prompts = xalloc(sizeof(char *) * n); for (i = 0; i < n; i++) { char *prompt = d[i].prompt; int len = strlen(prompt); char *str = xalloc(max + 3); memset(str, ' ', max); strcpy(str + max - len, prompt); strcpy(str + max, ": "); prompts[i] = str; if (d[i].value) d[i].value = xdup(d[i].value); } dialog_rebuild(up, clreos, header, prompts, d, n, start, 0); i = start; for (;;) { char *orig = d[i].value; int passwordp = d[i].mode == DIALOG_PASSWORD; dialog_action = dialog_continue; if (d[i].mode == DIALOG_CHALLENGE) rl_set_keymap(dialog_empty_keymap); else rl_set_keymap(dialog_keymap); d[i].value = getline2(prompts[i], orig, passwordp, !passwordp); if (orig) free(orig); switch (dialog_action) { case dialog_continue: dialog_next = i + 1; break; case dialog_clear: /* fall through */ case dialog_help: dialog_next = i; break; case dialog_relative: dialog_next += i; /* fall through */ case dialog_goto: if (dialog_next < 0 || dialog_next >= n) dialog_next = i; break; case dialog_done: dialog_next = n; break; } if (dialog_action == dialog_clear) putp(clear); else { if (header) i += 4; if (dialog_action != dialog_continue) i--; do putp(up); while (i--); } dialog_rebuild(up, clreos, header, prompts, d, n, dialog_next, dialog_action == dialog_help); if (dialog_next >= n) break; i = dialog_next; } for (i = 0; i < n; i++) free(prompts[i]); free(prompts); rl_set_keymap(original_keymap); rl_variable_bind("horizontal-scroll-mode", hsm); rl_inhibit_completion = 0; } ldapvi-1.7/data.c0000644000175000017500000001173610617054666012700 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "common.h" static named_array * named_array_new(char *name) { named_array *result = xalloc(sizeof(named_array)); result->name = name; result->array = g_ptr_array_new(); return result; } static void named_array_free(named_array *na) { free(na->name); g_ptr_array_free(na->array, 1); free(na); } static int named_array_cmp(named_array *a, named_array *b) { return strcmp(a->name, b->name); } int named_array_ptr_cmp(const void *aa, const void *bb) { named_array *a = *((named_array **) aa); named_array *b = *((named_array **) bb); return named_array_cmp(a, b); } /* * entry */ tentry * entry_new(char *dn) { return (tentry *) named_array_new(dn); } void entry_free(tentry *entry) { GPtrArray *attributes = entry_attributes(entry); int n = attributes->len; int i; for (i = 0; i < n; i++) attribute_free(g_ptr_array_index(attributes, i)); named_array_free((named_array *) entry); } int entry_cmp(tentry *e, tentry *f) { return named_array_cmp((named_array *) e, (named_array *) f); } /* * value */ /* * attribute */ tattribute * attribute_new(char *ad) { return (tattribute *) named_array_new(ad); } void attribute_free(tattribute *attribute) { GPtrArray *values = attribute_values(attribute); int n = values->len; int i; for (i = 0; i < n; i++) g_array_free(g_ptr_array_index(values, i), 1); named_array_free((named_array *) attribute); } int attribute_cmp(tattribute *a, tattribute *b) { return named_array_cmp((named_array *) a, (named_array *) b); } /* * misc */ tattribute * entry_find_attribute(tentry *entry, char *ad, int createp) { GPtrArray *attributes = entry_attributes(entry); tattribute *attribute = 0; int i; for (i = 0; i < attributes->len; i++) { tattribute *a = g_ptr_array_index(attributes, i); if (!strcmp(attribute_ad(a), ad)) { attribute = a; break; } } if (!attribute && createp) { attribute = attribute_new(xdup(ad)); g_ptr_array_add(attributes, attribute); } return attribute; } void attribute_append_value(tattribute *attribute, char *data, int n) { GArray *value = g_array_sized_new(0, 0, 1, n); g_array_append_vals(value, data, n); g_ptr_array_add(attribute_values(attribute), value); } int attribute_find_value(tattribute *attribute, char *data, int n) { int i; GPtrArray *values = attribute_values(attribute); for (i = 0; i < values->len; i++) { GArray *value = values->pdata[i]; if (value->len == n && !memcmp(value->data, data, n)) return i; } return -1; } int attribute_remove_value(tattribute *a, char *data, int n) { int i = attribute_find_value(a, data, n); if (i == -1) return i; g_array_free(g_ptr_array_remove_index_fast(attribute_values(a), i), 1); return 0; } /* * Aus irgendwelchen Gruenden habe ich mal beschlossen, GArrays mit chars drin * statt GStrings zu nehmen fuer die Attributwerte. Wie unpraktisch. */ char * array2string(GArray *av) { int n = av->len; char *str = xalloc(n + 1); memcpy(str, av->data, n); str[n] = 0; return str; } /* * allocate a new berval and copy LEN bytes of DATA into it */ static struct berval * dup2berval(char *data, int len) { struct berval *bv = xalloc(sizeof(struct berval)); bv->bv_val = xalloc(len); memcpy(bv->bv_val, data, len); bv->bv_len = len; return bv; } void xfree_berval(struct berval *bv) { free(bv->bv_val); free(bv); } struct berval * string2berval(GArray *s) { return dup2berval(s->data, s->len); } struct berval * gstring2berval(GString *s) { return dup2berval(s->str, s->len); } LDAPMod * attribute2mods(tattribute *attribute) { GPtrArray *values = attribute_values(attribute); LDAPMod *m = xalloc(sizeof(LDAPMod)); int j; m->mod_op = LDAP_MOD_BVALUES; m->mod_type = xdup(attribute_ad(attribute)); m->mod_bvalues = xalloc( (1 + values->len) * sizeof(struct berval *)); for (j = 0; j < values->len; j++) m->mod_bvalues[j] = string2berval(g_ptr_array_index(values, j)); m->mod_bvalues[j] = 0; return m; } LDAPMod ** entry2mods(tentry *entry) { GPtrArray *attributes = entry_attributes(entry); LDAPMod **result = xalloc((attributes->len + 1) * sizeof(LDAPMod *)); int i; for (i = 0; i < attributes->len; i++) result[i] = attribute2mods(g_ptr_array_index(attributes, i)); result[i] = 0; return result; } ldapvi-1.7/COPYING0000644000175000017500000004310510617054666012651 0ustar daviddavid GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) 19yy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) 19yy name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. ldapvi-1.7/GNUmakefile.in0000644000175000017500000000166610617054666014303 0ustar daviddavidCC:=@CC@ CFLAGS:=@CPPFLAGS@ @CFLAGS@ LDFLAGS:=@LDFLAGS@ @LIBS@ INSTALL:=@INSTALL@ prefix:=@prefix@ exec_prefix:=@exec_prefix@ all: ldapvi dist: ldapvi ldapvi.1 ldapvi: ldapvi.o data.o diff.o error.o misc.o parse.o port.o print.o search.o base64.o arguments.o parseldif.o schema.c sasl.o $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS) %.o: %.c common.h $(CC) -c $(CFLAGS) -o $@ $< .PHONY: clean clean: rm -f ldapvi *.o gmon.out ldapvi.1: version.h ldapvi ldapvi.1.in help2man -n "LDAP client" -N ./ldapvi | cat - ldapvi.1.in >ldapvi.1.out mv ldapvi.1.out ldapvi.1 .PHONY: install install: ldapvi mkdir -p @bindir@ @mandir@/man1/ @prefix@/share/doc/ldapvi @INSTALL_PROGRAM@ ldapvi @bindir@ @INSTALL_PROGRAM@ -m 644 ldapvi.1 @mandir@/man1/ @INSTALL_PROGRAM@ -m 644 manual/manual.css manual/manual.xml manual/bg.png manual/html.xsl @prefix@/share/doc/ldapvi distclean: rm -rf configure GNUmakefile config.h config.log autom4te.cache config.status ldapvi-1.7/schema.c0000644000175000017500000002205010617054666013216 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "common.h" LDAPObjectClass * schema_get_objectclass(tschema *schema, char *name) { return g_hash_table_lookup(schema->classes, name); } LDAPAttributeType * schema_get_attributetype(tschema *schema, char *name) { return g_hash_table_lookup(schema->types, name); } char * objectclass_name(LDAPObjectClass *cls) { char **names = cls->oc_names; if (names && *names) return *names; return cls->oc_oid; } char * attributetype_name(LDAPAttributeType *at) { char **names = at->at_names; if (names && *names) return *names; return at->at_oid; } static void add_objectclass(GHashTable *classes, LDAPObjectClass *cls) { int i; char **names = cls->oc_names; g_hash_table_insert(classes, cls->oc_oid, cls); if (names) for (i = 0; names[i]; i++) g_hash_table_insert(classes, names[i], cls); } static void add_attributetype(GHashTable *types, LDAPAttributeType *at) { int i; char **names = at->at_names; g_hash_table_insert(types, at->at_oid, at); if (names) for (i = 0; names[i]; i++) g_hash_table_insert(types, names[i], at); } static gboolean strcaseequal(gconstpointer v, gconstpointer w) { return strcasecmp((char *) v, (char *) w) == 0; } /* From GLIB - Library of useful routines for C programming, g_str_hash() * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald */ static guint strcasehash(gconstpointer v) { const signed char *p = v; guint32 h = *p; if (h) for (p += 1; *p != '\0'; p++) h = (h << 5) - h + tolower(*p); return h; } static gboolean aux_class_entry_p(gpointer key, gpointer value, gpointer data) { LDAPObjectClass *class = value; return !!strcmp(key, class->oc_oid); } static gboolean aux_type_entry_p(gpointer key, gpointer value, gpointer data) { LDAPAttributeType *at = value; return !!strcmp(key, at->at_oid); } static void free_class(gpointer key, gpointer value, gpointer data) { ldap_objectclass_free(value); } static void free_type(gpointer key, gpointer value, gpointer data) { ldap_attributetype_free(value); } void schema_free(tschema *schema) { g_hash_table_foreach_steal(schema->classes, aux_class_entry_p, 0); g_hash_table_foreach_steal(schema->types, aux_type_entry_p, 0); g_hash_table_foreach(schema->classes, free_class, 0); g_hash_table_foreach(schema->types, free_type, 0); g_hash_table_destroy(schema->classes); g_hash_table_destroy(schema->types); free(schema); } tschema * schema_new(LDAP *ld) { LDAPMessage *result, *entry; char **values; char *subschema_dn; int code; const char *errp; char *attrs[2] = {"subschemaSubentry", 0}; tschema *schema; if (ldap_search_s(ld, "", LDAP_SCOPE_BASE, 0, attrs, 0, &result)) { ldap_perror(ld, "ldap_search"); return 0; } if ( !(entry = ldap_first_entry(ld, result))) { ldap_perror(ld, "ldap_first_entry"); return 0; } values = ldap_get_values(ld, entry, "subschemaSubentry"); if (!values) { fputs("subschemaSubentry attribute not found.", stderr); ldap_msgfree(result); return 0; } subschema_dn = xdup(*values); ldap_value_free(values); ldap_msgfree(result); entry = get_entry(ld, subschema_dn, &result); free(subschema_dn); values = ldap_get_values(ld, entry, "objectClasses"); schema = xalloc(sizeof(tschema)); schema->classes = g_hash_table_new(strcasehash, strcaseequal); schema->types = g_hash_table_new(strcasehash, strcaseequal); if (values) { char **ptr = values; for (ptr = values; *ptr; ptr++) { LDAPObjectClass *cls = ldap_str2objectclass(*ptr, &code, &errp, 0); if (cls) add_objectclass(schema->classes, cls); else fprintf(stderr, "Warning: Cannot parse class: %s\n", ldap_scherr2str(code)); } ldap_value_free(values); } values = ldap_get_values(ld, entry, "attributeTypes"); if (values) { char **ptr = values; for (ptr = values; *ptr; ptr++) { LDAPAttributeType *at = ldap_str2attributetype( *ptr, &code, &errp, 0); if (at) add_attributetype(schema->types, at); else fprintf(stderr, "Warning: Cannot parse type: %s\n", ldap_scherr2str(code)); } ldap_value_free(values); } ldap_msgfree(result); return schema; } tentroid * entroid_new(tschema *schema) { tentroid *result = xalloc(sizeof(tentroid)); result->schema = schema; result->classes = g_ptr_array_new(); result->must = g_ptr_array_new(); result->may = g_ptr_array_new(); result->structural = 0; result->comment = g_string_sized_new(0); result->error = g_string_sized_new(0); return result; } void entroid_reset(tentroid *entroid) { g_ptr_array_set_size(entroid->classes, 0); g_ptr_array_set_size(entroid->must, 0); g_ptr_array_set_size(entroid->may, 0); entroid->structural = 0; g_string_truncate(entroid->comment, 0); g_string_truncate(entroid->error, 0); } void entroid_free(tentroid *entroid) { g_ptr_array_free(entroid->classes, 1); g_ptr_array_free(entroid->must, 1); g_ptr_array_free(entroid->may, 1); g_string_free(entroid->comment, 1); g_string_free(entroid->error, 1); free(entroid); } LDAPObjectClass * entroid_get_objectclass(tentroid *entroid, char *name) { LDAPObjectClass *cls = schema_get_objectclass(entroid->schema, name); if (!cls) { g_string_assign(entroid->error, "Error: Object class not found: "); g_string_append(entroid->error, name); g_string_append_c(entroid->error, '\n'); } return cls; } LDAPAttributeType * entroid_get_attributetype(tentroid *entroid, char *name) { LDAPAttributeType *at = schema_get_attributetype(entroid->schema, name); if (!at) { g_string_assign(entroid->error, "Error: Attribute type not found: "); g_string_append(entroid->error, name); g_string_append_c(entroid->error, '\n'); } return at; } LDAPObjectClass * entroid_request_class(tentroid *entroid, char *name) { LDAPObjectClass *cls = entroid_get_objectclass(entroid, name); if (cls) adjoin_ptr(entroid->classes, cls); return cls; } int entroid_remove_ad(tentroid *entroid, char *ad) { LDAPAttributeType *at; char *name; char *s = strchr(ad, ';'); int found; if (s) { int n = s - ad; name = xalloc(n); memcpy(name, ad, n); } else name = ad; if ( !(at = entroid_get_attributetype(entroid, name))) return 0; found = g_ptr_array_remove(entroid->must, at); found |= g_ptr_array_remove(entroid->may, at); if (name != ad) free(name); return found; } static int compute_entroid_1(tentroid *entroid, LDAPObjectClass *cls) { char **ptr; for (ptr = cls->oc_sup_oids; ptr && *ptr; ptr++) if (!entroid_request_class(entroid, *ptr)) return -1; if (cls->oc_kind == LDAP_SCHEMA_STRUCTURAL) { char *str; if (entroid->structural) str = "### WARNING: extra structural object class: "; else { str = "# structural object class: "; entroid->structural = cls; } g_string_append(entroid->comment, str); g_string_append(entroid->comment, objectclass_name(cls)); g_string_append_c(entroid->comment, '\n'); } for (ptr = cls->oc_at_oids_must; ptr && *ptr; ptr++) { LDAPAttributeType *at = entroid_get_attributetype(entroid, *ptr); if (!at) return -1; g_ptr_array_remove(entroid->may, at); adjoin_ptr(entroid->must, at); } for (ptr = cls->oc_at_oids_may; ptr && *ptr; ptr++) { int i; LDAPAttributeType *at = entroid_get_attributetype(entroid, *ptr); if (!at) return -1; for (i = 0; i < entroid->must->len; i++) if (at == g_ptr_array_index(entroid->must, i)) break; if (i >= entroid->must->len) g_ptr_array_add(entroid->may, at); } return 0; } /* * Add all superclasses to entroid->classes; add required and optional * attributes to entroid->must, entroid->may. Set entroid->structural * to the structural objectclass, if any. Extra trace output for user * display in entroid->comment; * * Return 0 on success, -1 else. * Error message, if any, in entroid->error. */ int compute_entroid(tentroid *entroid) { int i; for (i = 0; i < entroid->classes->len; i++) { LDAPObjectClass *cls = g_ptr_array_index(entroid->classes, i); if (compute_entroid_1(entroid, cls) == -1) return -1; } if (!entroid->structural) g_string_append(entroid->comment, "### WARNING:" " no structural object class specified!\n"); return 0; } ldapvi-1.7/ldapvi.1.in0000644000175000017500000000126010617054666013560 0ustar daviddavid.SH GETTING STARTED Assuming a suitably configured LDAP library, run ldapvi without arguments to see all entries available. Otherwise, try `ldapvi -h HOSTNAME --discover' to query the ROOT DSE for available naming contexts. Once that works, run `ldapvi -h HOSTNAME --discover --config' to generate sample configuration that can be pasted into ~/.ldaprc or /etc/ldap/ldap.conf. .SH FILE FORMAT ldapvi uses an LDIF-like syntax, but not standard LDIF. Please refer to http://www.lichteblau.com/ldapvi/manual.xml#syntax .SH BUGS Please report bugs to . .SH SEE ALSO http://www.lichteblau.com/ldapvi/manual.xml .SH AUTHOR David Lichteblau ldapvi-1.7/parseldif.c0000644000175000017500000003724210617054666013740 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define _XOPEN_SOURCE #include #include "common.h" #define fast_g_string_append_c(gstring, c) \ do { \ if ((gstring)->len + 1 >= (gstring)->allocated_len) \ g_string_append_c((gstring), (c)); \ else { \ (gstring)->str[(gstring)->len++] = (c); \ (gstring)->str[(gstring)->len] = 0; \ } \ } while (0) /* * 0: ok * -1: parse error * -2: line is just "-" */ static int ldif_read_ad(FILE *s, GString *lhs) { int c; for (;;) { switch ( c = getc_unlocked(s)) { case ':': if (ferror(s)) syserr(); return 0; case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; case '\r': if (fgetc(s) != '\n') return -1; /* fall through */ case '\n': if (lhs->len) { if ( (c = fgetc(s)) == ' ') /* folded line */ break; ungetc(c, s); if (lhs->len == 1 && lhs->str[0] == '-') return -2; } fputs("Error: Unexpected EOL.\n", stderr); return -1; case 0: fputs("Error: Null byte not allowed.\n", stderr); return -1; default: fast_g_string_append_c(lhs, c); } } } static int ldif_read_encoding(FILE *s) { int c; for (;;) { switch ( c = getc_unlocked(s)) { case ' ': break; case ':': /* fall through */ case '<': return c; case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; case '\r': if (fgetc(s) != '\n') return -1; /* fall through */ case '\n': if ( (c = fgetc(s)) == ' ') /* folded line */ break; ungetc(c, s); return '\n'; case 0: fputs("Error: Null byte not allowed.\n", stderr); return -1; default: ungetc(c, s); return 0; } } } static int ldif_read_safe(FILE *s, GString *data) { int c; for (;;) switch ( c = getc_unlocked(s)) { case '\r': if (fgetc(s) != '\n') return -1; /* fall through */ case '\n': if ( (c = fgetc(s)) == ' ') /* folded line */ break; ungetc(c, s); if (ferror(s)) syserr(); return 0; case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; default: fast_g_string_append_c(data, c); } } static int ldif_read_from_file(GString *data, char *name) { int fd, n; if ( (fd = open(name, O_RDONLY)) == -1) { perror("open"); return -1; } data->len = 0; n = 1024; do { int olen = data->len; g_string_set_size(data, data->len + n); if ( (n = read(fd, data->str + olen, n)) == -1) syserr(); data->len = olen + n; } while (n > 0); if (close(fd) == -1) syserr(); return 0; } static int ldif_skip_comment(FILE *s) { int c; for (;;) switch ( c = fgetc(s)) { case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; case '\r': if (fgetc(s) != '\n') return -1; /* fall through */ case '\n': if ( (c = fgetc(s)) == ' ') /* folded line */ break; ungetc(c, s); if (ferror(s)) syserr(); return 0; } } /* * Read an LDIF line. * * 0: ok if name->len != 0 * 0: end of file or empty line if name->len == 0 * -1: parse error * -2: line is just "-" */ static int ldif_read_line1(FILE *s, GString *name, GString *value) { int c; char encoding; unsigned char *ustr; int len; g_string_truncate(name, 0); g_string_truncate(value, 0); /* skip comment lines */ do { c = fgetc(s); switch (c) { case EOF: if (ferror(s)) syserr(); return 0; case '\n': return 0; case '\r': if (fgetc(s) != '\n') return -1; return 0; case '#': if (ldif_skip_comment(s) == -1) return -1; break; default: ungetc(c, s); c = -1; } } while (c != -1); if ( c = ldif_read_ad(s, name)) return c; if ( (encoding = ldif_read_encoding(s)) == -1) return -1; switch (encoding) { case 0: if (ldif_read_safe(s, value) == -1) return -1; break; case '\n': break; case ':': if (ldif_read_safe(s, value) == -1) return -1; ustr = (unsigned char *) value->str;; if ( (len = read_base64(value->str, ustr, value->len)) == -1) { fputs("Error: Invalid Base64 string.\n", stderr); return -1; } value->len = len; break; case '<': if (ldif_read_safe(s, value) == -1) return -1; if (strncmp(value->str, "file://", 7)) { fputs("Error: Unknown URL scheme.\n", stderr); return -1; } if (ldif_read_from_file(value, value->str + 7) == -1) return -1; break; default: abort(); } return 0; } /* * Read an LDIF line ("-" not allowed). * * 0: ok if name->len != 0 * 0: end of file or empty line if name->len == 0 * -1: parse error */ static int ldif_read_line(FILE *s, GString *name, GString *value) { int rc = ldif_read_line1(s, name, value); if (rc == -2) { fputs("Error: Unexpected EOL.\n", stderr); rc = -1; } return rc; } static char * ldif_read_rename_body(FILE *s, GString *tmp1, GString *tmp2, char *olddn, int *deleteoldrdn) { char *newrdn; char *dn; int i; if (ldif_read_line(s, tmp1, tmp2) == -1) return 0; if (strcmp(tmp1->str, "newrdn")) { fputs("Error: Expected 'newrdn'.\n", stderr); return 0; } i = tmp2->len; newrdn = xdup(tmp2->str); if (ldif_read_line(s, tmp1, tmp2) == -1) { free(newrdn); return 0; } if (strcmp(tmp1->str, "deleteoldrdn")) { fputs("Error: Expected 'deleteoldrdn'.\n", stderr); free(newrdn); return 0; } if (!strcmp(tmp2->str, "0")) *deleteoldrdn = 0; else if (!strcmp(tmp2->str, "1")) *deleteoldrdn = 1; else { fputs("Error: Expected '0' or '1' for 'deleteoldrdn'.\n", stderr); free(newrdn); return 0; } if (ldif_read_line(s, tmp1, tmp2) == -1) return 0; if (tmp1->len == 0) { char *komma = strchr(olddn, ','); if (!komma) { /* probably cannot rename an entry directly below * the Root DSE, but let's play along for now */ return newrdn; } dn = xalloc(i + strlen(komma) + 1); strcpy(dn, newrdn); strcpy(dn + i, komma); free(newrdn); return dn; } if (strcmp(tmp1->str, "newsuperior")) { free(newrdn); fputs("Error: Garbage at end of moddn record.\n", stderr); return 0; } if (tmp2->len == 0) return newrdn; dn = xalloc(i + tmp2->len + 2); strcpy(dn, newrdn); dn[i] = ','; strcpy(dn + i + 1, tmp2->str); free(newrdn); return dn; } static int ldif_read_nothing(FILE *s, GString *tmp1, GString *tmp2) { if (ldif_read_line(s, tmp1, tmp2) == -1) return -1; if (tmp1->len) { fputs("Error: Garbage at end of record.\n", stderr); return -1; } return 0; } static LDAPMod * ldif_ldapmod4line(char *action, char *ad) { LDAPMod *m; int op; if (!strcmp(action, "add")) op = LDAP_MOD_ADD; else if (!strcmp(action, "delete")) op = LDAP_MOD_DELETE; else if (!strcmp(action, "replace")) op = LDAP_MOD_REPLACE; else { fputs(action, stderr); fputs("Error: Invalid change marker.\n", stderr); return 0; } m = xalloc(sizeof(LDAPMod)); m->mod_op = op | LDAP_MOD_BVALUES; m->mod_type = xdup(ad); return m; } static LDAPMod ** ldif_read_modify_body(FILE *s, GString *tmp1, GString *tmp2) { LDAPMod **result; GPtrArray *mods = g_ptr_array_new(); GPtrArray *values; LDAPMod *m = 0; int rc; for (;;) { switch (ldif_read_line(s, tmp1, tmp2)) { case 0: break; case -1: goto error; default: abort(); } if (tmp1->len == 0) break; values = g_ptr_array_new(); if ( !(m = ldif_ldapmod4line(tmp1->str, tmp2->str))) goto error; g_ptr_array_add(mods, m); do { switch ( rc = ldif_read_line1(s, tmp1, tmp2)) { case 0: if (strcmp(tmp1->str, m->mod_type)) { fputs("Error: Attribute name mismatch" " in change-modify.", stderr); goto error; } g_ptr_array_add(values, gstring2berval(tmp2)); break; case -2: break; case -1: goto error; default: abort(); } } while (rc != -2); g_ptr_array_add(values, 0); m->mod_bvalues = (void *) values->pdata; g_ptr_array_free(values, 0); values = 0; } g_ptr_array_add(mods, 0); result = (LDAPMod **) mods->pdata; g_ptr_array_free(mods, 0); return result; error: g_ptr_array_free(mods, 1); if (values) { int i; for (i = 0; i < values->len; i++) xfree_berval(values->pdata[i]); g_ptr_array_free(values, 0); } return 0; } /* * Lies die erste Zeile eines beliebigen Records nach position `offset' in `s'. * Setze *pos (falls pos != 0). * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - pos ist die exakte Anfangsposition. * - Setze *key auf den Schluessel (falls key != 0). * - Setze *dn auf den Distinguished Name (falls dn != 0). * EOF ist kein Fehler und liefert *key = 0 (falls key != 0); * * Der Schluessel ist dabei * "delete" fuer "changetype: delete" * "modify" fuer "changetype: modify" * "rename" fuer "changetype: moddn" und "changetype: modrdn", * "add" fuer "changetype: add" erlauben wir mal ganz frech ebenfalls * oder andernfalls der Wert von "ldapvi-key: ...", das als erste * Zeile im attrval-record erscheinen muss. */ static int ldif_read_header(GString *tmp1, GString *tmp2, FILE *s, long offset, char **key, char **dn, long *pos) { char **rdns = 0; char *k; char *d; long pos2; if (offset != -1) if (fseek(s, offset, SEEK_SET) == -1) syserr(); do { if (pos) if ( (*pos = ftell(s)) == -1) syserr(); if (ldif_read_line(s, tmp1, tmp2) == -1) return -1; if (tmp1->len == 0 && feof(s)) { if (key) *key = 0; return 0; } if (!strcmp(tmp1->str, "version")) { if (strcmp(tmp2->str, "1")) { fputs("Error: Invalid file format.\n", stderr); return -1; } tmp1->len = 0; } } while (!tmp1->len); rdns = ldap_explode_dn(tmp2->str, 0); if (!rdns) { fputs("Error: Invalid distinguished name string.\n", stderr); return -1; } if (dn) d = xdup(tmp2->str); if ( (pos2 = ftell(s)) == -1) syserr(); if (ldif_read_line(s, tmp1, tmp2) == -1) { if (dn) free(d); return -1; } if (!strcmp(tmp1->str, "ldapvi-key")) k = tmp2->str; else if (!strcmp(tmp1->str, "changetype")) { if (!strcmp(tmp2->str, "modrdn")) k = "rename"; else if (!strcmp(tmp2->str, "moddn")) k = "rename"; else if (!strcmp(tmp2->str, "delete") || !strcmp(tmp2->str, "modify") || !strcmp(tmp2->str, "add")) k = tmp2->str; else { fputs("Error: invalid changetype.\n", stderr); if (dn) free(d); return -1; } } else if (!strcmp(tmp1->str, "control")) { fputs("Error: Sorry, 'control:' not supported.\n", stderr); if (dn) free(d); return -1; } else { k = "add"; if (fseek(s, pos2, SEEK_SET) == -1) syserr(); } if (key) *key = xdup(k); if (dn) *dn = d; ldap_value_free(rdns); return 0; } static int ldif_read_attrval_body(GString *tmp1, GString *tmp2, FILE *s, tentry *entry) { for (;;) { tattribute *attribute; if (ldif_read_line(s, tmp1, tmp2) == -1) return -1; if (!tmp1->len) break; attribute = entry_find_attribute(entry, tmp1->str, 1); attribute_append_value(attribute, tmp2->str, tmp2->len); } return 0; } /* * Lies ein attrval-record nach position `offset' in `s'. * Setze *pos (falls pos != 0). * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - pos ist die exakte Anfangsposition. * - Setze *entry auf den gelesenen Eintrag (falls entry != 0). * - Setze *key auf den Schluessel (falls key != 0). * EOF ist kein Fehler und liefert *key = 0 (falls key != 0); */ int ldif_read_entry(FILE *s, long offset, char **key, tentry **entry, long *pos) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *dn; char *k = 0; tentry *e = 0; int rc = ldif_read_header(tmp1, tmp2, s, offset, &k, &dn, pos); if (rc || !k) goto cleanup; e = entry_new(dn); rc = ldif_read_attrval_body(tmp1, tmp2, s, e); if (!rc) { if (entry) { *entry = e; e = 0; } if (key) { *key = k; k = 0; } } cleanup: if (k) free(k); if (e) entry_free(e); g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } /* * Lies die ersten beiden Zeilen eines beliebigen Records nach position * `offset' in `s'. * * Setze *pos (falls pos != 0). * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - pos ist die exakte Anfangsposition. * - Setze *key auf den Schluessel (falls key != 0). */ int ldif_peek_entry(FILE *s, long offset, char **key, long *pos) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); int rc = ldif_read_header(tmp1, tmp2, s, offset, key, 0, pos); g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } /* * Lies ein rename-record nach position `offset' in `s'. * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - Setze *dn1 auf den alten DN. * - Setze *dn2 auf den neuen DN. * - *deleteoldrdn auf 1 oder 0; */ int ldif_read_rename(FILE *s, long offset, char **dn1, char **dn2, int *deleteoldrdn) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *olddn; char *newdn; int rc = ldif_read_header(tmp1, tmp2, s, offset, 0, &olddn, 0); if (rc) { g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } newdn = ldif_read_rename_body(s, tmp1, tmp2, olddn, deleteoldrdn); g_string_free(tmp1, 1); g_string_free(tmp2, 1); if (!newdn) { free(olddn); return -1; } if (dn1) *dn1 = olddn; else free(olddn); if (dn2) *dn2 = newdn; else free(newdn); return 0; } int ldif_read_delete(FILE *s, long offset, char **dn) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *str; int rc = ldif_read_header(tmp1, tmp2, s, offset, 0, &str, 0); if (rc) { g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } rc = ldif_read_nothing(s, tmp1, tmp2); g_string_free(tmp1, 1); g_string_free(tmp2, 1); if (rc == -1) free(str); else *dn = str; return rc; } /* * Lies ein modify-record nach position `offset' in `s'. * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - Setze *dn auf den DN. * - Setze *mods auf die Aenderungen. */ int ldif_read_modify(FILE *s, long offset, char **dn, LDAPMod ***mods) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *d; LDAPMod **m; int rc = ldif_read_header(tmp1, tmp2, s, offset, 0, &d, 0); if (rc) { g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } m = ldif_read_modify_body(s, tmp1, tmp2); g_string_free(tmp1, 1); g_string_free(tmp2, 1); if (!m) { free(d); return -1; } if (dn) *dn = d; else free(d); if (mods) *mods = m; else ldap_mods_free(m, 1); return 0; } /* * Parse a complete entry or changerecord and ignore it. Set *key accordingly. * Leave the stream positioned after the entry. * * Treat EOF as success and set *key to NULL. * * return value: * 0 on success * -1 on parse error */ int ldif_skip_entry(FILE *s, long offset, char **key) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *k = 0; int rc = ldif_read_header(tmp1, tmp2, s, offset, &k, 0, 0); if (!rc && k) for (;;) { if (ldif_read_line1(s, tmp1, tmp2) == -1) { rc = -1; break; } if (tmp1->len == 0) { if (key) *key = k; else free(k); break; } } g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } tparser ldif_parser = { ldif_read_entry, ldif_peek_entry, ldif_skip_entry, ldif_read_rename, ldif_read_delete, ldif_read_modify, print_ldif_entry }; ldapvi-1.7/configure0000755000175000017500000052145610617054704013530 0ustar daviddavid#! /bin/sh # Guess values for system-dependent variables and create Makefiles. # Generated by GNU Autoconf 2.61. # # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH if test "x$CONFIG_SHELL" = x; then if (eval ":") 2>/dev/null; then as_have_required=yes else as_have_required=no fi if test $as_have_required = yes && (eval ": (as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=\$LINENO as_lineno_2=\$LINENO test \"x\$as_lineno_1\" != \"x\$as_lineno_2\" && test \"x\`expr \$as_lineno_1 + 1\`\" = \"x\$as_lineno_2\") || { (exit 1); exit 1; } ") 2> /dev/null; then : else as_candidate_shells= as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. case $as_dir in /*) for as_base in sh bash ksh sh5; do as_candidate_shells="$as_candidate_shells $as_dir/$as_base" done;; esac done IFS=$as_save_IFS for as_shell in $as_candidate_shells $SHELL; do # Try only shells that exist, to save several forks. if { test -f "$as_shell" || test -f "$as_shell.exe"; } && { ("$as_shell") 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : _ASEOF }; then CONFIG_SHELL=$as_shell as_have_required=yes if { "$as_shell" 2> /dev/null <<\_ASEOF if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi : (as_func_return () { (exit $1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = "$1" ); then : else exitcode=1 echo positional parameters were not saved. fi test $exitcode = 0) || { (exit 1); exit 1; } ( as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2") || { (exit 1); exit 1; } _ASEOF }; then break fi fi done if test "x$CONFIG_SHELL" != x; then for as_var in BASH_ENV ENV do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done export CONFIG_SHELL exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"} fi if test $as_have_required = no; then echo This script requires a shell more modern than all the echo shells that I found on your system. Please install a echo modern shell, or manually run the script under such a echo shell if you do have one. { (exit 1); exit 1; } fi fi fi (eval "as_func_return () { (exit \$1) } as_func_success () { as_func_return 0 } as_func_failure () { as_func_return 1 } as_func_ret_success () { return 0 } as_func_ret_failure () { return 1 } exitcode=0 if as_func_success; then : else exitcode=1 echo as_func_success failed. fi if as_func_failure; then exitcode=1 echo as_func_failure succeeded. fi if as_func_ret_success; then : else exitcode=1 echo as_func_ret_success failed. fi if as_func_ret_failure; then exitcode=1 echo as_func_ret_failure succeeded. fi if ( set x; as_func_ret_success y && test x = \"\$1\" ); then : else exitcode=1 echo positional parameters were not saved. fi test \$exitcode = 0") || { echo No shell found that supports shell functions. echo Please tell autoconf@gnu.org about your system, echo including any error possibly output before this echo message } as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 7<&0 &1 # Name of the host. # hostname on some systems (SVR3.2, Linux) returns a bogus exit status, # so uname gets run too. ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` # # Initializations. # ac_default_prefix=/usr/local ac_clean_files= ac_config_libobj_dir=. LIBOBJS= cross_compiling=no subdirs= MFLAGS= MAKEFLAGS= SHELL=${CONFIG_SHELL-/bin/sh} # Identity of this package. PACKAGE_NAME= PACKAGE_TARNAME= PACKAGE_VERSION= PACKAGE_STRING= PACKAGE_BUGREPORT= # Factoring default headers for most tests. ac_includes_default="\ #include #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef STDC_HEADERS # include # include #else # ifdef HAVE_STDLIB_H # include # endif #endif #ifdef HAVE_STRING_H # if !defined STDC_HEADERS && defined HAVE_MEMORY_H # include # endif # include #endif #ifdef HAVE_STRINGS_H # include #endif #ifdef HAVE_INTTYPES_H # include #endif #ifdef HAVE_STDINT_H # include #endif #ifdef HAVE_UNISTD_H # include #endif" ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datarootdir datadir sysconfdir sharedstatedir localstatedir includedir oldincludedir docdir infodir htmldir dvidir pdfdir psdir libdir localedir mandir DEFS ECHO_C ECHO_N ECHO_T LIBS build_alias host_alias target_alias INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT CPP GREP EGREP PKG_CONFIG LIBOBJS LTLIBOBJS' ac_subst_files='' ac_precious_vars='build_alias host_alias target_alias CC CFLAGS LDFLAGS LIBS CPPFLAGS CPP' # Initialize some variables set by options. ac_init_help= ac_init_version=false # The variables have the same names as the options, with # dashes changed to underlines. cache_file=/dev/null exec_prefix=NONE no_create= no_recursion= prefix=NONE program_prefix=NONE program_suffix=NONE program_transform_name=s,x,x, silent= site= srcdir= verbose= x_includes=NONE x_libraries=NONE # Installation directory options. # These are left unexpanded so users can "make install exec_prefix=/foo" # and all the variables that are supposed to be based on exec_prefix # by default will actually change. # Use braces instead of parens because sh, perl, etc. also accept them. # (The list follows the same order as the GNU Coding Standards.) bindir='${exec_prefix}/bin' sbindir='${exec_prefix}/sbin' libexecdir='${exec_prefix}/libexec' datarootdir='${prefix}/share' datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE}' infodir='${datarootdir}/info' htmldir='${docdir}' dvidir='${docdir}' pdfdir='${docdir}' psdir='${docdir}' libdir='${exec_prefix}/lib' localedir='${datarootdir}/locale' mandir='${datarootdir}/man' ac_prev= ac_dashdash= for ac_option do # If the previous option needs an argument, assign it. if test -n "$ac_prev"; then eval $ac_prev=\$ac_option ac_prev= continue fi case $ac_option in *=*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; *) ac_optarg=yes ;; esac # Accept the important Cygnus configure options, so we can diagnose typos. case $ac_dashdash$ac_option in --) ac_dashdash=yes ;; -bindir | --bindir | --bindi | --bind | --bin | --bi) ac_prev=bindir ;; -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) bindir=$ac_optarg ;; -build | --build | --buil | --bui | --bu) ac_prev=build_alias ;; -build=* | --build=* | --buil=* | --bui=* | --bu=*) build_alias=$ac_optarg ;; -cache-file | --cache-file | --cache-fil | --cache-fi \ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) ac_prev=cache_file ;; -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) cache_file=$ac_optarg ;; --config-cache | -C) cache_file=config.cache ;; -datadir | --datadir | --datadi | --datad) ac_prev=datadir ;; -datadir=* | --datadir=* | --datadi=* | --datad=*) datadir=$ac_optarg ;; -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ | --dataroo | --dataro | --datar) ac_prev=datarootdir ;; -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) datarootdir=$ac_optarg ;; -disable-* | --disable-*) ac_feature=`expr "x$ac_option" : 'x-*disable-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=no ;; -docdir | --docdir | --docdi | --doc | --do) ac_prev=docdir ;; -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) docdir=$ac_optarg ;; -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) ac_prev=dvidir ;; -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) dvidir=$ac_optarg ;; -enable-* | --enable-*) ac_feature=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_feature" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid feature name: $ac_feature" >&2 { (exit 1); exit 1; }; } ac_feature=`echo $ac_feature | sed 's/[-.]/_/g'` eval enable_$ac_feature=\$ac_optarg ;; -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ | --exec | --exe | --ex) ac_prev=exec_prefix ;; -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ | --exec=* | --exe=* | --ex=*) exec_prefix=$ac_optarg ;; -gas | --gas | --ga | --g) # Obsolete; use --with-gas. with_gas=yes ;; -help | --help | --hel | --he | -h) ac_init_help=long ;; -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) ac_init_help=recursive ;; -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) ac_init_help=short ;; -host | --host | --hos | --ho) ac_prev=host_alias ;; -host=* | --host=* | --hos=* | --ho=*) host_alias=$ac_optarg ;; -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) ac_prev=htmldir ;; -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ | --ht=*) htmldir=$ac_optarg ;; -includedir | --includedir | --includedi | --included | --include \ | --includ | --inclu | --incl | --inc) ac_prev=includedir ;; -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ | --includ=* | --inclu=* | --incl=* | --inc=*) includedir=$ac_optarg ;; -infodir | --infodir | --infodi | --infod | --info | --inf) ac_prev=infodir ;; -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) infodir=$ac_optarg ;; -libdir | --libdir | --libdi | --libd) ac_prev=libdir ;; -libdir=* | --libdir=* | --libdi=* | --libd=*) libdir=$ac_optarg ;; -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ | --libexe | --libex | --libe) ac_prev=libexecdir ;; -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ | --libexe=* | --libex=* | --libe=*) libexecdir=$ac_optarg ;; -localedir | --localedir | --localedi | --localed | --locale) ac_prev=localedir ;; -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) localedir=$ac_optarg ;; -localstatedir | --localstatedir | --localstatedi | --localstated \ | --localstate | --localstat | --localsta | --localst | --locals) ac_prev=localstatedir ;; -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) localstatedir=$ac_optarg ;; -mandir | --mandir | --mandi | --mand | --man | --ma | --m) ac_prev=mandir ;; -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) mandir=$ac_optarg ;; -nfp | --nfp | --nf) # Obsolete; use --without-fp. with_fp=no ;; -no-create | --no-create | --no-creat | --no-crea | --no-cre \ | --no-cr | --no-c | -n) no_create=yes ;; -no-recursion | --no-recursion | --no-recursio | --no-recursi \ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) no_recursion=yes ;; -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ | --oldin | --oldi | --old | --ol | --o) ac_prev=oldincludedir ;; -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) oldincludedir=$ac_optarg ;; -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) ac_prev=prefix ;; -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) prefix=$ac_optarg ;; -program-prefix | --program-prefix | --program-prefi | --program-pref \ | --program-pre | --program-pr | --program-p) ac_prev=program_prefix ;; -program-prefix=* | --program-prefix=* | --program-prefi=* \ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) program_prefix=$ac_optarg ;; -program-suffix | --program-suffix | --program-suffi | --program-suff \ | --program-suf | --program-su | --program-s) ac_prev=program_suffix ;; -program-suffix=* | --program-suffix=* | --program-suffi=* \ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) program_suffix=$ac_optarg ;; -program-transform-name | --program-transform-name \ | --program-transform-nam | --program-transform-na \ | --program-transform-n | --program-transform- \ | --program-transform | --program-transfor \ | --program-transfo | --program-transf \ | --program-trans | --program-tran \ | --progr-tra | --program-tr | --program-t) ac_prev=program_transform_name ;; -program-transform-name=* | --program-transform-name=* \ | --program-transform-nam=* | --program-transform-na=* \ | --program-transform-n=* | --program-transform-=* \ | --program-transform=* | --program-transfor=* \ | --program-transfo=* | --program-transf=* \ | --program-trans=* | --program-tran=* \ | --progr-tra=* | --program-tr=* | --program-t=*) program_transform_name=$ac_optarg ;; -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) ac_prev=pdfdir ;; -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) pdfdir=$ac_optarg ;; -psdir | --psdir | --psdi | --psd | --ps) ac_prev=psdir ;; -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) psdir=$ac_optarg ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) silent=yes ;; -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ | --sbi=* | --sb=*) sbindir=$ac_optarg ;; -sharedstatedir | --sharedstatedir | --sharedstatedi \ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ | --sharedst | --shareds | --shared | --share | --shar \ | --sha | --sh) ac_prev=sharedstatedir ;; -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ | --sha=* | --sh=*) sharedstatedir=$ac_optarg ;; -site | --site | --sit) ac_prev=site ;; -site=* | --site=* | --sit=*) site=$ac_optarg ;; -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) ac_prev=srcdir ;; -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) srcdir=$ac_optarg ;; -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ | --syscon | --sysco | --sysc | --sys | --sy) ac_prev=sysconfdir ;; -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) sysconfdir=$ac_optarg ;; -target | --target | --targe | --targ | --tar | --ta | --t) ac_prev=target_alias ;; -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) target_alias=$ac_optarg ;; -v | -verbose | --verbose | --verbos | --verbo | --verb) verbose=yes ;; -version | --version | --versio | --versi | --vers | -V) ac_init_version=: ;; -with-* | --with-*) ac_package=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=\$ac_optarg ;; -without-* | --without-*) ac_package=`expr "x$ac_option" : 'x-*without-\(.*\)'` # Reject names that are not valid shell variable names. expr "x$ac_package" : ".*[^-._$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid package name: $ac_package" >&2 { (exit 1); exit 1; }; } ac_package=`echo $ac_package | sed 's/[-.]/_/g'` eval with_$ac_package=no ;; --x) # Obsolete; use --with-x. with_x=yes ;; -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ | --x-incl | --x-inc | --x-in | --x-i) ac_prev=x_includes ;; -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) x_includes=$ac_optarg ;; -x-libraries | --x-libraries | --x-librarie | --x-librari \ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) ac_prev=x_libraries ;; -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) x_libraries=$ac_optarg ;; -*) { echo "$as_me: error: unrecognized option: $ac_option Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *=*) ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` # Reject names that are not valid shell variable names. expr "x$ac_envvar" : ".*[^_$as_cr_alnum]" >/dev/null && { echo "$as_me: error: invalid variable name: $ac_envvar" >&2 { (exit 1); exit 1; }; } eval $ac_envvar=\$ac_optarg export $ac_envvar ;; *) # FIXME: should be removed in autoconf 3.0. echo "$as_me: WARNING: you should use --build, --host, --target" >&2 expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && echo "$as_me: WARNING: invalid host type: $ac_option" >&2 : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option} ;; esac done if test -n "$ac_prev"; then ac_option=--`echo $ac_prev | sed 's/_/-/g'` { echo "$as_me: error: missing argument to $ac_option" >&2 { (exit 1); exit 1; }; } fi # Be sure to have absolute directory names. for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ libdir localedir mandir do eval ac_val=\$$ac_var case $ac_val in [\\/$]* | ?:[\\/]* ) continue;; NONE | '' ) case $ac_var in *prefix ) continue;; esac;; esac { echo "$as_me: error: expected an absolute directory name for --$ac_var: $ac_val" >&2 { (exit 1); exit 1; }; } done # There might be people who depend on the old broken behavior: `$host' # used to hold the argument of --host etc. # FIXME: To remove some day. build=$build_alias host=$host_alias target=$target_alias # FIXME: To remove some day. if test "x$host_alias" != x; then if test "x$build_alias" = x; then cross_compiling=maybe echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host. If a cross compiler is detected then cross compile mode will be used." >&2 elif test "x$build_alias" != "x$host_alias"; then cross_compiling=yes fi fi ac_tool_prefix= test -n "$host_alias" && ac_tool_prefix=$host_alias- test "$silent" = yes && exec 6>/dev/null ac_pwd=`pwd` && test -n "$ac_pwd" && ac_ls_di=`ls -di .` && ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || { echo "$as_me: error: Working directory cannot be determined" >&2 { (exit 1); exit 1; }; } test "X$ac_ls_di" = "X$ac_pwd_ls_di" || { echo "$as_me: error: pwd does not report name of working directory" >&2 { (exit 1); exit 1; }; } # Find the source files, if location was not specified. if test -z "$srcdir"; then ac_srcdir_defaulted=yes # Try the directory containing this script, then the parent directory. ac_confdir=`$as_dirname -- "$0" || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$0" : 'X\(//\)[^/]' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` srcdir=$ac_confdir if test ! -r "$srcdir/$ac_unique_file"; then srcdir=.. fi else ac_srcdir_defaulted=no fi if test ! -r "$srcdir/$ac_unique_file"; then test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." { echo "$as_me: error: cannot find sources ($ac_unique_file) in $srcdir" >&2 { (exit 1); exit 1; }; } fi ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" ac_abs_confdir=`( cd "$srcdir" && test -r "./$ac_unique_file" || { echo "$as_me: error: $ac_msg" >&2 { (exit 1); exit 1; }; } pwd)` # When building in place, set srcdir=. if test "$ac_abs_confdir" = "$ac_pwd"; then srcdir=. fi # Remove unnecessary trailing slashes from srcdir. # Double slashes in file names in object file debugging info # mess up M-x gdb in Emacs. case $srcdir in */) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; esac for ac_var in $ac_precious_vars; do eval ac_env_${ac_var}_set=\${${ac_var}+set} eval ac_env_${ac_var}_value=\$${ac_var} eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} eval ac_cv_env_${ac_var}_value=\$${ac_var} done # # Report the --help message. # if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF \`configure' configures this package to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... To assign environment variables (e.g., CC, CFLAGS...), specify them as VAR=VALUE. See below for descriptions of some of the useful variables. Defaults for the options are specified in brackets. Configuration: -h, --help display this help and exit --help=short display options specific to this package --help=recursive display the short help of all the included packages -V, --version display version information and exit -q, --quiet, --silent do not print \`checking...' messages --cache-file=FILE cache test results in FILE [disabled] -C, --config-cache alias for \`--cache-file=config.cache' -n, --no-create do not create output files --srcdir=DIR find the sources in DIR [configure dir or \`..'] Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify an installation prefix other than \`$ac_default_prefix' using \`--prefix', for instance \`--prefix=\$HOME'. For better control, use the options below. Fine tuning of the installation directories: --bindir=DIR user executables [EPREFIX/bin] --sbindir=DIR system admin executables [EPREFIX/sbin] --libexecdir=DIR program executables [EPREFIX/libexec] --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] --datadir=DIR read-only architecture-independent data [DATAROOTDIR] --infodir=DIR info documentation [DATAROOTDIR/info] --localedir=DIR locale-dependent data [DATAROOTDIR/locale] --mandir=DIR man documentation [DATAROOTDIR/man] --docdir=DIR documentation root [DATAROOTDIR/doc/PACKAGE] --htmldir=DIR html documentation [DOCDIR] --dvidir=DIR dvi documentation [DOCDIR] --pdfdir=DIR pdf documentation [DOCDIR] --psdir=DIR ps documentation [DOCDIR] _ACEOF cat <<\_ACEOF _ACEOF fi if test -n "$ac_init_help"; then cat <<\_ACEOF Optional Features: --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-debug enable debugging Optional Packages: --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) --with-libcrypto=(openssl|gnutls) default is openssl Set PKG_CONFIG_PATH to choose a glib installation. Some influential environment variables: CC C compiler command CFLAGS C compiler flags LDFLAGS linker flags, e.g. -L if you have libraries in a nonstandard directory LIBS libraries to pass to the linker, e.g. -l CPPFLAGS C/C++/Objective C preprocessor flags, e.g. -I if you have headers in a nonstandard directory CPP C preprocessor Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. _ACEOF ac_status=$? fi if test "$ac_init_help" = "recursive"; then # If there are subdirs, report their specific --help. for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue test -d "$ac_dir" || continue ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix cd "$ac_dir" || { ac_status=$?; continue; } # Check for guested configure. if test -f "$ac_srcdir/configure.gnu"; then echo && $SHELL "$ac_srcdir/configure.gnu" --help=recursive elif test -f "$ac_srcdir/configure"; then echo && $SHELL "$ac_srcdir/configure" --help=recursive else echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 fi || ac_status=$? cd "$ac_pwd" || { ac_status=$?; break; } done fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF configure generated by GNU Autoconf 2.61 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF exit fi cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. It was created by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was $ $0 $@ _ACEOF exec 5>>config.log { cat <<_ASUNAME ## --------- ## ## Platform. ## ## --------- ## hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` uname -m = `(uname -m) 2>/dev/null || echo unknown` uname -r = `(uname -r) 2>/dev/null || echo unknown` uname -s = `(uname -s) 2>/dev/null || echo unknown` uname -v = `(uname -v) 2>/dev/null || echo unknown` /usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` /bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` /bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` /usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` /usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` /usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` /bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` /usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` /bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` _ASUNAME as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. echo "PATH: $as_dir" done IFS=$as_save_IFS } >&5 cat >&5 <<_ACEOF ## ----------- ## ## Core tests. ## ## ----------- ## _ACEOF # Keep a trace of the command line. # Strip out --no-create and --no-recursion so they do not pile up. # Strip out --silent because we don't want to record it for future runs. # Also quote any args containing shell meta-characters. # Make two passes to allow for proper duplicate-argument suppression. ac_configure_args= ac_configure_args0= ac_configure_args1= ac_must_keep_next=false for ac_pass in 1 2 do for ac_arg do case $ac_arg in -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil) continue ;; *\'*) ac_arg=`echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; esac case $ac_pass in 1) ac_configure_args0="$ac_configure_args0 '$ac_arg'" ;; 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then ac_must_keep_next=false # Got value, back to normal. else case $ac_arg in *=* | --config-cache | -C | -disable-* | --disable-* \ | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ | -with-* | --with-* | -without-* | --without-* | --x) case "$ac_configure_args0 " in "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; esac ;; -* ) ac_must_keep_next=true ;; esac fi ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac done done $as_unset ac_configure_args0 || test "${ac_configure_args0+set}" != set || { ac_configure_args0=; export ac_configure_args0; } $as_unset ac_configure_args1 || test "${ac_configure_args1+set}" != set || { ac_configure_args1=; export ac_configure_args1; } # When interrupted or exit'd, cleanup temporary files, and complete # config.log. We remove comments because anyway the quotes in there # would cause problems or look ugly. # WARNING: Use '\'' to represent an apostrophe within the trap. # WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. trap 'exit_status=$? # Save into config.log some information that might help in debugging. { echo cat <<\_ASBOX ## ---------------- ## ## Cache variables. ## ## ---------------- ## _ASBOX echo # The following way of writing the cache mishandles newlines in values, ( for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( *${as_nl}ac_space=\ *) sed -n \ "s/'\''/'\''\\\\'\'''\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" ;; #( *) sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) echo cat <<\_ASBOX ## ----------------- ## ## Output variables. ## ## ----------------- ## _ASBOX echo for ac_var in $ac_subst_vars do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo if test -n "$ac_subst_files"; then cat <<\_ASBOX ## ------------------- ## ## File substitutions. ## ## ------------------- ## _ASBOX echo for ac_var in $ac_subst_files do eval ac_val=\$$ac_var case $ac_val in *\'\''*) ac_val=`echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; esac echo "$ac_var='\''$ac_val'\''" done | sort echo fi if test -s confdefs.h; then cat <<\_ASBOX ## ----------- ## ## confdefs.h. ## ## ----------- ## _ASBOX echo cat confdefs.h echo fi test "$ac_signal" != 0 && echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 rm -f core *.core core.conftest.* && rm -f -r conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 for ac_signal in 1 2 13 15; do trap 'ac_signal='$ac_signal'; { (exit 1); exit 1; }' $ac_signal done ac_signal=0 # confdefs.h avoids OS command line length limits that DEFS can exceed. rm -f -r conftest* confdefs.h # Predefined preprocessor variables. cat >>confdefs.h <<_ACEOF #define PACKAGE_NAME "$PACKAGE_NAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_TARNAME "$PACKAGE_TARNAME" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_VERSION "$PACKAGE_VERSION" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_STRING "$PACKAGE_STRING" _ACEOF cat >>confdefs.h <<_ACEOF #define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" _ACEOF # Let the site file select an alternate cache file if it wants to. # Prefer explicitly selected file to automatically selected ones. if test -n "$CONFIG_SITE"; then set x "$CONFIG_SITE" elif test "x$prefix" != xNONE; then set x "$prefix/share/config.site" "$prefix/etc/config.site" else set x "$ac_default_prefix/share/config.site" \ "$ac_default_prefix/etc/config.site" fi shift for ac_site_file do if test -r "$ac_site_file"; then { echo "$as_me:$LINENO: loading site script $ac_site_file" >&5 echo "$as_me: loading site script $ac_site_file" >&6;} sed 's/^/| /' "$ac_site_file" >&5 . "$ac_site_file" fi done if test -r "$cache_file"; then # Some versions of bash will fail to source /dev/null (special # files actually), so we avoid doing that. if test -f "$cache_file"; then { echo "$as_me:$LINENO: loading cache $cache_file" >&5 echo "$as_me: loading cache $cache_file" >&6;} case $cache_file in [\\/]* | ?:[\\/]* ) . "$cache_file";; *) . "./$cache_file";; esac fi else { echo "$as_me:$LINENO: creating cache $cache_file" >&5 echo "$as_me: creating cache $cache_file" >&6;} >$cache_file fi # Check that the precious variables saved in the cache have kept the same # value. ac_cache_corrupted=false for ac_var in $ac_precious_vars; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val=\$ac_cv_env_${ac_var}_value eval ac_new_val=\$ac_env_${ac_var}_value case $ac_old_set,$ac_new_set in set,) { echo "$as_me:$LINENO: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} ac_cache_corrupted=: ;; ,set) { echo "$as_me:$LINENO: error: \`$ac_var' was not set in the previous run" >&5 echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} ac_cache_corrupted=: ;; ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. if test "$ac_new_set" = set; then case $ac_new_val in *\'*) ac_arg=$ac_var=`echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; *) ac_arg=$ac_var=$ac_new_val ;; esac case " $ac_configure_args " in *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. *) ac_configure_args="$ac_configure_args '$ac_arg'" ;; esac fi done if $ac_cache_corrupted; then { echo "$as_me:$LINENO: error: changes in the environment can compromise the build" >&5 echo "$as_me: error: changes in the environment can compromise the build" >&2;} { { echo "$as_me:$LINENO: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&5 echo "$as_me: error: run \`make distclean' and/or \`rm $cache_file' and start over" >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu # Check whether --enable-debug was given. if test "${enable_debug+set}" = set; then enableval=$enable_debug; if test -n "$CFLAGS"; then { echo "$as_me:$LINENO: WARNING: ignoring CFLAGS because of --debug" >&5 echo "$as_me: WARNING: ignoring CFLAGS because of --debug" >&2;} fi CFLAGS="-std=c89 -pedantic -g -Wall -Wno-parentheses" fi if test -z "$CFLAGS"; then CFLAGS=-Wno-parentheses fi ac_aux_dir= for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do if test -f "$ac_dir/install-sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install-sh -c" break elif test -f "$ac_dir/install.sh"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/install.sh -c" break elif test -f "$ac_dir/shtool"; then ac_aux_dir=$ac_dir ac_install_sh="$ac_aux_dir/shtool install -c" break fi done if test -z "$ac_aux_dir"; then { { echo "$as_me:$LINENO: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&5 echo "$as_me: error: cannot find install-sh or install.sh in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" >&2;} { (exit 1); exit 1; }; } fi # These three variables are undocumented and unsupported, # and are intended to be withdrawn in a future Autoconf release. # They can cause serious problems if a builder's source tree is in a directory # whose full name contains unusual characters. ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or # incompatible versions: # SysV /etc/install, /usr/sbin/install # SunOS /usr/etc/install # IRIX /sbin/install # AIX /bin/install # AmigaOS /C/install, which installs bootblocks on floppy discs # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. { echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6; } if test -z "$INSTALL"; then if test "${ac_cv_path_install+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. # Account for people who put trailing slashes in PATH elements. case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. # Don't use installbsd from OSF since it installs stuff as root # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then if test $ac_prog = install && grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # AIX install. It has an incompatible calling convention. : elif test $ac_prog = install && grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then # program-specific install script used by HP pwplus--don't use. : else ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" break 3 fi fi done done ;; esac done IFS=$as_save_IFS fi if test "${ac_cv_path_install+set}" = set; then INSTALL=$ac_cv_path_install else # As a last resort, use the slow shell script. Don't cache a # value for INSTALL within a source directory, because that will # break other packages using the cache if that directory is # removed, or if the value is a relative name. INSTALL=$ac_install_sh fi fi { echo "$as_me:$LINENO: result: $INSTALL" >&5 echo "${ECHO_T}$INSTALL" >&6; } # Use test -z because SunOS4 sh mishandles braces in ${var-val}. # It thinks the first close brace ends the variable substitution. test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' # port.c ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. set dummy ${ac_tool_prefix}gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$ac_cv_prog_CC"; then ac_ct_CC=$CC # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="gcc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi else CC="$ac_cv_prog_CC" fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. set dummy ${ac_tool_prefix}cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="${ac_tool_prefix}cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi fi if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else ac_prog_rejected=no as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then ac_prog_rejected=yes continue fi ac_cv_prog_CC="cc" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS if test $ac_prog_rejected = yes; then # We found a bogon in the path, so make sure we never use it. set dummy $ac_cv_prog_CC shift if test $# != 0; then # We chose a different compiler from the bogus one. # However, it has the same basename, so the bogon will be chosen # first if we set CC to just the basename; use the full file name. shift ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" fi fi fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi fi if test -z "$CC"; then if test -n "$ac_tool_prefix"; then for ac_prog in cl.exe do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. set dummy $ac_tool_prefix$ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$CC"; then ac_cv_prog_CC="$CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_CC="$ac_tool_prefix$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi CC=$ac_cv_prog_CC if test -n "$CC"; then { echo "$as_me:$LINENO: result: $CC" >&5 echo "${ECHO_T}$CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$CC" && break done fi if test -z "$CC"; then ac_ct_CC=$CC for ac_prog in cl.exe do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_prog_ac_ct_CC+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if test -n "$ac_ct_CC"; then ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. else as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_prog_ac_ct_CC="$ac_prog" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS fi fi ac_ct_CC=$ac_cv_prog_ac_ct_CC if test -n "$ac_ct_CC"; then { echo "$as_me:$LINENO: result: $ac_ct_CC" >&5 echo "${ECHO_T}$ac_ct_CC" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi test -n "$ac_ct_CC" && break done if test "x$ac_ct_CC" = x; then CC="" else case $cross_compiling:$ac_tool_warned in yes:) { echo "$as_me:$LINENO: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&5 echo "$as_me: WARNING: In the future, Autoconf will not detect cross-tools whose name does not start with the host triplet. If you think this configuration is useful to you, please write to autoconf@gnu.org." >&2;} ac_tool_warned=yes ;; esac CC=$ac_ct_CC fi fi fi test -z "$CC" && { { echo "$as_me:$LINENO: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&5 echo "$as_me: error: no acceptable C compiler found in \$PATH See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } # Provide some information about the compiler. echo "$as_me:$LINENO: checking for C compiler version" >&5 ac_compiler=`set X $ac_compile; echo $2` { (ac_try="$ac_compiler --version >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler --version >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -v >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -v >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } { (ac_try="$ac_compiler -V >&5" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compiler -V >&5") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files a.out a.exe b.out" # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. { echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6; } ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` # # List of possible output files, starting from the most likely. # The algorithm is not robust to junk in `.', hence go to wildcards (a.*) # only as a last resort. b.out is created by i960 compilers. ac_files='a_out.exe a.exe conftest.exe a.out conftest a.* conftest.* b.out' # # The IRIX 6 linker writes into existing files which may not be # executable, retaining their permissions. Remove them first so a # subsequent execution test works. ac_rmfiles= for ac_file in $ac_files do case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; * ) ac_rmfiles="$ac_rmfiles $ac_file";; esac done rm -f $ac_rmfiles if { (ac_try="$ac_link_default" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link_default") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. # So ignore a value of `no', otherwise this would lead to `EXEEXT = no' # in a Makefile. We should not override ac_cv_exeext if it was cached, # so that the user can short-circuit this test for compilers unknown to # Autoconf. for ac_file in $ac_files '' do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; [ab].out ) # We found the default executable, but exeext='' is most # certainly right. break;; *.* ) if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; then :; else ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` fi # We set ac_cv_exeext here because the later test for it is not # safe: cross compilers may not add the suffix if given an `-o' # argument, so we may need to know it at that point already. # Even if this section looks crufty: it has the advantage of # actually working. break;; * ) break;; esac done test "$ac_cv_exeext" = no && ac_cv_exeext= else ac_file='' fi { echo "$as_me:$LINENO: result: $ac_file" >&5 echo "${ECHO_T}$ac_file" >&6; } if test -z "$ac_file"; then echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: C compiler cannot create executables See \`config.log' for more details." >&5 echo "$as_me: error: C compiler cannot create executables See \`config.log' for more details." >&2;} { (exit 77); exit 77; }; } fi ac_exeext=$ac_cv_exeext # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether the C compiler works" >&5 echo $ECHO_N "checking whether the C compiler works... $ECHO_C" >&6; } # FIXME: These cross compiler hacks should be removed for Autoconf 3.0 # If not cross compiling, check that we can run a simple program. if test "$cross_compiling" != yes; then if { ac_try='./$ac_file' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then cross_compiling=no else if test "$cross_compiling" = maybe; then cross_compiling=yes else { { echo "$as_me:$LINENO: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&5 echo "$as_me: error: cannot run C compiled programs. If you meant to cross compile, use \`--host'. See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi fi fi { echo "$as_me:$LINENO: result: yes" >&5 echo "${ECHO_T}yes" >&6; } rm -f a.out a.exe conftest$ac_cv_exeext b.out ac_clean_files=$ac_clean_files_save # Check that the compiler produces executables we can run. If not, either # the compiler is broken, or we cross compile. { echo "$as_me:$LINENO: checking whether we are cross compiling" >&5 echo $ECHO_N "checking whether we are cross compiling... $ECHO_C" >&6; } { echo "$as_me:$LINENO: result: $cross_compiling" >&5 echo "${ECHO_T}$cross_compiling" >&6; } { echo "$as_me:$LINENO: checking for suffix of executables" >&5 echo $ECHO_N "checking for suffix of executables... $ECHO_C" >&6; } if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then # If both `conftest.exe' and `conftest' are `present' (well, observable) # catch `conftest.exe'. For instance with Cygwin, `ls conftest' will # work properly (i.e., refer to `conftest.exe'), while it won't with # `rm'. for ac_file in conftest.exe conftest conftest.*; do test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` break;; * ) break;; esac done else { { echo "$as_me:$LINENO: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of executables: cannot compile and link See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest$ac_cv_exeext { echo "$as_me:$LINENO: result: $ac_cv_exeext" >&5 echo "${ECHO_T}$ac_cv_exeext" >&6; } rm -f conftest.$ac_ext EXEEXT=$ac_cv_exeext ac_exeext=$EXEEXT { echo "$as_me:$LINENO: checking for suffix of object files" >&5 echo $ECHO_N "checking for suffix of object files... $ECHO_C" >&6; } if test "${ac_cv_objext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.o conftest.obj if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; then for ac_file in conftest.o conftest.obj conftest.*; do test -f "$ac_file" || continue; case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf ) ;; *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` break;; esac done else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 { { echo "$as_me:$LINENO: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&5 echo "$as_me: error: cannot compute suffix of object files: cannot compile See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi rm -f conftest.$ac_cv_objext conftest.$ac_ext fi { echo "$as_me:$LINENO: result: $ac_cv_objext" >&5 echo "${ECHO_T}$ac_cv_objext" >&6; } OBJEXT=$ac_cv_objext ac_objext=$OBJEXT { echo "$as_me:$LINENO: checking whether we are using the GNU C compiler" >&5 echo $ECHO_N "checking whether we are using the GNU C compiler... $ECHO_C" >&6; } if test "${ac_cv_c_compiler_gnu+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { #ifndef __GNUC__ choke me #endif ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_compiler_gnu=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_compiler_gnu=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi { echo "$as_me:$LINENO: result: $ac_cv_c_compiler_gnu" >&5 echo "${ECHO_T}$ac_cv_c_compiler_gnu" >&6; } GCC=`test $ac_compiler_gnu = yes && echo yes` ac_test_CFLAGS=${CFLAGS+set} ac_save_CFLAGS=$CFLAGS { echo "$as_me:$LINENO: checking whether $CC accepts -g" >&5 echo $ECHO_N "checking whether $CC accepts -g... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_g+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_save_c_werror_flag=$ac_c_werror_flag ac_c_werror_flag=yes ac_cv_prog_cc_g=no CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 CFLAGS="" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_c_werror_flag=$ac_save_c_werror_flag CFLAGS="-g" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_g=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext ac_c_werror_flag=$ac_save_c_werror_flag fi { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6; } if test "$ac_test_CFLAGS" = set; then CFLAGS=$ac_save_CFLAGS elif test $ac_cv_prog_cc_g = yes; then if test "$GCC" = yes; then CFLAGS="-g -O2" else CFLAGS="-g" fi else if test "$GCC" = yes; then CFLAGS="-O2" else CFLAGS= fi fi { echo "$as_me:$LINENO: checking for $CC option to accept ISO C89" >&5 echo $ECHO_N "checking for $CC option to accept ISO C89... $ECHO_C" >&6; } if test "${ac_cv_prog_cc_c89+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_prog_cc_c89=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include /* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ struct buf { int x; }; FILE * (*rcsopen) (struct buf *, struct stat *, int); static char *e (p, i) char **p; int i; { return p[i]; } static char *f (char * (*g) (char **, int), char **p, ...) { char *s; va_list v; va_start (v,p); s = g (p, va_arg (v,int)); va_end (v); return s; } /* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has function prototypes and stuff, but not '\xHH' hex character constants. These don't provoke an error unfortunately, instead are silently treated as 'x'. The following induces an error, until -std is added to get proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an array size at least. It's necessary to write '\x00'==0 to get something that's true only with -std. */ int osf4_cc_array ['\x00' == 0 ? 1 : -1]; /* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters inside strings and character constants. */ #define FOO(x) 'x' int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); int argc; char **argv; int main () { return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; ; return 0; } _ACEOF for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" do CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_prog_cc_c89=$ac_arg else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext test "x$ac_cv_prog_cc_c89" != "xno" && break done rm -f conftest.$ac_ext CC=$ac_save_CC fi # AC_CACHE_VAL case "x$ac_cv_prog_cc_c89" in x) { echo "$as_me:$LINENO: result: none needed" >&5 echo "${ECHO_T}none needed" >&6; } ;; xno) { echo "$as_me:$LINENO: result: unsupported" >&5 echo "${ECHO_T}unsupported" >&6; } ;; *) CC="$CC $ac_cv_prog_cc_c89" { echo "$as_me:$LINENO: result: $ac_cv_prog_cc_c89" >&5 echo "${ECHO_T}$ac_cv_prog_cc_c89" >&6; } ;; esac ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu for ac_func in mkdtemp do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in on_exit do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done # solaris { echo "$as_me:$LINENO: checking for main in -lsocket" >&5 echo $ECHO_N "checking for main in -lsocket... $ECHO_C" >&6; } if test "${ac_cv_lib_socket_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lsocket $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_socket_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_socket_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_socket_main" >&5 echo "${ECHO_T}$ac_cv_lib_socket_main" >&6; } if test $ac_cv_lib_socket_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSOCKET 1 _ACEOF LIBS="-lsocket $LIBS" fi { echo "$as_me:$LINENO: checking for main in -lresolv" >&5 echo $ECHO_N "checking for main in -lresolv... $ECHO_C" >&6; } if test "${ac_cv_lib_resolv_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lresolv $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_resolv_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_resolv_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_resolv_main" >&5 echo "${ECHO_T}$ac_cv_lib_resolv_main" >&6; } if test $ac_cv_lib_resolv_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBRESOLV 1 _ACEOF LIBS="-lresolv $LIBS" fi # traditional libldap isn't enough { echo "$as_me:$LINENO: checking for main in -llber" >&5 echo $ECHO_N "checking for main in -llber... $ECHO_C" >&6; } if test "${ac_cv_lib_lber_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-llber $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_lber_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_lber_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_lber_main" >&5 echo "${ECHO_T}$ac_cv_lib_lber_main" >&6; } if test $ac_cv_lib_lber_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBLBER 1 _ACEOF LIBS="-llber $LIBS" fi { echo "$as_me:$LINENO: checking for main in -lldap" >&5 echo $ECHO_N "checking for main in -lldap... $ECHO_C" >&6; } if test "${ac_cv_lib_ldap_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_ldap_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ldap_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_main" >&5 echo "${ECHO_T}$ac_cv_lib_ldap_main" >&6; } if test $ac_cv_lib_ldap_main = yes; then : else { { echo "$as_me:$LINENO: error: libldap not found" >&5 echo "$as_me: error: libldap not found" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for ldap_initialize in -lldap" >&5 echo $ECHO_N "checking for ldap_initialize in -lldap... $ECHO_C" >&6; } if test "${ac_cv_lib_ldap_ldap_initialize+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldap_initialize (); int main () { return ldap_initialize (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_ldap_ldap_initialize=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ldap_ldap_initialize=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_initialize" >&5 echo "${ECHO_T}$ac_cv_lib_ldap_ldap_initialize" >&6; } if test $ac_cv_lib_ldap_ldap_initialize = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBLDAP 1 _ACEOF LIBS="-lldap $LIBS" else { { echo "$as_me:$LINENO: error: libldap present but obsolete" >&5 echo "$as_me: error: libldap present but obsolete" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for ldap_bv2dn_x in -lldap" >&5 echo $ECHO_N "checking for ldap_bv2dn_x in -lldap... $ECHO_C" >&6; } if test "${ac_cv_lib_ldap_ldap_bv2dn_x+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lldap $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char ldap_bv2dn_x (); int main () { return ldap_bv2dn_x (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_ldap_ldap_bv2dn_x=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ldap_ldap_bv2dn_x=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ldap_ldap_bv2dn_x" >&5 echo "${ECHO_T}$ac_cv_lib_ldap_ldap_bv2dn_x" >&6; } if test $ac_cv_lib_ldap_ldap_bv2dn_x = yes; then cat >>confdefs.h <<\_ACEOF #define LIBLDAP22 1 _ACEOF else cat >>confdefs.h <<\_ACEOF #define LIBLDAP21 1 _ACEOF fi # sasl ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5 echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6; } # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= fi if test -z "$CPP"; then if test "${ac_cv_prog_CPP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Double quotes because CPP needs to be expanded for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" do ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then break fi done ac_cv_prog_CPP=$CPP fi CPP=$ac_cv_prog_CPP else ac_cv_prog_CPP=$CPP fi { echo "$as_me:$LINENO: result: $CPP" >&5 echo "${ECHO_T}$CPP" >&6; } ac_preproc_ok=false for ac_c_preproc_warn_flag in '' yes do # Use a header file that comes with gcc, so configuring glibc # with a fresh cross-compiler works. # Prefer to if __STDC__ is defined, since # exists even on freestanding compilers. # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #ifdef __STDC__ # include #else # include #endif Syntax error _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then : else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Broken: fails on valid input. continue fi rm -f conftest.err conftest.$ac_ext # OK, works on sane cases. Now check whether nonexistent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then # Broken: success on invalid input. continue else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 # Passes both tests. ac_preproc_ok=: break fi rm -f conftest.err conftest.$ac_ext done # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. rm -f conftest.err conftest.$ac_ext if $ac_preproc_ok; then : else { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&5 echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check See \`config.log' for more details." >&2;} { (exit 1); exit 1; }; } fi ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' ac_compiler_gnu=$ac_cv_c_compiler_gnu { echo "$as_me:$LINENO: checking for grep that handles long lines and -e" >&5 echo $ECHO_N "checking for grep that handles long lines and -e... $ECHO_C" >&6; } if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else # Extract the first word of "grep ggrep" to use in msg output if test -z "$GREP"; then set dummy grep ggrep; ac_prog_name=$2 if test "${ac_cv_path_GREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_GREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in grep ggrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue # Check for GNU ac_path_GREP and select it if it is found. # Check for GNU $ac_path_GREP case `"$ac_path_GREP" --version 2>&1` in *GNU*) ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'GREP' >> "conftest.nl" "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_GREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_GREP_found && break 3 done done done IFS=$as_save_IFS fi GREP="$ac_cv_path_GREP" if test -z "$GREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_GREP=$GREP fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_GREP" >&5 echo "${ECHO_T}$ac_cv_path_GREP" >&6; } GREP="$ac_cv_path_GREP" { echo "$as_me:$LINENO: checking for egrep" >&5 echo $ECHO_N "checking for egrep... $ECHO_C" >&6; } if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 then ac_cv_path_EGREP="$GREP -E" else # Extract the first word of "egrep" to use in msg output if test -z "$EGREP"; then set dummy egrep; ac_prog_name=$2 if test "${ac_cv_path_EGREP+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_path_EGREP_found=false # Loop through the user's path and test for each of PROGNAME-LIST as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_prog in egrep; do for ac_exec_ext in '' $ac_executable_extensions; do ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue # Check for GNU ac_path_EGREP and select it if it is found. # Check for GNU $ac_path_EGREP case `"$ac_path_EGREP" --version 2>&1` in *GNU*) ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; *) ac_count=0 echo $ECHO_N "0123456789$ECHO_C" >"conftest.in" while : do cat "conftest.in" "conftest.in" >"conftest.tmp" mv "conftest.tmp" "conftest.in" cp "conftest.in" "conftest.nl" echo 'EGREP' >> "conftest.nl" "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break ac_count=`expr $ac_count + 1` if test $ac_count -gt ${ac_path_EGREP_max-0}; then # Best one so far, save it but keep looking for a better one ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_max=$ac_count fi # 10*(2^10) chars as input seems more than enough test $ac_count -gt 10 && break done rm -f conftest.in conftest.tmp conftest.nl conftest.out;; esac $ac_path_EGREP_found && break 3 done done done IFS=$as_save_IFS fi EGREP="$ac_cv_path_EGREP" if test -z "$EGREP"; then { { echo "$as_me:$LINENO: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&5 echo "$as_me: error: no acceptable $ac_prog_name could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" >&2;} { (exit 1); exit 1; }; } fi else ac_cv_path_EGREP=$EGREP fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_path_EGREP" >&5 echo "${ECHO_T}$ac_cv_path_EGREP" >&6; } EGREP="$ac_cv_path_EGREP" { echo "$as_me:$LINENO: checking for ANSI C header files" >&5 echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; } if test "${ac_cv_header_stdc+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #include #include int main () { ; return 0; } _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_cv_header_stdc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_header_stdc=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "memchr" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | $EGREP "free" >/dev/null 2>&1; then : else ac_cv_header_stdc=no fi rm -f conftest* fi if test $ac_cv_header_stdc = yes; then # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. if test "$cross_compiling" = yes; then : else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include #include #if ((' ' & 0x0FF) == 0x020) # define ISLOWER(c) ('a' <= (c) && (c) <= 'z') # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ (('a' <= (c) && (c) <= 'i') \ || ('j' <= (c) && (c) <= 'r') \ || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif #define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) int main () { int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) return 2; return 0; } _ACEOF rm -f conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { ac_try='./conftest$ac_exeext' { (case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_try") 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else echo "$as_me: program exited with status $ac_status" >&5 echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ( exit $ac_status ) ac_cv_header_stdc=no fi rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi { echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5 echo "${ECHO_T}$ac_cv_header_stdc" >&6; } if test $ac_cv_header_stdc = yes; then cat >>confdefs.h <<\_ACEOF #define STDC_HEADERS 1 _ACEOF fi # On IRIX 5.3, sys/types and inttypes.h are conflicting. for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_header" >&5 echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; } if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include <$ac_header> _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then eval "$as_ac_Header=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_Header=no" fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_Header'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_Header'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_header" | $as_tr_cpp` 1 _ACEOF fi done if test "${ac_cv_header_sasl_sasl_h+set}" = set; then { echo "$as_me:$LINENO: checking for sasl/sasl.h" >&5 echo $ECHO_N "checking for sasl/sasl.h... $ECHO_C" >&6; } if test "${ac_cv_header_sasl_sasl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_sasl_sasl_h" >&5 echo "${ECHO_T}$ac_cv_header_sasl_sasl_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking sasl/sasl.h usability" >&5 echo $ECHO_N "checking sasl/sasl.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking sasl/sasl.h presence" >&5 echo $ECHO_N "checking sasl/sasl.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: sasl/sasl.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: sasl/sasl.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: sasl/sasl.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: sasl/sasl.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: sasl/sasl.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: sasl/sasl.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: sasl/sasl.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: sasl/sasl.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: sasl/sasl.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for sasl/sasl.h" >&5 echo $ECHO_N "checking for sasl/sasl.h... $ECHO_C" >&6; } if test "${ac_cv_header_sasl_sasl_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_sasl_sasl_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_sasl_sasl_h" >&5 echo "${ECHO_T}$ac_cv_header_sasl_sasl_h" >&6; } fi if test $ac_cv_header_sasl_sasl_h = yes; then cat >>confdefs.h <<\_ACEOF #define HAVE_SASL 1 _ACEOF else { echo "$as_me:$LINENO: WARNING: SASL support disabled" >&5 echo "$as_me: WARNING: SASL support disabled" >&2;} fi # terminfo { echo "$as_me:$LINENO: checking for library containing tigetstr" >&5 echo $ECHO_N "checking for library containing tigetstr... $ECHO_C" >&6; } if test "${ac_cv_search_tigetstr+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_func_search_save_LIBS=$LIBS cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char tigetstr (); int main () { return tigetstr (); ; return 0; } _ACEOF for ac_lib in '' curses ncurses; do if test -z "$ac_lib"; then ac_res="none required" else ac_res=-l$ac_lib LIBS="-l$ac_lib $ac_func_search_save_LIBS" fi rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_search_tigetstr=$ac_res else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext if test "${ac_cv_search_tigetstr+set}" = set; then break fi done if test "${ac_cv_search_tigetstr+set}" = set; then : else ac_cv_search_tigetstr=no fi rm conftest.$ac_ext LIBS=$ac_func_search_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_search_tigetstr" >&5 echo "${ECHO_T}$ac_cv_search_tigetstr" >&6; } ac_res=$ac_cv_search_tigetstr if test "$ac_res" != no; then test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" else { { echo "$as_me:$LINENO: error: libcurses not found" >&5 echo "$as_me: error: libcurses not found" >&2;} { (exit 1); exit 1; }; } fi if test "${ac_cv_header_curses_h+set}" = set; then { echo "$as_me:$LINENO: checking for curses.h" >&5 echo $ECHO_N "checking for curses.h... $ECHO_C" >&6; } if test "${ac_cv_header_curses_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 fi { echo "$as_me:$LINENO: result: $ac_cv_header_curses_h" >&5 echo "${ECHO_T}$ac_cv_header_curses_h" >&6; } else # Is the header compilable? { echo "$as_me:$LINENO: checking curses.h usability" >&5 echo $ECHO_N "checking curses.h usability... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ $ac_includes_default #include _ACEOF rm -f conftest.$ac_objext if { (ac_try="$ac_compile" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_compile") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest.$ac_objext; then ac_header_compiler=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_compiler=no fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_compiler" >&5 echo "${ECHO_T}$ac_header_compiler" >&6; } # Is the header present? { echo "$as_me:$LINENO: checking curses.h presence" >&5 echo $ECHO_N "checking curses.h presence... $ECHO_C" >&6; } cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ #include _ACEOF if { (ac_try="$ac_cpp conftest.$ac_ext" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } >/dev/null && { test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || test ! -s conftest.err }; then ac_header_preproc=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_header_preproc=no fi rm -f conftest.err conftest.$ac_ext { echo "$as_me:$LINENO: result: $ac_header_preproc" >&5 echo "${ECHO_T}$ac_header_preproc" >&6; } # So? What about this header? case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in yes:no: ) { echo "$as_me:$LINENO: WARNING: curses.h: accepted by the compiler, rejected by the preprocessor!" >&5 echo "$as_me: WARNING: curses.h: accepted by the compiler, rejected by the preprocessor!" >&2;} { echo "$as_me:$LINENO: WARNING: curses.h: proceeding with the compiler's result" >&5 echo "$as_me: WARNING: curses.h: proceeding with the compiler's result" >&2;} ac_header_preproc=yes ;; no:yes:* ) { echo "$as_me:$LINENO: WARNING: curses.h: present but cannot be compiled" >&5 echo "$as_me: WARNING: curses.h: present but cannot be compiled" >&2;} { echo "$as_me:$LINENO: WARNING: curses.h: check for missing prerequisite headers?" >&5 echo "$as_me: WARNING: curses.h: check for missing prerequisite headers?" >&2;} { echo "$as_me:$LINENO: WARNING: curses.h: see the Autoconf documentation" >&5 echo "$as_me: WARNING: curses.h: see the Autoconf documentation" >&2;} { echo "$as_me:$LINENO: WARNING: curses.h: section \"Present But Cannot Be Compiled\"" >&5 echo "$as_me: WARNING: curses.h: section \"Present But Cannot Be Compiled\"" >&2;} { echo "$as_me:$LINENO: WARNING: curses.h: proceeding with the preprocessor's result" >&5 echo "$as_me: WARNING: curses.h: proceeding with the preprocessor's result" >&2;} { echo "$as_me:$LINENO: WARNING: curses.h: in the future, the compiler will take precedence" >&5 echo "$as_me: WARNING: curses.h: in the future, the compiler will take precedence" >&2;} ;; esac { echo "$as_me:$LINENO: checking for curses.h" >&5 echo $ECHO_N "checking for curses.h... $ECHO_C" >&6; } if test "${ac_cv_header_curses_h+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_cv_header_curses_h=$ac_header_preproc fi { echo "$as_me:$LINENO: result: $ac_cv_header_curses_h" >&5 echo "${ECHO_T}$ac_cv_header_curses_h" >&6; } fi if test $ac_cv_header_curses_h = yes; then : else { { echo "$as_me:$LINENO: error: curses.h not found" >&5 echo "$as_me: error: curses.h not found" >&2;} { (exit 1); exit 1; }; } fi # popt { echo "$as_me:$LINENO: checking for poptGetContext in -lpopt" >&5 echo $ECHO_N "checking for poptGetContext in -lpopt... $ECHO_C" >&6; } if test "${ac_cv_lib_popt_poptGetContext+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lpopt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char poptGetContext (); int main () { return poptGetContext (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_popt_poptGetContext=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_popt_poptGetContext=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_popt_poptGetContext" >&5 echo "${ECHO_T}$ac_cv_lib_popt_poptGetContext" >&6; } if test $ac_cv_lib_popt_poptGetContext = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBPOPT 1 _ACEOF LIBS="-lpopt $LIBS" else { { echo "$as_me:$LINENO: error: libpopt not found" >&5 echo "$as_me: error: libpopt not found" >&2;} { (exit 1); exit 1; }; } fi # readline { echo "$as_me:$LINENO: checking for readline in -lreadline" >&5 echo $ECHO_N "checking for readline in -lreadline... $ECHO_C" >&6; } if test "${ac_cv_lib_readline_readline+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lreadline $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char readline (); int main () { return readline (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_readline_readline=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_readline_readline=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_readline_readline" >&5 echo "${ECHO_T}$ac_cv_lib_readline_readline" >&6; } if test $ac_cv_lib_readline_readline = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBREADLINE 1 _ACEOF LIBS="-lreadline $LIBS" else { { echo "$as_me:$LINENO: error: libreadline not found" >&5 echo "$as_me: error: libreadline not found" >&2;} { (exit 1); exit 1; }; } fi # pkg-config # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 { echo "$as_me:$LINENO: checking for $ac_word" >&5 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; } if test "${ac_cv_path_PKG_CONFIG+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else case $PKG_CONFIG in [\\/]* | ?:[\\/]*) ac_cv_path_PKG_CONFIG="$PKG_CONFIG" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. for ac_exec_ext in '' $ac_executable_extensions; do if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then ac_cv_path_PKG_CONFIG="$as_dir/$ac_word$ac_exec_ext" echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi done done IFS=$as_save_IFS test -z "$ac_cv_path_PKG_CONFIG" && ac_cv_path_PKG_CONFIG="no" ;; esac fi PKG_CONFIG=$ac_cv_path_PKG_CONFIG if test -n "$PKG_CONFIG"; then { echo "$as_me:$LINENO: result: $PKG_CONFIG" >&5 echo "${ECHO_T}$PKG_CONFIG" >&6; } else { echo "$as_me:$LINENO: result: no" >&5 echo "${ECHO_T}no" >&6; } fi if test "x$PKG_CONFIG" = "xno"; then { { echo "$as_me:$LINENO: error: pkg-config not found" >&5 echo "$as_me: error: pkg-config not found" >&2;} { (exit 1); exit 1; }; }; fi # glib LIBS="`$PKG_CONFIG --libs glib-2.0` $LIBS" CFLAGS="`$PKG_CONFIG --cflags glib-2.0` $CFLAGS" { echo "$as_me:$LINENO: checking for main in -lglib-2.0" >&5 echo $ECHO_N "checking for main in -lglib-2.0... $ECHO_C" >&6; } if test "${ac_cv_lib_glib_2_0_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lglib-2.0 $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_glib_2_0_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_glib_2_0_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_glib_2_0_main" >&5 echo "${ECHO_T}$ac_cv_lib_glib_2_0_main" >&6; } if test $ac_cv_lib_glib_2_0_main = yes; then : else { { echo "$as_me:$LINENO: error: libglib2.0 not found" >&5 echo "$as_me: error: libglib2.0 not found" >&2;} { (exit 1); exit 1; }; } fi # libcrypto # Check whether --with-libcrypto was given. if test "${with_libcrypto+set}" = set; then withval=$with_libcrypto; else with_libcrypto=openssl fi case $with_libcrypto in openssl) LIBS="`$PKG_CONFIG --libs openssl` $LIBS" CFLAGS="`$PKG_CONFIG --cflags openssl` $CFLAGS" { echo "$as_me:$LINENO: checking for main in -lssl" >&5 echo $ECHO_N "checking for main in -lssl... $ECHO_C" >&6; } if test "${ac_cv_lib_ssl_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lssl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_ssl_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_ssl_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_ssl_main" >&5 echo "${ECHO_T}$ac_cv_lib_ssl_main" >&6; } if test $ac_cv_lib_ssl_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBSSL 1 _ACEOF LIBS="-lssl $LIBS" else { { echo "$as_me:$LINENO: error: OpenSSL not found" >&5 echo "$as_me: error: OpenSSL not found" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<\_ACEOF #define HAVE_OPENSSL 1 _ACEOF ;; gnutls) LIBS="`$PKG_CONFIG --libs gnutls` $LIBS" CFLAGS="`$PKG_CONFIG --cflags gnutls` $CFLAGS" { echo "$as_me:$LINENO: checking for main in -lgnutls" >&5 echo $ECHO_N "checking for main in -lgnutls... $ECHO_C" >&6; } if test "${ac_cv_lib_gnutls_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgnutls $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gnutls_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gnutls_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gnutls_main" >&5 echo "${ECHO_T}$ac_cv_lib_gnutls_main" >&6; } if test $ac_cv_lib_gnutls_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBGNUTLS 1 _ACEOF LIBS="-lgnutls $LIBS" else { { echo "$as_me:$LINENO: error: GnuTLS not found" >&5 echo "$as_me: error: GnuTLS not found" >&2;} { (exit 1); exit 1; }; } fi { echo "$as_me:$LINENO: checking for main in -lgnutls-openssl" >&5 echo $ECHO_N "checking for main in -lgnutls-openssl... $ECHO_C" >&6; } if test "${ac_cv_lib_gnutls_openssl_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lgnutls-openssl $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_gnutls_openssl_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_gnutls_openssl_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_gnutls_openssl_main" >&5 echo "${ECHO_T}$ac_cv_lib_gnutls_openssl_main" >&6; } if test $ac_cv_lib_gnutls_openssl_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBGNUTLS_OPENSSL 1 _ACEOF LIBS="-lgnutls-openssl $LIBS" else { { echo "$as_me:$LINENO: error: libgnutls-openssl not found" >&5 echo "$as_me: error: libgnutls-openssl not found" >&2;} { (exit 1); exit 1; }; } fi cat >>confdefs.h <<\_ACEOF #define HAVE_GNUTLS 1 _ACEOF cat >>confdefs.h <<\_ACEOF #define SHA_DIGEST_LENGTH 20 _ACEOF ;; *) { { echo "$as_me:$LINENO: error: invalid value --with-libcrypto=$with_libcrypto, expected openssl or gnutls" >&5 echo "$as_me: error: invalid value --with-libcrypto=$with_libcrypto, expected openssl or gnutls" >&2;} { (exit 1); exit 1; }; } ;; esac for ac_func in SHA1 do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done for ac_func in RAND_pseudo_bytes do as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh` { echo "$as_me:$LINENO: checking for $ac_func" >&5 echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; } if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ /* Define $ac_func to an innocuous variant, in case declares $ac_func. For example, HP-UX 11i declares gettimeofday. */ #define $ac_func innocuous_$ac_func /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func (); below. Prefer to if __STDC__ is defined, since exists even on freestanding compilers. */ #ifdef __STDC__ # include #else # include #endif #undef $ac_func /* Override any GCC internal prototype to avoid an error. Use char because int might match the return type of a GCC builtin and then its argument prototype would still apply. */ #ifdef __cplusplus extern "C" #endif char $ac_func (); /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ #if defined __stub_$ac_func || defined __stub___$ac_func choke me #endif int main () { return $ac_func (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then eval "$as_ac_var=yes" else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 eval "$as_ac_var=no" fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext fi ac_res=`eval echo '${'$as_ac_var'}'` { echo "$as_me:$LINENO: result: $ac_res" >&5 echo "${ECHO_T}$ac_res" >&6; } if test `eval echo '${'$as_ac_var'}'` = yes; then cat >>confdefs.h <<_ACEOF #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1 _ACEOF fi done { echo "$as_me:$LINENO: checking for main in -lcrypt" >&5 echo $ECHO_N "checking for main in -lcrypt... $ECHO_C" >&6; } if test "${ac_cv_lib_crypt_main+set}" = set; then echo $ECHO_N "(cached) $ECHO_C" >&6 else ac_check_lib_save_LIBS=$LIBS LIBS="-lcrypt $LIBS" cat >conftest.$ac_ext <<_ACEOF /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ int main () { return main (); ; return 0; } _ACEOF rm -f conftest.$ac_objext conftest$ac_exeext if { (ac_try="$ac_link" case "(($ac_try" in *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; *) ac_try_echo=$ac_try;; esac eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5 (eval "$ac_link") 2>conftest.er1 ac_status=$? grep -v '^ *+' conftest.er1 >conftest.err rm -f conftest.er1 cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && { test -z "$ac_c_werror_flag" || test ! -s conftest.err } && test -s conftest$ac_exeext && $as_test_x conftest$ac_exeext; then ac_cv_lib_crypt_main=yes else echo "$as_me: failed program was:" >&5 sed 's/^/| /' conftest.$ac_ext >&5 ac_cv_lib_crypt_main=no fi rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \ conftest$ac_exeext conftest.$ac_ext LIBS=$ac_check_lib_save_LIBS fi { echo "$as_me:$LINENO: result: $ac_cv_lib_crypt_main" >&5 echo "${ECHO_T}$ac_cv_lib_crypt_main" >&6; } if test $ac_cv_lib_crypt_main = yes; then cat >>confdefs.h <<_ACEOF #define HAVE_LIBCRYPT 1 _ACEOF LIBS="-lcrypt $LIBS" fi # Check whether --with-dummy was given. if test "${with_dummy+set}" = set; then withval=$with_dummy; fi ac_config_headers="$ac_config_headers config.h" ac_config_files="$ac_config_files GNUmakefile" cat >confcache <<\_ACEOF # This file is a shell script that caches the results of configure # tests run on this system so they can be shared between configure # scripts and configure runs, see configure's option --config-cache. # It is not useful on other systems. If it contains results you don't # want to keep, you may remove or edit it. # # config.status only pays attention to the cache file if you give it # the --recheck option to rerun configure. # # `ac_cv_env_foo' variables (set or unset) will be overridden when # loading this file, other *unset* `ac_cv_foo' will be assigned the # following values. _ACEOF # The following way of writing the cache mishandles newlines in values, # but we know of no workaround that is simple, portable, and efficient. # So, we kill variables containing newlines. # Ultrix sh set writes to stderr and can't be redirected directly, # and sets the high bit in the cache file unless we assign to the vars. ( for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do eval ac_val=\$$ac_var case $ac_val in #( *${as_nl}*) case $ac_var in #( *_cv_*) { echo "$as_me:$LINENO: WARNING: Cache variable $ac_var contains a newline." >&5 echo "$as_me: WARNING: Cache variable $ac_var contains a newline." >&2;} ;; esac case $ac_var in #( _ | IFS | as_nl) ;; #( *) $as_unset $ac_var ;; esac ;; esac done (set) 2>&1 | case $as_nl`(ac_space=' '; set) 2>&1` in #( *${as_nl}ac_space=\ *) # `set' does not quote correctly, so add quotes (double-quote # substitution turns \\\\ into \\, and sed turns \\ into \). sed -n \ "s/'/'\\\\''/g; s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" ;; #( *) # `set' quotes correctly as required by POSIX, so do not add quotes. sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" ;; esac | sort ) | sed ' /^ac_cv_env_/b end t clear :clear s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ t end s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ :end' >>confcache if diff "$cache_file" confcache >/dev/null 2>&1; then :; else if test -w "$cache_file"; then test "x$cache_file" != "x/dev/null" && { echo "$as_me:$LINENO: updating cache $cache_file" >&5 echo "$as_me: updating cache $cache_file" >&6;} cat confcache >$cache_file else { echo "$as_me:$LINENO: not updating unwritable cache $cache_file" >&5 echo "$as_me: not updating unwritable cache $cache_file" >&6;} fi fi rm -f confcache test "x$prefix" = xNONE && prefix=$ac_default_prefix # Let make expand exec_prefix. test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' DEFS=-DHAVE_CONFIG_H ac_libobjs= ac_ltlibobjs= for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue # 1. Remove the extension, and $U if already installed. ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' ac_i=`echo "$ac_i" | sed "$ac_script"` # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR # will be set to the directory where LIBOBJS objects are built. ac_libobjs="$ac_libobjs \${LIBOBJDIR}$ac_i\$U.$ac_objext" ac_ltlibobjs="$ac_ltlibobjs \${LIBOBJDIR}$ac_i"'$U.lo' done LIBOBJS=$ac_libobjs LTLIBOBJS=$ac_ltlibobjs : ${CONFIG_STATUS=./config.status} ac_clean_files_save=$ac_clean_files ac_clean_files="$ac_clean_files $CONFIG_STATUS" { echo "$as_me:$LINENO: creating $CONFIG_STATUS" >&5 echo "$as_me: creating $CONFIG_STATUS" >&6;} cat >$CONFIG_STATUS <<_ACEOF #! $SHELL # Generated by $as_me. # Run this file to recreate the current configuration. # Compiler output produced by configure, useful for debugging # configure, is in config.log if it exists. debug=false ac_cs_recheck=false ac_cs_silent=false SHELL=\${CONFIG_SHELL-$SHELL} _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ## --------------------- ## ## M4sh Initialization. ## ## --------------------- ## # Be more Bourne compatible DUALCASE=1; export DUALCASE # for MKS sh if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then emulate sh NULLCMD=: # Zsh 3.x and 4.x performs word splitting on ${1+"$@"}, which # is contrary to our usage. Disable this feature. alias -g '${1+"$@"}'='"$@"' setopt NO_GLOB_SUBST else case `(set -o) 2>/dev/null` in *posix*) set -o posix ;; esac fi # PATH needs CR # Avoid depending upon Character Ranges. as_cr_letters='abcdefghijklmnopqrstuvwxyz' as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' as_cr_Letters=$as_cr_letters$as_cr_LETTERS as_cr_digits='0123456789' as_cr_alnum=$as_cr_Letters$as_cr_digits # The user is always right. if test "${PATH_SEPARATOR+set}" != set; then echo "#! /bin/sh" >conf$$.sh echo "exit 0" >>conf$$.sh chmod +x conf$$.sh if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then PATH_SEPARATOR=';' else PATH_SEPARATOR=: fi rm -f conf$$.sh fi # Support unset when possible. if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false fi # IFS # We need space, tab and new line, in precisely that order. Quoting is # there to prevent editors from complaining about space-tab. # (If _AS_PATH_WALK were called with IFS unset, it would disable word # splitting by setting IFS to empty value.) as_nl=' ' IFS=" "" $as_nl" # Find who we are. Look in the path if we contain no directory separator. case $0 in *[\\/]* ) as_myself=$0 ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR for as_dir in $PATH do IFS=$as_save_IFS test -z "$as_dir" && as_dir=. test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break done IFS=$as_save_IFS ;; esac # We did not find ourselves, most probably we were run as `sh COMMAND' # in which case we are not to be found in the path. if test "x$as_myself" = x; then as_myself=$0 fi if test ! -f "$as_myself"; then echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 { (exit 1); exit 1; } fi # Work around bugs in pre-3.0 UWIN ksh. for as_var in ENV MAIL MAILPATH do ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var done PS1='$ ' PS2='> ' PS4='+ ' # NLS nuisances. for as_var in \ LANG LANGUAGE LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION \ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else ($as_unset $as_var) >/dev/null 2>&1 && $as_unset $as_var fi done # Required to use basename. if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then as_basename=basename else as_basename=false fi # Name of the executable. as_me=`$as_basename -- "$0" || $as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ X"$0" : 'X\(//\)$' \| \ X"$0" : 'X\(/\)' \| . 2>/dev/null || echo X/"$0" | sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } /^X\/\(\/\/\)$/{ s//\1/ q } /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` # CDPATH. $as_unset CDPATH as_lineno_1=$LINENO as_lineno_2=$LINENO test "x$as_lineno_1" != "x$as_lineno_2" && test "x`expr $as_lineno_1 + 1`" = "x$as_lineno_2" || { # Create $as_me.lineno as a copy of $as_myself, but with $LINENO # uniformly replaced by the line number. The first 'sed' inserts a # line-number line after each line using $LINENO; the second 'sed' # does the real work. The second script uses 'N' to pair each # line-number line with the line containing $LINENO, and appends # trailing '-' during substitution so that $LINENO is not a special # case at line end. # (Raja R Harinath suggested sed '=', and Paul Eggert wrote the # scripts with optimization help from Paolo Bonzini. Blame Lee # E. McMahon (1931-1989) for sed's syntax. :-) sed -n ' p /[$]LINENO/= ' <$as_myself | sed ' s/[$]LINENO.*/&-/ t lineno b :lineno N :loop s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ t loop s/-\n.*// ' >$as_me.lineno && chmod +x "$as_me.lineno" || { echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2 { (exit 1); exit 1; }; } # Don't try to exec as it changes $[0], causing all sort of problems # (the dirname of $[0] is not the place where we might find the # original and so on. Autoconf is especially sensitive to this). . "./$as_me.lineno" # Exit status is that of the last command. exit } if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then as_dirname=dirname else as_dirname=false fi ECHO_C= ECHO_N= ECHO_T= case `echo -n x` in -n*) case `echo 'x\c'` in *c*) ECHO_T=' ';; # ECHO_T is single tab character. *) ECHO_C='\c';; esac;; *) ECHO_N='-n';; esac if expr a : '\(a\)' >/dev/null 2>&1 && test "X`expr 00001 : '.*\(...\)'`" = X001; then as_expr=expr else as_expr=false fi rm -f conf$$ conf$$.exe conf$$.file if test -d conf$$.dir; then rm -f conf$$.dir/conf$$.file else rm -f conf$$.dir mkdir conf$$.dir fi echo >conf$$.file if ln -s conf$$.file conf$$ 2>/dev/null; then as_ln_s='ln -s' # ... but there are two gotchas: # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. # In both cases, we have to default to `cp -p'. ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || as_ln_s='cp -p' elif ln conf$$.file conf$$ 2>/dev/null; then as_ln_s=ln else as_ln_s='cp -p' fi rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file rmdir conf$$.dir 2>/dev/null if mkdir -p . 2>/dev/null; then as_mkdir_p=: else test -d ./-p && rmdir ./-p as_mkdir_p=false fi if test -x / >/dev/null 2>&1; then as_test_x='test -x' else if ls -dL / >/dev/null 2>&1; then as_ls_L_option=L else as_ls_L_option= fi as_test_x=' eval sh -c '\'' if test -d "$1"; then test -d "$1/."; else case $1 in -*)set "./$1";; esac; case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in ???[sx]*):;;*)false;;esac;fi '\'' sh ' fi as_executable_p=$as_test_x # Sed expression to map a string onto a valid CPP name. as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" exec 6>&1 # Save the log message, to keep $[0] and so on meaningful, and to # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" This file was extended by $as_me, which was generated by GNU Autoconf 2.61. Invocation command line was CONFIG_FILES = $CONFIG_FILES CONFIG_HEADERS = $CONFIG_HEADERS CONFIG_LINKS = $CONFIG_LINKS CONFIG_COMMANDS = $CONFIG_COMMANDS $ $0 $@ on `(hostname || uname -n) 2>/dev/null | sed 1q` " _ACEOF cat >>$CONFIG_STATUS <<_ACEOF # Files that config.status was made for. config_files="$ac_config_files" config_headers="$ac_config_headers" _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF ac_cs_usage="\ \`$as_me' instantiates files from templates according to the current configuration. Usage: $0 [OPTIONS] [FILE]... -h, --help print this help, then exit -V, --version print version number and configuration settings, then exit -q, --quiet do not print progress messages -d, --debug don't remove temporary files --recheck update $as_me by reconfiguring in the same conditions --file=FILE[:TEMPLATE] instantiate the configuration file FILE --header=FILE[:TEMPLATE] instantiate the configuration header FILE Configuration files: $config_files Configuration headers: $config_headers Report bugs to ." _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_cs_version="\\ config.status configured by $0, generated by GNU Autoconf 2.61, with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\" Copyright (C) 2006 Free Software Foundation, Inc. This config.status script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it." ac_pwd='$ac_pwd' srcdir='$srcdir' INSTALL='$INSTALL' _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If no file are specified by the user, then we need to provide default # value. By we need to know if files were specified by the user. ac_need_defaults=: while test $# != 0 do case $1 in --*=*) ac_option=`expr "X$1" : 'X\([^=]*\)='` ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` ac_shift=: ;; *) ac_option=$1 ac_optarg=$2 ac_shift=shift ;; esac case $ac_option in # Handling of the options. -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) ac_cs_recheck=: ;; --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) echo "$ac_cs_version"; exit ;; --debug | --debu | --deb | --de | --d | -d ) debug=: ;; --file | --fil | --fi | --f ) $ac_shift CONFIG_FILES="$CONFIG_FILES $ac_optarg" ac_need_defaults=false;; --header | --heade | --head | --hea ) $ac_shift CONFIG_HEADERS="$CONFIG_HEADERS $ac_optarg" ac_need_defaults=false;; --he | --h) # Conflict between --help and --header { echo "$as_me: error: ambiguous option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; };; --help | --hel | -h ) echo "$ac_cs_usage"; exit ;; -q | -quiet | --quiet | --quie | --qui | --qu | --q \ | -silent | --silent | --silen | --sile | --sil | --si | --s) ac_cs_silent=: ;; # This is an error. -*) { echo "$as_me: error: unrecognized option: $1 Try \`$0 --help' for more information." >&2 { (exit 1); exit 1; }; } ;; *) ac_config_targets="$ac_config_targets $1" ac_need_defaults=false ;; esac shift done ac_configure_extra_args= if $ac_cs_silent; then exec 6>/dev/null ac_configure_extra_args="$ac_configure_extra_args --silent" fi _ACEOF cat >>$CONFIG_STATUS <<_ACEOF if \$ac_cs_recheck; then echo "running CONFIG_SHELL=$SHELL $SHELL $0 "$ac_configure_args \$ac_configure_extra_args " --no-create --no-recursion" >&6 CONFIG_SHELL=$SHELL export CONFIG_SHELL exec $SHELL "$0"$ac_configure_args \$ac_configure_extra_args --no-create --no-recursion fi _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF exec 5>>config.log { echo sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX ## Running $as_me. ## _ASBOX echo "$ac_log" } >&5 _ACEOF cat >>$CONFIG_STATUS <<_ACEOF _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # Handling of arguments. for ac_config_target in $ac_config_targets do case $ac_config_target in "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;; "GNUmakefile") CONFIG_FILES="$CONFIG_FILES GNUmakefile" ;; *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5 echo "$as_me: error: invalid argument: $ac_config_target" >&2;} { (exit 1); exit 1; }; };; esac done # If the user did not use the arguments to specify the items to instantiate, # then the envvar interface is used. Set only those that are not. # We use the long form for the default assignment because of an extremely # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers fi # Have a temporary directory for convenience. Make it in the build tree # simply because there is no reason against having it here, and in addition, # creating and moving files from /tmp can sometimes cause problems. # Hook for its removal unless debugging. # Note that there is a small window in which the directory will not be cleaned: # after its creation but before its name has been assigned to `$tmp'. $debug || { tmp= trap 'exit_status=$? { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status ' 0 trap '{ (exit 1); exit 1; }' 1 2 13 15 } # Create a (secure) tmp directory for tmp files. { tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" } || { tmp=./conf$$-$RANDOM (umask 077 && mkdir "$tmp") } || { echo "$me: cannot create a temporary directory in ." >&2 { (exit 1); exit 1; } } # # Set up the sed scripts for CONFIG_FILES section. # # No need to generate the scripts if there are no CONFIG_FILES. # This happens for instance when ./config.status config.h if test -n "$CONFIG_FILES"; then _ACEOF ac_delim='%!_!# ' for ac_last_try in false false false false false :; do cat >conf$$subs.sed <<_ACEOF SHELL!$SHELL$ac_delim PATH_SEPARATOR!$PATH_SEPARATOR$ac_delim PACKAGE_NAME!$PACKAGE_NAME$ac_delim PACKAGE_TARNAME!$PACKAGE_TARNAME$ac_delim PACKAGE_VERSION!$PACKAGE_VERSION$ac_delim PACKAGE_STRING!$PACKAGE_STRING$ac_delim PACKAGE_BUGREPORT!$PACKAGE_BUGREPORT$ac_delim exec_prefix!$exec_prefix$ac_delim prefix!$prefix$ac_delim program_transform_name!$program_transform_name$ac_delim bindir!$bindir$ac_delim sbindir!$sbindir$ac_delim libexecdir!$libexecdir$ac_delim datarootdir!$datarootdir$ac_delim datadir!$datadir$ac_delim sysconfdir!$sysconfdir$ac_delim sharedstatedir!$sharedstatedir$ac_delim localstatedir!$localstatedir$ac_delim includedir!$includedir$ac_delim oldincludedir!$oldincludedir$ac_delim docdir!$docdir$ac_delim infodir!$infodir$ac_delim htmldir!$htmldir$ac_delim dvidir!$dvidir$ac_delim pdfdir!$pdfdir$ac_delim psdir!$psdir$ac_delim libdir!$libdir$ac_delim localedir!$localedir$ac_delim mandir!$mandir$ac_delim DEFS!$DEFS$ac_delim ECHO_C!$ECHO_C$ac_delim ECHO_N!$ECHO_N$ac_delim ECHO_T!$ECHO_T$ac_delim LIBS!$LIBS$ac_delim build_alias!$build_alias$ac_delim host_alias!$host_alias$ac_delim target_alias!$target_alias$ac_delim INSTALL_PROGRAM!$INSTALL_PROGRAM$ac_delim INSTALL_SCRIPT!$INSTALL_SCRIPT$ac_delim INSTALL_DATA!$INSTALL_DATA$ac_delim CC!$CC$ac_delim CFLAGS!$CFLAGS$ac_delim LDFLAGS!$LDFLAGS$ac_delim CPPFLAGS!$CPPFLAGS$ac_delim ac_ct_CC!$ac_ct_CC$ac_delim EXEEXT!$EXEEXT$ac_delim OBJEXT!$OBJEXT$ac_delim CPP!$CPP$ac_delim GREP!$GREP$ac_delim EGREP!$EGREP$ac_delim PKG_CONFIG!$PKG_CONFIG$ac_delim LIBOBJS!$LIBOBJS$ac_delim LTLIBOBJS!$LTLIBOBJS$ac_delim _ACEOF if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 53; then break elif $ac_last_try; then { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5 echo "$as_me: error: could not make $CONFIG_STATUS" >&2;} { (exit 1); exit 1; }; } else ac_delim="$ac_delim!$ac_delim _$ac_delim!! " fi done ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed` if test -n "$ac_eof"; then ac_eof=`echo "$ac_eof" | sort -nru | sed 1q` ac_eof=`expr $ac_eof + 1` fi cat >>$CONFIG_STATUS <<_ACEOF cat >"\$tmp/subs-1.sed" <<\CEOF$ac_eof /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end _ACEOF sed ' s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g s/^/s,@/; s/!/@,|#_!!_#|/ :n t n s/'"$ac_delim"'$/,g/; t s/$/\\/; p N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n ' >>$CONFIG_STATUS >$CONFIG_STATUS <<_ACEOF :end s/|#_!!_#|//g CEOF$ac_eof _ACEOF # VPATH may cause trouble with some makes, so we remove $(srcdir), # ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and # trailing colons and then remove the whole line if VPATH becomes empty # (actually we leave an empty line to preserve line numbers). if test "x$srcdir" = x.; then ac_vpsub='/^[ ]*VPATH[ ]*=/{ s/:*\$(srcdir):*/:/ s/:*\${srcdir}:*/:/ s/:*@srcdir@:*/:/ s/^\([^=]*=[ ]*\):*/\1/ s/:*$// s/^[^=]*=[ ]*$// }' fi cat >>$CONFIG_STATUS <<\_ACEOF fi # test -n "$CONFIG_FILES" for ac_tag in :F $CONFIG_FILES :H $CONFIG_HEADERS do case $ac_tag in :[FHLC]) ac_mode=$ac_tag; continue;; esac case $ac_mode$ac_tag in :[FHL]*:*);; :L* | :C*:*) { { echo "$as_me:$LINENO: error: Invalid tag $ac_tag." >&5 echo "$as_me: error: Invalid tag $ac_tag." >&2;} { (exit 1); exit 1; }; };; :[FH]-) ac_tag=-:-;; :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; esac ac_save_IFS=$IFS IFS=: set x $ac_tag IFS=$ac_save_IFS shift ac_file=$1 shift case $ac_mode in :L) ac_source=$1;; :[FH]) ac_file_inputs= for ac_f do case $ac_f in -) ac_f="$tmp/stdin";; *) # Look for the file first in the build tree, then in the source tree # (if the path is not absolute). The absolute path cannot be DOS-style, # because $ac_f cannot contain `:'. test -f "$ac_f" || case $ac_f in [\\/$]*) false;; *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; esac || { { echo "$as_me:$LINENO: error: cannot find input file: $ac_f" >&5 echo "$as_me: error: cannot find input file: $ac_f" >&2;} { (exit 1); exit 1; }; };; esac ac_file_inputs="$ac_file_inputs $ac_f" done # Let's still pretend it is `configure' which instantiates (i.e., don't # use $as_me), people would be surprised to read: # /* config.h. Generated by config.status. */ configure_input="Generated from "`IFS=: echo $* | sed 's|^[^:]*/||;s|:[^:]*/|, |g'`" by configure." if test x"$ac_file" != x-; then configure_input="$ac_file. $configure_input" { echo "$as_me:$LINENO: creating $ac_file" >&5 echo "$as_me: creating $ac_file" >&6;} fi case $ac_tag in *:-:* | *:-) cat >"$tmp/stdin";; esac ;; esac ac_dir=`$as_dirname -- "$ac_file" || $as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$ac_file" : 'X\(//\)[^/]' \| \ X"$ac_file" : 'X\(//\)$' \| \ X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || echo X"$ac_file" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` { as_dir="$ac_dir" case $as_dir in #( -*) as_dir=./$as_dir;; esac test -d "$as_dir" || { $as_mkdir_p && mkdir -p "$as_dir"; } || { as_dirs= while :; do case $as_dir in #( *\'*) as_qdir=`echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #( *) as_qdir=$as_dir;; esac as_dirs="'$as_qdir' $as_dirs" as_dir=`$as_dirname -- "$as_dir" || $as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ X"$as_dir" : 'X\(//\)[^/]' \| \ X"$as_dir" : 'X\(//\)$' \| \ X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || echo X"$as_dir" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q } /^X\(\/\/\)[^/].*/{ s//\1/ q } /^X\(\/\/\)$/{ s//\1/ q } /^X\(\/\).*/{ s//\1/ q } s/.*/./; q'` test -d "$as_dir" && break done test -z "$as_dirs" || eval "mkdir $as_dirs" } || test -d "$as_dir" || { { echo "$as_me:$LINENO: error: cannot create directory $as_dir" >&5 echo "$as_me: error: cannot create directory $as_dir" >&2;} { (exit 1); exit 1; }; }; } ac_builddir=. case "$ac_dir" in .) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_dir_suffix=/`echo "$ac_dir" | sed 's,^\.[\\/],,'` # A ".." for each directory in $ac_dir_suffix. ac_top_builddir_sub=`echo "$ac_dir_suffix" | sed 's,/[^\\/]*,/..,g;s,/,,'` case $ac_top_builddir_sub in "") ac_top_builddir_sub=. ac_top_build_prefix= ;; *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; esac ;; esac ac_abs_top_builddir=$ac_pwd ac_abs_builddir=$ac_pwd$ac_dir_suffix # for backward compatibility: ac_top_builddir=$ac_top_build_prefix case $srcdir in .) # We are building in place. ac_srcdir=. ac_top_srcdir=$ac_top_builddir_sub ac_abs_top_srcdir=$ac_pwd ;; [\\/]* | ?:[\\/]* ) # Absolute name. ac_srcdir=$srcdir$ac_dir_suffix; ac_top_srcdir=$srcdir ac_abs_top_srcdir=$srcdir ;; *) # Relative name. ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_build_prefix$srcdir ac_abs_top_srcdir=$ac_pwd/$srcdir ;; esac ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix case $ac_mode in :F) # # CONFIG_FILE # case $INSTALL in [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; esac _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF # If the template does not know about datarootdir, expand it. # FIXME: This hack should be removed a few years after 2.60. ac_datarootdir_hack=; ac_datarootdir_seen= case `sed -n '/datarootdir/ { p q } /@datadir@/p /@docdir@/p /@infodir@/p /@localedir@/p /@mandir@/p ' $ac_file_inputs` in *datarootdir*) ac_datarootdir_seen=yes;; *@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) { echo "$as_me:$LINENO: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} _ACEOF cat >>$CONFIG_STATUS <<_ACEOF ac_datarootdir_hack=' s&@datadir@&$datadir&g s&@docdir@&$docdir&g s&@infodir@&$infodir&g s&@localedir@&$localedir&g s&@mandir@&$mandir&g s&\\\${datarootdir}&$datarootdir&g' ;; esac _ACEOF # Neutralize VPATH when `$srcdir' = `.'. # Shell code in configure.ac might set extrasub. # FIXME: do we really want to maintain this feature? cat >>$CONFIG_STATUS <<_ACEOF sed "$ac_vpsub $extrasub _ACEOF cat >>$CONFIG_STATUS <<\_ACEOF :t /@[a-zA-Z_][a-zA-Z_0-9]*@/!b s&@configure_input@&$configure_input&;t t s&@top_builddir@&$ac_top_builddir_sub&;t t s&@srcdir@&$ac_srcdir&;t t s&@abs_srcdir@&$ac_abs_srcdir&;t t s&@top_srcdir@&$ac_top_srcdir&;t t s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t s&@builddir@&$ac_builddir&;t t s&@abs_builddir@&$ac_abs_builddir&;t t s&@abs_top_builddir@&$ac_abs_top_builddir&;t t s&@INSTALL@&$ac_INSTALL&;t t $ac_datarootdir_hack " $ac_file_inputs | sed -f "$tmp/subs-1.sed" >$tmp/out test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } && { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } && { echo "$as_me:$LINENO: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&5 echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' which seems to be undefined. Please make sure it is defined." >&2;} rm -f "$tmp/stdin" case $ac_file in -) cat "$tmp/out"; rm -f "$tmp/out";; *) rm -f "$ac_file"; mv "$tmp/out" $ac_file;; esac ;; :H) # # CONFIG_HEADER # _ACEOF # Transform confdefs.h into a sed script `conftest.defines', that # substitutes the proper values into config.h.in to produce config.h. rm -f conftest.defines conftest.tail # First, append a space to every undef/define line, to ease matching. echo 's/$/ /' >conftest.defines # Then, protect against being on the right side of a sed subst, or in # an unquoted here document, in config.status. If some macros were # called several times there might be several #defines for the same # symbol, which is useless. But do not sort them, since the last # AC_DEFINE must be honored. ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* # These sed commands are passed to sed as "A NAME B PARAMS C VALUE D", where # NAME is the cpp macro being defined, VALUE is the value it is being given. # PARAMS is the parameter list in the macro definition--in most cases, it's # just an empty string. ac_dA='s,^\\([ #]*\\)[^ ]*\\([ ]*' ac_dB='\\)[ (].*,\\1define\\2' ac_dC=' ' ac_dD=' ,' uniq confdefs.h | sed -n ' t rset :rset s/^[ ]*#[ ]*define[ ][ ]*// t ok d :ok s/[\\&,]/\\&/g s/^\('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/ '"$ac_dA"'\1'"$ac_dB"'\2'"${ac_dC}"'\3'"$ac_dD"'/p s/^\('"$ac_word_re"'\)[ ]*\(.*\)/'"$ac_dA"'\1'"$ac_dB$ac_dC"'\2'"$ac_dD"'/p ' >>conftest.defines # Remove the space that was appended to ease matching. # Then replace #undef with comments. This is necessary, for # example, in the case of _POSIX_SOURCE, which is predefined and required # on some systems where configure will not decide to define it. # (The regexp can be short, since the line contains either #define or #undef.) echo 's/ $// s,^[ #]*u.*,/* & */,' >>conftest.defines # Break up conftest.defines: ac_max_sed_lines=50 # First sed command is: sed -f defines.sed $ac_file_inputs >"$tmp/out1" # Second one is: sed -f defines.sed "$tmp/out1" >"$tmp/out2" # Third one will be: sed -f defines.sed "$tmp/out2" >"$tmp/out1" # et cetera. ac_in='$ac_file_inputs' ac_out='"$tmp/out1"' ac_nxt='"$tmp/out2"' while : do # Write a here document: cat >>$CONFIG_STATUS <<_ACEOF # First, check the format of the line: cat >"\$tmp/defines.sed" <<\\CEOF /^[ ]*#[ ]*undef[ ][ ]*$ac_word_re[ ]*\$/b def /^[ ]*#[ ]*define[ ][ ]*$ac_word_re[( ]/b def b :def _ACEOF sed ${ac_max_sed_lines}q conftest.defines >>$CONFIG_STATUS echo 'CEOF sed -f "$tmp/defines.sed"' "$ac_in >$ac_out" >>$CONFIG_STATUS ac_in=$ac_out; ac_out=$ac_nxt; ac_nxt=$ac_in sed 1,${ac_max_sed_lines}d conftest.defines >conftest.tail grep . conftest.tail >/dev/null || break rm -f conftest.defines mv conftest.tail conftest.defines done rm -f conftest.defines conftest.tail echo "ac_result=$ac_in" >>$CONFIG_STATUS cat >>$CONFIG_STATUS <<\_ACEOF if test x"$ac_file" != x-; then echo "/* $configure_input */" >"$tmp/config.h" cat "$ac_result" >>"$tmp/config.h" if diff $ac_file "$tmp/config.h" >/dev/null 2>&1; then { echo "$as_me:$LINENO: $ac_file is unchanged" >&5 echo "$as_me: $ac_file is unchanged" >&6;} else rm -f $ac_file mv "$tmp/config.h" $ac_file fi else echo "/* $configure_input */" cat "$ac_result" fi rm -f "$tmp/out12" ;; esac done # for ac_tag { (exit 0); exit 0; } _ACEOF chmod +x $CONFIG_STATUS ac_clean_files=$ac_clean_files_save # configure is writing to config.log, and then calls config.status. # config.status does its own redirection, appending to config.log. # Unfortunately, on DOS this fails, as config.log is still kept open # by configure, so config.status won't be able to write to it; its # output is simply discarded. So we exec the FD to /dev/null, # effectively closing config.log, so it can be properly (re)opened and # appended to by config.status. When coming back to configure, we # need to make the FD available again. if test "$no_create" != yes; then ac_cs_success=: ac_config_status_args= test "$silent" = yes && ac_config_status_args="$ac_config_status_args --quiet" exec 5>/dev/null $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false exec 5>>config.log # Use ||, not &&, to avoid exiting from the if with $? = 1, which # would make configure fail if this is the last instruction. $ac_cs_success || { (exit 1); exit 1; } fi ldapvi-1.7/NEWS0000644000175000017500000000737710617054666012330 0ustar daviddavid1.7 2007-05-05 - Fixed buffer overrun in home_filename(), thanks to Thomas Friebel. 1.6 2006-11-04 New features: - SASL support (thanks to Perry Nguyen) * new command line arguments -I, -Q, -O, -R, -Y, -X, -U, as well as --bind and --bind-dialog * new keys 'B' and '*' * incompatible change: renamed --root to --read and dropped its short name -R - new value encodings md5, smd5, sha1, ssha1 (thanks to Michael Hanselmann) * incompatible change: value encoding md5 renamed to cryptmd5 * new configure option --with-libcrypto - extended ldapvi syntax with change records * new key 'V' - new command line arguments --in, --out, --delete, --rename - LDIF support in the editor * new command line arguments --ldif, --ldapvi, --ldapsearch, --ldapmodify, --ldapdelete, --ldapmoddn, --add * incompatible change: old command line argument --add renamed to --empty - UTF-8 support; new command line option --encoding - use libreadline to read the user name - support for configuration files ~/.ldapvirc or /etc/ldapvi.conf in ldapvi syntax, taking precedence over .ldaprc and /etc/ldap.conf if present * new command line argument --profile * new command line argument --ldap-conf - show optional attributes as comments * new command line argument -m (--may) * new key '+' - new key 'f': forget deletions - continuous mode, similar to ldapmodify -c * new key 'Y' * new command line argument -c (--continue) * incompatible change: -c does not mean --config anymore - incompatible change: new command line option --noninteractive * -! means --noninteractive now, not --noquestions - C-l clears the screen - pipe --help to a pager if used on a terminal Bugfixes: - always replace entire attributes (fixing a bug reported by Javier Barroso) - fixed LDIF export to always Base64-encode non-ASCII values - oops: escape backslashes properly - schema reading (--class) works with Fedora DS now Build change: - preprocessor sellout: automagically #ifdefed support for libldap 2.1 Last not least: - new documentation in manual/manual.xml 1.5 2005-12-11 - fixed argument parsing (thanks to Andrea Barisani for the report) 1.4 2005-11-15 r43 - updated for libldap 2.2 - cygwin works - fixed bogus modify operation when moving an entry without changing its rdn - new command line option --tls - new command line option -R - workaround for Microsoft ROOT DSE oddity: need * instead of + 1.3 2005-11-13 r33 * last release to require libldap 2.1 - in ldap_delete, treat notAllowedOnNonLeaf as non-fatal, allowing subtrees to be deleted in incorrect order - check for empty DNs later, so that search results including the ROOT DSE do not lead to a parse error anymore - for syntax errors, try to open the editor near the error position. (This assumes support for the +N argument vi and emacs understand.) - new command line argument --config: print basic LDAP library parameters to standard output for easy .ldaprc setup - new command line argument --discover: as an alternative to --base, query the ROOT DSE for all namingContexts and repeat searching in all contexts automatically - new command line argument --class: specify objectclasses at the command line that are looked up and inserted as a template 1.2 2004-07-07 r18 (patch-17) - fixed segfault: allow deletions to be skipped (thanks to Gerfried Fuchs for the bug report) - MD5 hashes are stored in crypt()-format, so prepend {CRYPT}, not {MD5} 1.1 2004-01-27 r9 (patch-8) - fixed compare() bugs involving fastcmp() (thanks to Bernardo Innocenti for the bug report) - fixed deleteoldrdn in LDIF output - new option --diff - tests, some comments 1.0 2004-01-01 r1 (base-0) initial release ldapvi-1.7/INSTALL0000644000175000017500000000121110617054666012637 0ustar daviddavidldapvi -------- http://www.lichteblau.com/ldapvi/ David Lichteblau ldapvi@lists.askja.de (https://lists.askja.de/listinfo/ldapvi) Installation: $ ./configure && gmake # gmake install Prerequisites: - Recent OpenLDAP client library (>= 2.2 preferred, 2.1 tolerated) - glib-2.0 - popt - curses - GNU make - OpenSSL or GnuTLS, choose using ./configure --with-libcrypto - GNU readline - Build dependency: SASL support is compiled into ldapvi if and only if Cyrus SASL headers can be found. (Whether libldap was compiled with SASL support is only relevant at run time.) Tested on: Linux, Solaris, FreeBSD, IRIX, Cygwin ldapvi-1.7/install-sh0000644000175000017500000001440610617054666013621 0ustar daviddavid#!/bin/sh # # install - install a program, script, or datafile # # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else true fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=mkdir fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then true else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else true fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else true fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else true fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else true fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 ldapvi-1.7/version.h0000644000175000017500000000002610617054666013447 0ustar daviddavid#define VERSION "1.7" ldapvi-1.7/port.c0000644000175000017500000000766310617054666012757 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "config.h" #if defined(HAVE_OPENSSL) #include #include #elif defined(HAVE_GNUTLS) #include #include #else #error oops #endif #ifndef HAVE_RAND_PSEUDO_BYTES #define RAND_pseudo_bytes RAND_bytes #endif #ifndef HAVE_MKDTEMP char * mkdtemp(char *template) { int l = strlen(template); int i = l - 6; int fd; int n; if (i < 0) { errno = EINVAL; return 0; } fd = open("/dev/random", O_RDONLY); if (fd == -1) { fputs("Do you have /dev/random?\n", stderr); return 0; } while (i < l) { if ( (n = read(fd, template + i, l - i)) == -1) { close(fd); return 0; } while (n--) { unsigned char c = template[i]; c &= 63; if (c < 10) c += '0'; else if (c < 38) c += '?' - 10; else c += 'a' - 38; template[i] = c; i++; } } close(fd); if (mkdir(template, 0700) == -1) return 0; return template; } #endif #ifndef HAVE_ON_EXIT static void (*onexitfunction)(int , void *) = 0; static void *onexitarg; static void atexitfunction(void) { onexitfunction(-1, onexitarg); } int on_exit(void (*function)(int, void *), void *arg) { if (onexitfunction) yourfault("on_exit called twice"); onexitfunction = function; onexitarg = arg; return atexit(atexitfunction); } #endif void g_string_append_base64( GString *string, unsigned char const *src, size_t srclength); int g_string_append_sha(GString *string, char *key) { #ifdef HAVE_SHA1 unsigned char tmp[SHA_DIGEST_LENGTH]; SHA1((unsigned char *) key, strlen(key), tmp); g_string_append_base64(string, tmp, sizeof(tmp)); return 1; #else puts("Sorry, SHA1 support not linked into ldapvi."); return 0; #endif } int g_string_append_ssha(GString *string, char *key) { #ifdef HAVE_SHA1 char rand[4]; unsigned char tmp[SHA_DIGEST_LENGTH + sizeof(rand)]; SHA_CTX SHA1context; RAND_pseudo_bytes(rand, sizeof(rand)); SHA1_Init(&SHA1context); SHA1_Update(&SHA1context, key, strlen(key)); SHA1_Update(&SHA1context, rand, sizeof(rand)); SHA1_Final(tmp, &SHA1context); memcpy(tmp + SHA_DIGEST_LENGTH, rand, sizeof(rand)); g_string_append_base64(string, tmp, sizeof(tmp)); return 1; #else puts("Sorry, SHA1 support not linked into ldapvi."); return 0; #endif } int g_string_append_md5(GString *string, char *key) { unsigned char tmp[MD5_DIGEST_LENGTH]; MD5((unsigned char *) key, strlen(key), tmp); g_string_append_base64(string, tmp, sizeof(tmp)); return 1; } int g_string_append_smd5(GString *string, char *key) { unsigned char rand[4]; unsigned char tmp[MD5_DIGEST_LENGTH + sizeof(rand)]; MD5_CTX MD5context; RAND_pseudo_bytes(rand, sizeof(rand)); MD5_Init(&MD5context); MD5_Update(&MD5context, key, strlen(key)); MD5_Update(&MD5context, rand, sizeof(rand)); MD5_Final(tmp, &MD5context); memcpy(tmp + MD5_DIGEST_LENGTH, rand, sizeof(rand)); g_string_append_base64(string, tmp, sizeof(tmp)); return 1; } ldapvi-1.7/diff.c0000644000175000017500000004366410617054666012704 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "common.h" #include "config.h" typedef void (*note_function)(void *, void *, void *); static void compare_ptr_arrays(GPtrArray *a, GPtrArray *b, int (*cmp)(const void *, const void *), note_function note, void *x) { int i = 0; int j = 0; qsort(a->pdata, a->len, sizeof(void *), cmp); qsort(b->pdata, b->len, sizeof(void *), cmp); while (i < a->len && j < b->len) { void *ax = g_ptr_array_index(a, i); void *bx = g_ptr_array_index(b, j); int n = cmp(&ax, &bx); if (n < 0) { note(ax, 0, x); i++; } else if (n == 0) { note(ax, bx, x); i++; j++; } else { note(0, bx, x); j++; } } if (i == a->len) for (; j < b->len; j++) note(0, g_ptr_array_index(b, j), x); else for (; i < a->len; i++) note(g_ptr_array_index(a, i), 0, x); } static void note_values(GArray *a, GArray *b, int *changed) { if (!(a && b)) *changed = 1; } static void compare_attributes(tattribute *clean, tattribute *new, GPtrArray *mods) { int changed = 0; compare_ptr_arrays(attribute_values(clean), attribute_values(new), carray_ptr_cmp, (note_function) note_values, &changed); if (changed) { LDAPMod *m = attribute2mods(new); m->mod_op |= LDAP_MOD_REPLACE; g_ptr_array_add(mods, m); } } static void note_attributes(tattribute *a1, tattribute *a2, GPtrArray *mods) { tattribute *a; GPtrArray *values; LDAPMod *m; int i; if (a1 && a2) { compare_attributes(a1, a2, mods); return; } m = xalloc(sizeof(LDAPMod)); if (a1) { a = a1; m->mod_op = LDAP_MOD_DELETE; } else { a = a2; m->mod_op = LDAP_MOD_ADD; } values = attribute_values(a); m->mod_op |= LDAP_MOD_BVALUES; m->mod_type = xdup(attribute_ad(a)); m->mod_bvalues = xalloc((1 + values->len) * sizeof(struct berval *)); for (i = 0; i < values->len; i++) m->mod_bvalues[i] = string2berval(g_ptr_array_index(values, i)); m->mod_bvalues[values->len] = 0; g_ptr_array_add(mods, m); } static LDAPMod ** compare_entries(tentry *eclean, tentry *enew) { GPtrArray *mods = g_ptr_array_new(); compare_ptr_arrays(entry_attributes(eclean), entry_attributes(enew), named_array_ptr_cmp, (note_function) note_attributes, mods); if (!mods->len) { g_ptr_array_free(mods, 1); return 0; } g_ptr_array_add(mods, 0); { LDAPMod **result = (LDAPMod **) mods->pdata; g_ptr_array_free(mods, 0); return result; } } void long_array_invert(GArray *array, int i) { g_array_index(array, long, i) = -2 - g_array_index(array, long, i); } /* * Read N bytes from stream S at position P and stream T at position Q * and compare them. Return 0 if the segments are equal, else return 1. * If one the files terminates early, return 1. In any case, reset the * streams to the position they had when this function was invoked. */ int fastcmp(FILE *s, FILE *t, long p, long q, long n) { char *b = xalloc(n); /* XXX */ char *c = xalloc(n); /* XXX */ int rc = -1; long p_save; long q_save; if ( (p_save = ftell(s)) == -1) syserr(); if ( (q_save = ftell(t)) == -1) syserr(); if (fseek(s, p, SEEK_SET) == -1) syserr(); if (fseek(t, q, SEEK_SET) == -1) syserr(); if (fread(b, 1, n, s) != n) { if (ferror(s)) syserr(); goto cleanup; } if (fread(c, 1, n, t) != n) { if (ferror(t)) syserr(); goto cleanup; } rc = memcmp(b, c, n) != 0; cleanup: if (fseek(s, p_save, SEEK_SET) == -1) syserr(); if (fseek(t, q_save, SEEK_SET) == -1) syserr(); free(b); free(c); return rc; } /* * Do something with ENTRY and attribute AD, value DATA. * * With mode FROB_RDN_CHECK, determine whether the attribute value is present. * With mode FROB_RDN_CHECK_NONE, determine whether it isn't. * (Return 0 if so, -1 if not.) * * With mode FROB_RDN_REMOVE, remove it * With mode FROB_RDN_ADD, add it (unless already present) * (Return 0.) */ int frob_ava(tentry *entry, int mode, char *ad, char *data, int n) { tattribute *a; switch (mode) { case FROB_RDN_CHECK: a = entry_find_attribute(entry, ad, 0); if (!a) return -1; if (attribute_find_value(a, data, n) == -1) return -1; break; case FROB_RDN_CHECK_NONE: a = entry_find_attribute(entry, ad, 0); if (!a) return 0; if (attribute_find_value(a, data, n) == -1) return 0; return -1; break; case FROB_RDN_REMOVE: a = entry_find_attribute(entry, ad, 0); attribute_remove_value(a, data, n); break; case FROB_RDN_ADD: a = entry_find_attribute(entry, ad, 1); if (attribute_find_value(a, data, n) == -1) attribute_append_value(a, data, n); break; } return 0; } #if defined(LIBLDAP21) #warning compiling for libldap <= 2.1, running with >= 2.2 will result in segfault #define safe_str2dn ldap_str2dn #elif defined(LIBLDAP22) /* * the following is exactly equivalent to ldap_str2dn in libldap >= 2.2, * but will fail linking on 2.1. This way we avoid calling the old 2.1 * version of ldap_str2dn (leading to a segfault when accessing the result). */ static void safe_str2dn(char *str, LDAPDN *out, int flags) { struct berval bv; bv.bv_val = str; bv.bv_len = strlen(str); ldap_bv2dn_x(&bv, out, flags); } #else #error oops #endif /* * Call frob_ava for every ava in DN's (first) RDN. * DN must be valid. * * Return -1 if frob_ava ever does so, 0 else. */ int frob_rdn(tentry *entry, char *dn, int mode) { #ifdef LIBLDAP21 LDAPDN *olddn; #else LDAPDN olddn; #endif LDAPRDN rdn; int i; int rc = 0; safe_str2dn(dn, &olddn, LDAP_DN_FORMAT_LDAPV3); #ifdef LIBLDAP21 rdn = (**olddn)[0]; #else rdn = olddn[0]; #endif for (i = 0; rdn[i]; i++) { LDAPAVA *ava = rdn[i]; char *ad = ava->la_attr.bv_val; /* XXX */ struct berval *bv = &ava->la_value; if (frob_ava(entry, mode, ad, bv->bv_val, bv->bv_len) == -1) { rc = -1; goto cleanup; } } cleanup: ldap_dnfree(olddn); return rc; } /* * Check whether all of the following conditions are true and return a boolean. * - none of the DNs is empty, so RDN-frobbing code can rely on senseful DNs * - the attribute values in clean's RDN are contained in clean. * - the attribute values in data's RDN are contained in data. * - the attribute values in clean's RDN are either all contained in data * or that none of them are. */ int validate_rename(tentry *clean, tentry *data, int *deleteoldrdn) { if (!*entry_dn(clean)) { puts("Error: Cannot rename ROOT_DSE."); return -1; } if (!*entry_dn(data)) { puts("Error: Cannot replace ROOT_DSE."); return -1; } if (frob_rdn(clean, entry_dn(clean), FROB_RDN_CHECK) == -1) { puts("Error: Old RDN not found in entry."); return -1; } if (frob_rdn(data, entry_dn(data), FROB_RDN_CHECK) == -1) { puts("Error: New RDN not found in entry."); return -1; } if (frob_rdn(data, entry_dn(clean), FROB_RDN_CHECK) != -1) *deleteoldrdn = 0; else if (frob_rdn(data, entry_dn(clean), FROB_RDN_CHECK_NONE) != -1) *deleteoldrdn = 1; else { puts("Error: Incomplete RDN change."); return -1; } return 0; } static void rename_entry(tentry *entry, char *newdn, int deleteoldrdn) { if (deleteoldrdn) frob_rdn(entry, entry_dn(entry), FROB_RDN_REMOVE); frob_rdn(entry, newdn, FROB_RDN_ADD); free(entry_dn(entry)); entry_dn(entry) = xdup(newdn); } static void update_clean_copy( GArray *offsets, char *key, FILE *s, tentry *cleanentry, tparser *p) { long pos = fseek(s, 0, SEEK_END); if (pos == -1) syserr(); g_array_index(offsets, long, atoi(key)) = ftell(s); p->print(s, cleanentry, key, 0); } /* * read a changerecord of type `key' from `data', handle it, and return * 0 on success * -1 on syntax error * -2 on handler error */ int process_immediate(tparser *p, thandler *handler, void *userdata, FILE *data, long datapos, char *key) { if (!strcmp(key, "add")) { tentry *entry; LDAPMod **mods; if (p->entry(data, datapos, 0, &entry, 0) == -1) return -1; mods = entry2mods(entry); if (handler->add(-1, entry_dn(entry), mods, userdata) == -1) { ldap_mods_free(mods, 1); entry_free(entry); return -2; } ldap_mods_free(mods, 1); entry_free(entry); entry = 0; } else if (!strcmp(key, "replace")) { tentry *entry; LDAPMod **mods; int i; if (p->entry(data, datapos, 0, &entry, 0) == -1) return -1; mods = entry2mods(entry); for (i = 0; mods[i]; i++) { LDAPMod *mod = mods[i]; mod->mod_op &= LDAP_MOD_BVALUES; mod->mod_op |= LDAP_MOD_REPLACE; } if (handler->change(-1, entry_dn(entry), entry_dn(entry), mods, userdata) == -1) { ldap_mods_free(mods, 1); entry_free(entry); return -2; } ldap_mods_free(mods, 1); entry_free(entry); entry = 0; } else if (!strcmp(key, "rename")) { char *dn1; char *dn2; int deleteoldrdn; int rc; if (p->rename(data, datapos, &dn1, &dn2, &deleteoldrdn) ==-1) return -1; rc = handler->rename0(-1, dn1, dn2, deleteoldrdn, userdata); free(dn1); free(dn2); if (rc) return -2; } else if (!strcmp(key, "delete")) { char *dn; int rc; if (p->delete(data, datapos, &dn) == -1) return -1; rc = handler->delete(-1, dn, userdata); free(dn); if (rc) return -2; } else if (!strcmp(key, "modify")) { char *dn; LDAPMod **mods; if (p->modify(data, datapos, &dn, &mods) ==-1) return -1; if (handler->change(-1, dn, dn, mods, userdata) == -1) { free(dn); ldap_mods_free(mods, 1); return -2; } } else { fprintf(stderr, "Error: Invalid key: `%s'.\n", key); return -1; } return 0; } /* * read the next entry from `data', its clean copy from `clean', process * them as described for compare_streams, and return * 0 on success * -1 on syntax error * -2 on handler error */ static int process_next_entry( tparser *p, thandler *handler, void *userdata, GArray *offsets, FILE *clean, FILE *data, char *key, long datapos) { tentry *entry = 0; tentry *cleanentry = 0; int rc = -1; LDAPMod **mods; long pos; char *ptr; int n; int rename, deleteoldrdn; /* find clean copy */ n = strtol(key, &ptr, 10); if (*ptr) return process_immediate( p, handler, userdata, data, datapos, key); if (n < 0 || n >= offsets->len) { fprintf(stderr, "Error: Invalid key: `%s'.\n", key); goto cleanup; } pos = g_array_index(offsets, long, n); if (pos < 0) { fprintf(stderr, "Error: Duplicate entry %d.\n", n); goto cleanup; } /* find precise position */ if (p->entry(clean, pos, 0, 0, &pos) == -1) abort(); /* fast comparison */ if (n + 1 < offsets->len) { long next = g_array_index(offsets, long, n + 1); if (next >= 0 && !fastcmp(clean, data, pos, datapos, next-pos+1)) { datapos += next - pos; long_array_invert(offsets, n); if (fseek(data, datapos, SEEK_SET) == -1) syserr(); return 0; } } /* if we get here, a quick scan found a difference in the * files, so we need to read the entries and compare them */ if (p->entry(data, datapos, 0, &entry, 0) == -1) goto cleanup; if (p->entry(clean, pos, 0, &cleanentry, 0) == -1) abort(); /* compare and update */ if ( (rename = strcmp(entry_dn(cleanentry), entry_dn(entry)))){ if (validate_rename(cleanentry, entry, &deleteoldrdn)){ rc = -1; goto cleanup; } if (handler->rename(n, entry_dn(cleanentry), entry, userdata) == -1) { rc = -2; goto cleanup; } rename_entry(cleanentry, entry_dn(entry), deleteoldrdn); } if ( (mods = compare_entries(cleanentry, entry))) { if (handler->change(n, entry_dn(cleanentry), entry_dn(entry), mods, userdata) == -1) { if (mods) ldap_mods_free(mods, 1); if (rename) update_clean_copy( offsets, key, clean, cleanentry, p); rc = -2; goto cleanup; } ldap_mods_free(mods, 1); } /* mark as seen */ long_array_invert(offsets, n); entry_free(entry); entry = 0; entry_free(cleanentry); cleanentry = 0; return 0; cleanup: if (entry) { if (*entry_dn(entry)) fprintf(stderr, "Error at: %s\n", entry_dn(entry)); entry_free(entry); } if (cleanentry) entry_free(cleanentry); return rc; } static int nonleaf_action(tentry *entry, GArray *offsets, int n) { int i; printf("Error: Cannot delete non-leaf entry: %s\n", entry_dn(entry)); for (i = n + 1; i < offsets->len; i++) { if (g_array_index(offsets, long, n) >= 0) goto more_deletions; } /* no more deletions anyway, so no need to ignore this one */ return 0; more_deletions: switch (choose("Continue?", "yn!Q?", "(Type '?' for help.)")) { case 'y': return 1; case '!': return 2; case 'n': return 0; case 'Q': exit(0); case '?': puts("Commands:\n" " y -- continue deleting other entries\n" " ! -- continue and assume 'y' until done\n" " n -- abort deletions\n" " Q -- discard changes and quit\n" " ? -- this help"); goto more_deletions; } /* notreached */ return 0; } /* * process deletions as described for compare_streams. * return 0 on success, -2 else. */ static int process_deletions(tparser *p, thandler *handler, void *userdata, GArray *offsets, FILE *clean) { tentry *cleanentry = 0; long pos; int n; int ignore_nonleaf = 0; int n_leaf; int n_nonleaf; do { if (ignore_nonleaf) printf("Retrying %d failed deletion%s...\n", n_nonleaf, n_nonleaf == 1 ? "" : "s"); n_leaf = 0; n_nonleaf = 0; for (n = 0; n < offsets->len; n++) { if ( (pos = g_array_index(offsets, long, n)) < 0) continue; if (p->entry(clean, pos, 0, &cleanentry, 0) == -1) abort(); switch (handler->delete( n, entry_dn(cleanentry), userdata)) { case -1: entry_free(cleanentry); return -2; case -2: if (ignore_nonleaf) { printf("Skipping non-leaf entry: %s\n", entry_dn(cleanentry)); n_nonleaf++; break; } switch (nonleaf_action(cleanentry,offsets,n)) { case 0: entry_free(cleanentry); return -2; case 2: ignore_nonleaf = 1; /* fall through */ case 1: n_nonleaf++; } break; default: n_leaf++; long_array_invert(offsets, n); } entry_free(cleanentry); } } while (ignore_nonleaf && n_nonleaf > 0 && n_leaf > 0); return n_nonleaf ? -2 : 0; } /* * Die compare_streams-Schleife ist das Herz von ldapvi. * * Read two ldapvi data files in streams CLEAN and DATA and compare them. * * File CLEAN must contain numbered entries with consecutive keys starting at * zero. For each of these entries, array offset must contain a position * in the file, such that the entry can be read by seeking to that position * and calling read_entry(). * * File DATA, a modified copy of CLEAN may contain entries in any order, * which must be numbered or labeled "add", "rename", or "modify". If a * key is a number, the corresponding entry in CLEAN must exist, it is * read and compared to the modified copy. * * For each change, call the appropriate handler method with arguments * described below. Handler methods must return 0 on success, or -1 on * failure. (As a special case, return value -2 on a deletion indicates * an attempt to delete a non-leaf entry, which is non-fatal.) * * For each new entry (labeled with "add"), call * handler->add(dn, mods, USERDATA) * where MODS is a LDAPMod structure for the new entry. * * For each entry present in CLEAN but not DATA, call * handler->delete(dn, USERDATA) * (This step can be repeated in the case of non-leaf entries.) * * For each entry present in both files, handler can be called two times. * If the distinguished names of the old and new entry disagree, call * handler->change(old_entry, new_entry, 0, USERDATA) * If there are additional changes to the attributes of the entry, call * handler->change(renamed_entry, new_entry, mods, USERDATA) * where RENAMED_ENTRY is a copy of the original entry, which accounts * for attribute modifications due to a possible RDN change (new RDN * component values have to be added, and old RDN values be removed), * and MODS describes the changes between RENAMED_ENTRY and NEW_ENTRY. * * Entries labeled "delete" are changerecords for which the handler is * called as described above. * * Entries labeled "rename" are changerecords with their own method, * called as: * handler->rename(olddn, newdn, deleteoldrdn, USERDATA) * * Return 0 on success, -1 on parse error, -2 on handler failure. * * If an error occured, *error_position is the offset in DATA after * which the erroneous entry can be found. */ int compare_streams(tparser *p, thandler *handler, void *userdata, GArray *offsets, FILE *clean, FILE *data, long *error_position, long *syntax_error_position) { char *key = 0; int n; int rc; for (;;) { long datapos; /* read updated entry */ if (key) { free(key); key = 0; } if (p->peek(data, -1, &key, &datapos) == -1) goto cleanup; *error_position = datapos; if (!key) break; /* and do something with it */ if ( (rc = process_next_entry( p, handler, userdata, offsets, clean, data, key, datapos))) goto cleanup; } if ( (*error_position = ftell(data)) == -1) syserr(); rc = process_deletions(p, handler, userdata, offsets, clean); cleanup: if (key) free(key); if (syntax_error_position) if ( (*syntax_error_position = ftell(data)) == -1) syserr(); /* on user error, return now and keep state for recovery */ if (rc == -2) return rc; /* else some cleanup: unmark offsets */ for (n = 0; n < offsets->len; n++) if (g_array_index(offsets, long, n) < 0) long_array_invert(offsets, n); return rc; } ldapvi-1.7/parse.c0000644000175000017500000004136210617054666013077 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * Copyright (c) 2003,2004,2005,2006 David Lichteblau * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #define _XOPEN_SOURCE #include #include "common.h" #define fast_g_string_append_c(gstring, c) \ do { \ if ((gstring)->len + 1 >= (gstring)->allocated_len) \ g_string_append_c((gstring), (c)); \ else { \ (gstring)->str[(gstring)->len++] = (c); \ (gstring)->str[(gstring)->len] = 0; \ } \ } while (0) static int read_lhs(FILE *s, GString *lhs) { int c; for (;;) { switch ( c = getc_unlocked(s)) { case ' ': if (ferror(s)) syserr(); return 0; case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; case '\n': fputs("Error: Unexpected EOL.\n", stderr); return -1; case 0: fputs("Error: Null byte not allowed.\n", stderr); return -1; default: fast_g_string_append_c(lhs, c); } } } static int read_backslashed(FILE *s, GString *data) { int c; for (;;) { switch ( c = getc_unlocked(s)) { case '\n': if (ferror(s)) syserr(); return 0; case EOF: goto error; case '\\': if ( (c = fgetc(s)) == EOF) goto error; /* fall through */ default: fast_g_string_append_c(data, c); } } error: fputs("Error: Unexpected EOF.\n", stderr); return -1; } static int read_ldif_attrval(FILE *s, GString *data) { int c; for (;;) switch ( c = getc_unlocked(s)) { case '\n': if ( (c = fgetc(s)) == ' ') /* folded line */ break; ungetc(c, s); if (ferror(s)) syserr(); return 0; case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; default: fast_g_string_append_c(data, c); } } static int read_from_file(GString *data, char *name) { int fd, n; if ( (fd = open(name, O_RDONLY)) == -1) { perror("open"); return -1; } data->len = 0; n = 1024; do { int olen = data->len; g_string_set_size(data, data->len + n); if ( (n = read(fd, data->str + olen, n)) == -1) syserr(); data->len = olen + n; } while (n > 0); if (close(fd) == -1) syserr(); return 0; } static int skip_comment(FILE *s) { int c; for (;;) switch ( c = fgetc(s)) { case EOF: fputs("Error: Unexpected EOF.\n", stderr); return -1; case '\n': if ( (c = fgetc(s)) == ' ') /* folded line */ break; ungetc(c, s); if (ferror(s)) syserr(); return 0; } } static char *saltbag = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890./"; static char * cryptdes(char *key) { unsigned char salt[2]; int fd = open("/dev/random", 2); if (fd == -1) { puts("Sorry, crypt not available: Cannot open /dev/random."); return 0; } if (read(fd, salt, 2) != 2) syserr(); close(fd); salt[0] = saltbag[salt[0] & 63]; salt[1] = saltbag[salt[1] & 63]; return crypt(key, (char *) salt); } static char * cryptmd5(char *key) { char *result; unsigned char salt[11]; int i; int fd = open("/dev/random", 2); if (fd == -1) { puts("Sorry, MD5 not available: Cannot open /dev/random."); return 0; } salt[0] = '$'; salt[1] = '1'; salt[2] = '$'; if (read(fd, salt + 3, 8) != 8) syserr(); close(fd); for (i = 3; i < 11; i++) salt[i] = saltbag[salt[i] & 63]; result = crypt(key, (char *) salt); if (!result || strlen(result) < 25) { puts("Sorry, MD5 not available: Are you using the glibc?"); return 0; } return result; } /* * Read a line in * name ' ' (':' encoding)? value '\n' * syntax, skipping comments. VALUE is parsed according to ENCODING. * Empty NAME is allowed. * * 0: ok * -1: fatal parse error * -2: end of file or empty line */ static int read_line1(FILE *s, GString *name, GString *value) { int c; char *encoding; g_string_truncate(name, 0); g_string_truncate(value, 0); /* skip comment lines */ do { c = fgetc(s); switch (c) { case EOF: if (ferror(s)) syserr(); return -2; case '\n': return -2; case '#': if (skip_comment(s) == -1) return -1; break; default: ungetc(c, s); c = -1; } } while (c != -1); if (read_lhs(s, name) == -1) return -1; if ( encoding = memchr(name->str, ':', name->len)) { encoding++; name->len = encoding - name->str - 1; name->str[name->len] = 0; } if (!encoding || !strcmp(encoding, ";")) { if (read_backslashed(s, value) == -1) return -1; } else if (!*encoding) { if (read_ldif_attrval(s, value) == -1) return -1; } else if (!strcmp(encoding, ":")) { unsigned char *ustr; int len; if (read_ldif_attrval(s, value) == -1) return -1; ustr = (unsigned char *) value->str;; if ( (len = read_base64(value->str, ustr, value->len)) == -1) { fputs("Error: Invalid Base64 string.\n", stderr); return -1; } value->len = len; } else if (!strcmp(encoding, "<")) { if (read_ldif_attrval(s, value) == -1) return -1; if (strncmp(value->str, "file://", 7)) { fputs("Error: Unknown URL scheme.\n", stderr); return -1; } if (read_from_file(value, value->str + 7) == -1) return -1; } else if (!strcasecmp(encoding, "crypt")) { char *hash; if (read_ldif_attrval(s, value) == -1) return -1; if ( !(hash = cryptdes(value->str))) return -1; g_string_assign(value, "{CRYPT}"); g_string_append(value, hash); } else if (!strcasecmp(encoding, "cryptmd5")) { char *hash; if (read_ldif_attrval(s, value) == -1) return -1; if ( !(hash = cryptmd5(value->str))) return -1; g_string_assign(value, "{CRYPT}"); g_string_append(value, hash); } else if (!strcasecmp(encoding, "sha")) { if (read_ldif_attrval(s, value) == -1) return -1; g_string_assign(value, "{SHA}"); if (!g_string_append_sha(value, value->str)) return -1; } else if (!strcasecmp(encoding, "ssha")) { if (read_ldif_attrval(s, value) == -1) return -1; g_string_assign(value, "{SSHA}"); if (!g_string_append_ssha(value, value->str)) return -1; } else if (!strcasecmp(encoding, "md5")) { if (read_ldif_attrval(s, value) == -1) return -1; g_string_assign(value, "{MD5}"); if (!g_string_append_md5(value, value->str)) return -1; } else if (!strcasecmp(encoding, "smd5")) { if (read_ldif_attrval(s, value) == -1) return -1; g_string_assign(value, "{SMD5}"); if (!g_string_append_smd5(value, value->str)) return -1; } else { char *ptr; int n = strtol(encoding, &ptr, 10); if (*ptr) { fputs("Error: Unknown value encoding.\n", stderr); return -1; } g_string_set_size(value, n); if (fread(value->str, 1, n, s) != n) syserr(); } return 0; } /* * Read a line in * name ' ' (':' encoding)? value '\n' * syntax, skipping comments. VALUE is parsed according to ENCODING. * Empty NAME is a parse error. * * 0: ok if name->len != 0 * 0: end of file or empty line if name->len == 0 * -1: parse error */ static int read_line(FILE *s, GString *name, GString *value) { int rc = read_line1(s, name, value); switch (rc) { case -2: return 0; case -1: return -1; case 0: if (!name->len) { fputs("Error: Space at beginning of line.\n", stderr); return -1; } return 0; default: abort(); } } static char * read_rename_body(FILE *s, GString *tmp1, GString *tmp2, int *deleteoldrdn) { char *dn; if (read_line(s, tmp1, tmp2) == -1) return 0; if (!tmp1->len) { fputs("Error: Rename record lacks dn line.\n", stderr); return 0; } *deleteoldrdn = !strcmp(tmp1->str, "replace"); if (!*deleteoldrdn && strcmp(tmp1->str, "add")) { fputs("Error: Expected 'add' or 'replace' in rename record.\n", stderr); return 0; } dn = xdup(tmp2->str); if (read_line(s, tmp1, tmp2) == -1) { free(dn); return 0; } if (tmp1->len) { free(dn); fputs("Error: Garbage at end of rename record.\n", stderr); return 0; } return dn; } static int read_nothing(FILE *s, GString *tmp1, GString *tmp2) { if (read_line(s, tmp1, tmp2) == -1) return -1; if (tmp1->len) { fputs("Error: Garbage at end of record.\n", stderr); return -1; } return 0; } static LDAPMod * ldapmod4line(char *action, char *ad) { LDAPMod *m; int op; if (!strcmp(action, "add")) op = LDAP_MOD_ADD; else if (!strcmp(action, "delete")) op = LDAP_MOD_DELETE; else if (!strcmp(action, "replace")) op = LDAP_MOD_REPLACE; else { fputs("Error: Invalid change marker.\n", stderr); return 0; } m = xalloc(sizeof(LDAPMod)); m->mod_op = op | LDAP_MOD_BVALUES; m->mod_type = xdup(ad); return m; } static LDAPMod ** read_modify_body(FILE *s, GString *tmp1, GString *tmp2) { LDAPMod **result; GPtrArray *mods = g_ptr_array_new(); GPtrArray *values; LDAPMod *m = 0; for (;;) { switch (read_line1(s, tmp1, tmp2)) { case 0: break; case -1: goto error; case -2: if (m) { g_ptr_array_add(values, 0); m->mod_bvalues = (void *) values->pdata; g_ptr_array_free(values, 0); values = 0; } goto done; default: abort(); } if (tmp1->len) { if (m) { g_ptr_array_add(values, 0); m->mod_bvalues = (void *) values->pdata; g_ptr_array_free(values, 0); values = 0; } values = g_ptr_array_new(); if ( !(m = ldapmod4line(tmp1->str, tmp2->str))) goto error; g_ptr_array_add(mods, m); } else g_ptr_array_add(values, gstring2berval(tmp2)); } done: g_ptr_array_add(mods, 0); result = (LDAPMod **) mods->pdata; g_ptr_array_free(mods, 0); return result; error: g_ptr_array_free(mods, 1); if (values) { int i; for (i = 0; i < values->len; i++) xfree_berval(values->pdata[i]); g_ptr_array_free(values, 0); } return 0; } /* * Lies die erste Zeile eines beliebigen Records nach position `offset' in `s'. * Setze *pos (falls pos != 0). * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - pos ist die exakte Anfangsposition. * - Setze *key auf den Schluessel (falls key != 0). * - Setze *dn auf den Distinguished Name (falls dn != 0). * EOF ist kein Fehler und liefert *key = 0 (falls key != 0); */ static int read_header(GString *tmp1, GString *tmp2, FILE *s, long offset, char **key, char **dn, long *pos) { char **rdns = 0; if (offset != -1) if (fseek(s, offset, SEEK_SET) == -1) syserr(); do { if (pos) if ( (*pos = ftell(s)) == -1) syserr(); if (read_line(s, tmp1, tmp2) == -1) return -1; if (tmp1->len == 0 && feof(s)) { if (key) *key = 0; return 0; } if (!strcmp(tmp1->str, "version")) { if (strcmp(tmp2->str, "ldapvi")) { fputs("Error: Invalid file format.\n", stderr); return -1; } tmp1->len = 0; } } while (!tmp1->len); rdns = ldap_explode_dn(tmp2->str, 0); if (!rdns) { fputs("Error: Invalid distinguished name string.\n", stderr); return -1; } if (key) *key = xdup(tmp1->str); if (dn) *dn = xdup(tmp2->str); ldap_value_free(rdns); return 0; } static int read_attrval_body(GString *tmp1, GString *tmp2, FILE *s, tentry *entry) { for (;;) { tattribute *attribute; if (read_line(s, tmp1, tmp2) == -1) return -1; if (!tmp1->len) break; attribute = entry_find_attribute(entry, tmp1->str, 1); attribute_append_value(attribute, tmp2->str, tmp2->len); } return 0; } /* * Lies ein attrval-record nach position `offset' in `s'. * Setze *pos (falls pos != 0). * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - pos ist die exakte Anfangsposition. * - Setze *entry auf den gelesenen Eintrag (falls entry != 0). * - Setze *key auf den Schluessel (falls key != 0). * EOF ist kein Fehler und liefert *key = 0 (falls key != 0); */ int read_entry(FILE *s, long offset, char **key, tentry **entry, long *pos) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *dn; char *k = 0; tentry *e = 0; int rc = read_header(tmp1, tmp2, s, offset, &k, &dn, pos); if (rc || !k) goto cleanup; e = entry_new(dn); rc = read_attrval_body(tmp1, tmp2, s, e); if (!rc) { if (entry) { *entry = e; e = 0; } if (key) { *key = k; k = 0; } } cleanup: if (k) free(k); if (e) entry_free(e); g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } /* * Lies die erste Zeile eines beliebigen Records nach position `offset' in `s'. * Setze *pos (falls pos != 0). * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - pos ist die exakte Anfangsposition. * - Setze *key auf den Schluessel (falls key != 0). */ int peek_entry(FILE *s, long offset, char **key, long *pos) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); int rc = read_header(tmp1, tmp2, s, offset, key, 0, pos); g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } /* * Lies ein rename-record nach position `offset' in `s'. * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - Setze *dn1 auf den alten DN. * - Setze *dn2 auf den neuen DN. * - *deleteoldrdn auf 1 oder 0; */ int read_rename(FILE *s, long offset, char **dn1, char **dn2, int *deleteoldrdn) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *olddn; char *newdn; int rc = read_header(tmp1, tmp2, s, offset, 0, &olddn, 0); if (rc) { g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } newdn = read_rename_body(s, tmp1, tmp2, deleteoldrdn); g_string_free(tmp1, 1); g_string_free(tmp2, 1); if (!newdn) { free(olddn); return -1; } if (dn1) *dn1 = olddn; else free(olddn); if (dn2) *dn2 = newdn; else free(newdn); return 0; } int read_delete(FILE *s, long offset, char **dn) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *str; int rc = read_header(tmp1, tmp2, s, offset, 0, &str, 0); if (rc) { g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } rc = read_nothing(s, tmp1, tmp2); g_string_free(tmp1, 1); g_string_free(tmp2, 1); if (rc == -1) free(str); else *dn = str; return rc; } /* * Lies ein modify-record nach position `offset' in `s'. * Liefere 0 bei Erfolg, -1 sonst. * Bei Erfolg: * - Setze *dn auf den DN. * - Setze *mods auf die Aenderungen. */ int read_modify(FILE *s, long offset, char **dn, LDAPMod ***mods) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *d; LDAPMod **m; int rc = read_header(tmp1, tmp2, s, offset, 0, &d, 0); if (rc) { g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } m = read_modify_body(s, tmp1, tmp2); g_string_free(tmp1, 1); g_string_free(tmp2, 1); if (!m) { free(d); return -1; } if (dn) *dn = d; else free(d); if (mods) *mods = m; else ldap_mods_free(m, 1); return 0; } /* * Parse a complete entry or changerecord and ignore it. Set *key accordingly. * Leave the stream positioned after the entry. * * Treat EOF as success and set *key to NULL. * * return value: * 0 on success * -1 on parse error */ /* * FIXME: Warum lesen wir hier nicht einfach bis zur naechsten leeren Zeile? */ int skip_entry(FILE *s, long offset, char **key) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *k = 0; int rc = read_header(tmp1, tmp2, s, offset, &k, 0, 0); if (rc || !k) ; else if (!strcmp(k, "modify")) { LDAPMod **mods = read_modify_body(s, tmp1, tmp2); if (mods) ldap_mods_free(mods, 1); else rc = -1; } else if (!strcmp(k, "rename")) { int dor; char *newdn = read_rename_body(s, tmp1, tmp2, &dor); if (newdn) free(newdn); else rc = -1; } else if (!strcmp(k, "delete")) rc = read_nothing(s, tmp1, tmp2); else { tentry *e = entry_new(xdup("")); rc = read_attrval_body(tmp1, tmp2, s, e); entry_free(e); } if (key) *key = k; else free(k); g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } static int read_profile_header(GString *tmp1, GString *tmp2, FILE *s, char **name) { do { if (read_line(s, tmp1, tmp2) == -1) return -1; if (tmp1->len == 0 && feof(s)) { *name = 0; return 0; } } while (!tmp1->len); if (strcmp(tmp1->str, "profile")) { fprintf(stderr, "Error: Expected 'profile' in configuration," " found '%s' instead.\n", tmp1->str); return -1; } *name = xdup(tmp2->str); return 0; } int read_profile(FILE *s, tentry **entry) { GString *tmp1 = g_string_new(""); GString *tmp2 = g_string_new(""); char *name; tentry *e = 0; int rc = read_profile_header(tmp1, tmp2, s, &name); if (rc || !name) goto cleanup; e = entry_new(name); rc = read_attrval_body(tmp1, tmp2, s, e); if (!rc) { *entry = e; e = 0; } cleanup: if (e) entry_free(e); g_string_free(tmp1, 1); g_string_free(tmp2, 1); return rc; } tparser ldapvi_parser = { read_entry, peek_entry, skip_entry, read_rename, read_delete, read_modify, print_ldapvi_entry }; ldapvi-1.7/ldapvi.c0000644000175000017500000012205110617054666013237 0ustar daviddavid/* -*- show-trailing-whitespace: t; indent-tabs: t -*- * * Copyright (c) 2003,2004,2005,2006 David Lichteblau * Copyright (c) 2006 Perry Nguyen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include "common.h" typedef void (*handler_entry)(char *, tentry *, void *); static void parse_file( FILE *, tparser *, thandler *, void *, handler_entry, void *, int); static void cut_datafile(char *, long, cmdline *); static int write_file_header(FILE *, cmdline *); static int rebind(LDAP *, bind_options *, int, char *, int); static int compare(tparser *p, thandler *handler, void *userdata, GArray *offsets, char *cleanname, char *dataname, long *error_position, cmdline *cmdline) { FILE *clean, *data; int rc; long pos; if ( !(clean = fopen(cleanname, "r+"))) syserr(); if ( !(data = fopen(dataname, "r"))) syserr(); rc = compare_streams(p, handler, userdata, offsets, clean, data, &pos, error_position); if (fclose(clean) == EOF) syserr(); if (fclose(data) == EOF) syserr(); if (rc == -2) { /* an error has happened */ int n; if (!cmdline) { fputs("oops: unexpected error in handler\n", stderr); exit(1); } /* remove already-processed entries from the data file */ cut_datafile(dataname, pos, cmdline); /* flag already-processed entries in the offset table */ for (n = 0; n < offsets->len; n++) if (g_array_index(offsets, long, n) < 0) g_array_index(offsets, long, n) = -1; } return rc; } static void cleanup(int rc, char *pathname) { DIR *dir; struct dirent *entry; GString *str = g_string_new(pathname); int len; struct termios term; /* * delete temporary directory */ g_string_append(str, "/"); len = str->len; if ( !(dir = opendir(pathname))) syserr(); while ( (entry = readdir(dir))) if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")){ g_string_truncate(str, len); g_string_append(str, entry->d_name); if (unlink(str->str) == -1) syserr(); } if (closedir(dir) == -1) syserr(); if (rmdir(pathname) == -1) syserr(); g_string_free(str, 1); /* * reset terminal */ if (tcgetattr(0, &term) == -1) /* oh, running without a terminal */ return; term.c_lflag |= ICANON; term.c_lflag |= ECHO; if (tcsetattr(0, TCSANOW, &term) == -1) syserr(); } static void cleanup_signal(int n) { fprintf(stderr, "\nCaught signal %d, exiting...\n", n); exit(2); } static int moddn(LDAP *ld, char *old, char *new, int dor, LDAPControl **ctrls) { int rc; char **newrdns = ldap_explode_dn(new, 0); char **ptr = newrdns; char *newrdn = *ptr++; GString *newsup = g_string_sized_new(strlen(new)); if (newrdn) { if (*ptr) g_string_append(newsup, *ptr++); for (; *ptr; ptr++) { g_string_append_c(newsup, ','); g_string_append(newsup, *ptr); } } else newrdn = ""; rc = ldap_rename_s(ld, old, newrdn, newsup->str, dor, ctrls, 0); g_string_free(newsup, 1); ldap_value_free(newrdns); return rc; } /***************************************** * ldapmodify_handler */ struct ldapmodify_context { LDAP *ld; LDAPControl **controls; int verbose; int noquestions; int continuous; }; static int ldapmodify_error(struct ldapmodify_context *ctx, char *error) { ldap_perror(ctx->ld, error); if (!ctx->continuous) return -1; fputs("(error ignored)\n", stderr); return 0; } static int ldapmodify_change( int key, char *labeldn, char *dn, LDAPMod **mods, void *userdata) { struct ldapmodify_context *ctx = userdata; LDAP *ld = ctx->ld; LDAPControl **ctrls = ctx->controls; int verbose = ctx->verbose; if (verbose) printf("(modify) %s\n", labeldn); if (ldap_modify_ext_s(ld, dn, mods, ctrls, 0)) return ldapmodify_error(ctx, "ldap_modify"); return 0; } static int ldapmodify_rename(int key, char *dn1, tentry *modified, void *userdata) { struct ldapmodify_context *ctx = userdata; LDAP *ld = ctx->ld; LDAPControl **ctrls = ctx->controls; int verbose = ctx->verbose; char *dn2 = entry_dn(modified); int deleteoldrdn = frob_rdn(modified, dn1, FROB_RDN_CHECK) == -1; if (verbose) printf("(rename) %s to %s\n", dn1, dn2); if (moddn(ld, dn1, dn2, deleteoldrdn, ctrls)) return ldapmodify_error(ctx, "ldap_rename"); return 0; } static int ldapmodify_add(int key, char *dn, LDAPMod **mods, void *userdata) { struct ldapmodify_context *ctx = userdata; LDAP *ld = ctx->ld; LDAPControl **ctrls = ctx->controls; int verbose = ctx->verbose; if (verbose) printf("(add) %s\n", dn); if (ldap_add_ext_s(ld, dn, mods, ctrls, 0)) return ldapmodify_error(ctx, "ldap_add"); return 0; } static int ldapmodify_delete(int key, char *dn, void *userdata) { struct ldapmodify_context *ctx = userdata; LDAP *ld = ctx->ld; LDAPControl **ctrls = ctx->controls; int verbose = ctx->verbose; if (verbose) printf("(delete) %s\n", dn); switch (ldap_delete_ext_s(ld, dn, ctrls, 0)) { case 0: break; case LDAP_NOT_ALLOWED_ON_NONLEAF: if (!ctx->noquestions) return -2; /* else fall through */ default: return ldapmodify_error(ctx, "ldap_delete"); } return 0; } static int ldapmodify_rename0( int key, char *dn1, char *dn2, int deleteoldrdn, void *userdata) { struct ldapmodify_context *ctx = userdata; LDAP *ld = ctx->ld; LDAPControl **ctrls = ctx->controls; int verbose = ctx->verbose; if (verbose) printf("(rename) %s to %s\n", dn1, dn2); if (moddn(ld, dn1, dn2, deleteoldrdn, ctrls)) return ldapmodify_error(ctx, "ldap_rename"); return 0; } /***************************************** * ldif_handler */ static int ldif_change(int key, char *labeldn, char *dn, LDAPMod **mods, void *userdata) { FILE *s = userdata; print_ldif_modify(s, dn, mods); return 0; } static int ldif_rename(int key, char *olddn, tentry *modified, void *userdata) { FILE *s = userdata; int deleteoldrdn = frob_rdn(modified, olddn, FROB_RDN_CHECK) == -1; print_ldif_rename( s, olddn, entry_dn(modified), deleteoldrdn); return 0; } static int ldif_add(int key, char *dn, LDAPMod **mods, void *userdata) { FILE *s = userdata; print_ldif_add(s, dn, mods); return 0; } static int ldif_delete(int key, char *dn, void *userdata) { FILE *s = userdata; print_ldif_delete(s, dn); return 0; } static int ldif_rename0(int key, char *dn1, char *dn2, int deleteoldrdn, void *userdata) { FILE *s = userdata; print_ldif_rename(s, dn1, dn2, deleteoldrdn); return 0; } static thandler ldif_handler = { ldif_change, ldif_rename, ldif_add, ldif_delete, ldif_rename0 }; /***************************************** * noop handler */ static int noop_change(int key, char *labeldn, char *dn, LDAPMod **mods, void *userdata) { return 0; } static int noop_rename(int key, char *olddn, tentry *modified, void *userdata) { return 0; } static int noop_add(int key, char *dn, LDAPMod **mods, void *userdata) { return 0; } static int noop_delete(int key, char *dn, void *userdata) { return 0; } static int noop_rename0(int key, char *dn1, char *dn2, int deleteoldrdn, void *userdata) { return 0; } /***************************************** * forget_deletions_handler */ static int forget_deletion(int key, char *dn, void *userdata) { GArray *deletions = userdata; g_array_append_val(deletions, key); return 0; } static thandler forget_deletions_handler = { noop_change, noop_rename, noop_add, forget_deletion, noop_rename0 }; /***************************************** * vdif_handler */ static int vdif_change(int key, char *labeldn, char *dn, LDAPMod **mods, void *userdata) { FILE *s = userdata; print_ldapvi_modify(s, dn, mods); return 0; } static int vdif_rename(int key, char *olddn, tentry *modified, void *userdata) { FILE *s = userdata; int deleteoldrdn = frob_rdn(modified, olddn, FROB_RDN_CHECK) == -1; print_ldapvi_rename(s, olddn, entry_dn(modified), deleteoldrdn); return 0; } static int vdif_add(int key, char *dn, LDAPMod **mods, void *userdata) { FILE *s = userdata; print_ldapvi_add(s, dn, mods); return 0; } static int vdif_delete(int key, char *dn, void *userdata) { FILE *s = userdata; print_ldapvi_delete(s, dn); return 0; } static int vdif_rename0(int key, char *dn1, char *dn2, int deleteoldrdn, void *userdata) { FILE *s = userdata; print_ldapvi_rename(s, dn1, dn2, deleteoldrdn); return 0; } /***************************************** * statistics_handler */ struct statistics { int nmodify, nadd, ndelete, nrename; }; static int statistics_change( int key, char *labeldn, char *dn, LDAPMod **mods, void *userdata) { struct statistics *st = userdata; st->nmodify++; return 0; } static int statistics_rename(int key, char *olddn, tentry *modified, void *userdata) { struct statistics *st = userdata; st->nrename++; return 0; } static int statistics_add(int key, char *dn, LDAPMod **mods, void *userdata) { struct statistics *st = userdata; st->nadd++; return 0; } static int statistics_delete(int key, char *dn, void *userdata) { struct statistics *st = userdata; st->ndelete++; return 0; } static int statistics_rename0( int key, char *dn1, char *dn2, int deleteoldrdn, void *userdata) { struct statistics *st = userdata; st->nrename++; return 0; } /* end of handlers * **************************************** */ struct rebind_data { bind_options bind_options; LDAPURLDesc *seen; }; static void toggle_sasl(bind_options *bo) { if (bo->authmethod == LDAP_AUTH_SIMPLE) { bo->authmethod = LDAP_AUTH_SASL; puts("SASL authentication enabled."); printf("SASL mechanism: %s (use '*' to change)\n", bo->sasl_mech ? bo->sasl_mech : "(none)"); } else { bo->authmethod = LDAP_AUTH_SIMPLE; puts("Simple authentication enabled."); } } static void change_mechanism(bind_options *bo) { if (bo->authmethod == LDAP_AUTH_SIMPLE) { bo->authmethod = LDAP_AUTH_SASL; puts("Switching to SASL authentication."); } bo->sasl_mech = getline("SASL mechanism", bo->sasl_mech); } static int rebind_callback( LDAP *ld, const char *url, ber_tag_t request, int msgid, void *args) { struct rebind_data *rebind_data = args; LDAPURLDesc *urld; bind_options bo = rebind_data->bind_options; printf("Received referral to %s.\n", url); if (ldap_url_parse(url, &urld)) { puts("Error: Cannot parse URL."); return -1; } if (rebind_data->seen && !strcmp(rebind_data->seen->lud_scheme, urld->lud_scheme) && !strcmp(rebind_data->seen->lud_host, urld->lud_host) && rebind_data->seen->lud_port == urld->lud_port) /* confirmed already */ return 0; printf("You are not logged in to %s://%s:%d yet.\n" "Type '!' or 'y' to do so.\n", urld->lud_scheme, urld->lud_host, urld->lud_port); for (;;) { bo.dialog = BD_ALWAYS; switch (choose("Rebind?", "y!nB*qQ?", "(Type '?' for help.)")) { case '!': bo.dialog = BD_NEVER; /* fall through */ case 'y': if (rebind(ld, &bo, 0, 0, 1) == 0) { if (rebind_data->seen) ldap_free_urldesc(rebind_data->seen); rebind_data->seen = urld; return 0; } break; case 'n': ldap_free_urldesc(urld); return 0; case '*': change_mechanism(&bo); break; case 'B': toggle_sasl(&bo); break; case 'q': ldap_free_urldesc(urld); return -1; case 'Q': exit(0); case '?': puts("Commands:\n" " y -- ask for user name and rebind\n" " ! -- rebind using cached credentials\n" " n -- don't login, just continue\n" " B -- toggle SASL\n" " * -- set SASL mechanism\n" " q -- give up\n" " Q -- give up and exit ldapvi\n" " ? -- this help"); break; } } } static char * find_user(LDAP *ld, char *filter) { char *dn = 0; LDAPMessage *result = 0; LDAPMessage *entry = 0; if (ldap_bind_s(ld, 0, 0, LDAP_AUTH_SIMPLE)) { ldap_perror(ld, "ldap_bind"); goto cleanup; } if (ldap_search_s(ld, 0, LDAP_SCOPE_SUBTREE, filter, 0, 0, &result)) { ldap_perror(ld, "ldap_search"); goto cleanup; } if ( !(entry = ldap_first_entry(ld, result))) { puts("User not found."); goto cleanup; } if (ldap_next_entry(ld, result)) { puts("More than one entry matched user filter."); goto cleanup; } dn = ldap_get_dn(ld, entry); cleanup: if (result) ldap_msgfree(result); return dn; } static void ensure_tmp_directory(char *dir) { if (strcmp(dir, "/tmp/ldapvi-XXXXXX")) return; mkdtemp(dir); on_exit((on_exit_function) cleanup, dir); signal(SIGTERM, cleanup_signal); signal(SIGINT, cleanup_signal); signal(SIGPIPE, SIG_IGN); } static int rebind_sasl(LDAP *ld, bind_options *bind_options, char *dir, int verbose) { tsasl_defaults *defaults = sasl_defaults_new(bind_options); int rc; int sasl_mode; switch (bind_options->dialog) { case BD_NEVER: sasl_mode = LDAP_SASL_QUIET; break; case BD_AUTO: sasl_mode = LDAP_SASL_AUTOMATIC; break; case BD_ALWAYS: sasl_mode = LDAP_SASL_INTERACTIVE; break; default: abort(); } if (dir) { ensure_tmp_directory(dir); init_sasl_redirection(defaults, append(dir, "/sasl")); } rc = ldap_sasl_interactive_bind_s( ld, bind_options->user, bind_options->sasl_mech, NULL, NULL, sasl_mode, ldapvi_sasl_interact, defaults); sasl_defaults_free(defaults); if (defaults->fd != -1) { finish_sasl_redirection(defaults); free(defaults->pathname); } if (rc != LDAP_SUCCESS) { ldap_perror(ld, "ldap_sasl_interactive_bind_s"); return -1; } if (verbose) printf("Bound as authzid=%s, authcid=%s.\n", bind_options->sasl_authzid, bind_options->sasl_authcid); return 0; } static int rebind_simple(LDAP *ld, bind_options *bo, int verbose) { if (bo->dialog == BD_ALWAYS || (bo->dialog == BD_AUTO && bo->user && !bo->password)) { tdialog d[2]; init_dialog(d, DIALOG_DEFAULT, "Filter or DN", bo->user); init_dialog(d + 1, DIALOG_PASSWORD, "Password", bo->password); dialog("--- Login", d, 2, bo->user ? 1 : 0); bo->user = d[0].value; bo->password = d[1].value; } if (bo->user && bo->user[0] == '(') /* user is a search filter, not a name */ if ( !(bo->user = find_user(ld, bo->user))) return -1; if (ldap_bind_s(ld, bo->user, bo->password, LDAP_AUTH_SIMPLE)) { ldap_perror(ld, "ldap_bind"); return -1; } if (verbose) printf("Bound as %s.\n", bo->user); return 0; } static int rebind(LDAP *ld, bind_options *bind_options, int register_callback, char *dir, int verbose) { int rc = -1; struct rebind_data *rebind_data = xalloc(sizeof(struct rebind_data)); switch (bind_options->authmethod) { case LDAP_AUTH_SASL: if (rebind_sasl(ld, bind_options, dir, verbose)) return -1; break; case LDAP_AUTH_SIMPLE: if (rebind_simple(ld, bind_options, verbose)) return -1; break; } if (register_callback) { rebind_data->bind_options = *bind_options; rebind_data->bind_options.password = xdup(bind_options->password); rebind_data->seen = 0; if (ldap_set_rebind_proc(ld, rebind_callback, rebind_data)) ldaperr(ld, "ldap_set_rebind_proc"); } return 0; } void init_sasl_arguments(LDAP *ld, bind_options *bind_options) { if (!bind_options->sasl_mech) ldap_get_option(ld, LDAP_OPT_X_SASL_MECH, &bind_options->sasl_mech); if (!bind_options->sasl_realm) ldap_get_option(ld, LDAP_OPT_X_SASL_REALM, &bind_options->sasl_realm); if (!bind_options->sasl_authcid) ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHCID, &bind_options->sasl_authcid); if (!bind_options->sasl_authzid) ldap_get_option(ld, LDAP_OPT_X_SASL_AUTHZID, &bind_options->sasl_authzid); } static LDAP * do_connect(char *server, bind_options *bind_options, int referrals, int starttls, int tls, int deref, int profileonlyp, char *dir) { LDAP *ld = 0; int rc = 0; int drei = 3; if (server && !strstr(server, "://")) { char *url = xalloc(strlen(server) + sizeof("ldap://")); strcpy(url, "ldap://"); strcpy(url + 7, server); server = url; } if (ldap_set_option(0, LDAP_OPT_X_TLS_REQUIRE_CERT, (void *) &tls)) ldaperr(0, "ldap_set_option(LDAP_OPT_X_TLS)"); if ( rc = ldap_initialize(&ld, server)) { fprintf(stderr, "ldap_initialize: %s\n", ldap_err2string(rc)); exit(1); } if (!profileonlyp) init_sasl_arguments(ld, bind_options); if (ldap_set_option(ld, LDAP_OPT_PROTOCOL_VERSION, &drei)) ldaperr(ld, "ldap_set_option(LDAP_OPT_PROTOCOL_VERSION)"); if (starttls) if (ldap_start_tls_s(ld, 0, 0)) ldaperr(ld, "ldap_start_tls_s"); if (rebind(ld, bind_options, 1, dir, 0) == -1) { ldap_unbind_s(ld); return 0; } /* after initial bind, always ask interactively (except in '!' rebinds, * which are special-cased): */ bind_options->dialog = BD_ALWAYS; if (ldap_set_option(ld, LDAP_OPT_REFERRALS, referrals ? LDAP_OPT_ON : LDAP_OPT_OFF)) ldaperr(ld, "ldap_set_option(LDAP_OPT_REFERRALS)"); if (ldap_set_option(ld, LDAP_OPT_DEREF, (void *) &deref)) ldaperr(ld, "ldap_set_option(LDAP_OPT_DEREF)"); return ld; } /* * fixme: brauchen wir das mit dem user? dann sollten wir hier noch * sasl support vorsehen * * ldapvi-Kommandozeile konnte auch nicht schaden */ static int save_ldif(tparser *parser, GArray *offsets, char *clean, char *data, char *server, char *user, int managedsait) { int fd; FILE *s; GString *name = g_string_sized_new(300); g_string_append(name, ",ldapvi-"); if (gethostname(name->str + name->len, 300 - name->len) == -1) syserr(); name->len = strlen(name->str); g_string_sprintfa(name, "-%d.ldif", getpid()); if ( (fd = open(name->str, O_WRONLY | O_CREAT | O_EXCL, 0600)) == -1) { int error = errno; fprintf(stderr, "Cannot save %s: ", name->str); errno = error; perror(0); g_string_free(name, 1); return 1; } if ( !(s = fdopen(fd, "w"))) syserr(); fputs("version: 1\n", s); fputs("# to apply these changes using ldapvi, run:\n", s); fputs("# ldapvi --ldapmodify", s); if (managedsait) fputs(" -M", s); if (server) { fputs(" -h ", s); fputs(server, s); } fputc(' ', s); fputs(name->str, s); fputc('\n', s); compare(parser, &ldif_handler, s, offsets, clean, data, 0, 0); if (fclose(s) == EOF) syserr(); printf("Your changes have been saved to %s.\n", name->str); return 0; } static void view_ldif(tparser *parser, char *dir, GArray *offsets, char *clean, char *data) { FILE *s; char *name = append(dir, "/ldif"); if ( !(s = fopen(name, "w"))) syserr(); fputs("version: 1\n", s); compare(parser, &ldif_handler, s, offsets, clean, data, 0, 0); if (fclose(s) == EOF) syserr(); view(name); free(name); } static thandler vdif_handler = { vdif_change, vdif_rename, vdif_add, vdif_delete, vdif_rename0 }; static void view_vdif(tparser *parser, char *dir, GArray *offsets, char *clean, char *data) { FILE *s; char *name = append(dir, "/vdif"); if ( !(s = fopen(name, "w"))) syserr(); fputs("version: ldapvi\n", s); compare(parser, &vdif_handler, s, offsets, clean, data, 0, 0); if (fclose(s) == EOF) syserr(); view(name); free(name); } static void setcolor(int fg) { char *bold = tigetstr("bold"); char *setaf = tigetstr("setaf"); if (setaf) putp(tparm(setaf, fg)); if (bold) putp(bold); } static void print_counter(int color, char *label, int value) { char *sgr0 = tigetstr("sgr0"); if (value) setcolor(color); printf("%s: %d", label, value); if (sgr0) putp(sgr0); } /* collect statistics. This comparison step is important * for catching syntax errors before real processing starts. */ static int analyze_changes(tparser *p, GArray *offsets, char *clean, char *data, cmdline *cmdline) { struct statistics st; static thandler statistics_handler = { statistics_change, statistics_rename, statistics_add, statistics_delete, statistics_rename0 }; int rc; long pos; retry: memset(&st, 0, sizeof(st)); rc = compare( p, &statistics_handler, &st, offsets, clean, data, &pos, 0); /* Success? */ if (rc == 0) { if (!(st.nadd + st.ndelete + st.nmodify + st.nrename)) { if (!cmdline->quiet) puts("No changes."); return 0; } if (cmdline->quiet) return 1; print_counter(COLOR_GREEN, "add", st.nadd); fputs(", ", stdout); print_counter(COLOR_BLUE, "rename", st.nrename); fputs(", ", stdout); print_counter(COLOR_YELLOW, "modify", st.nmodify); fputs(", ", stdout); print_counter(COLOR_RED, "delete", st.ndelete); putchar('\n'); return 1; } if (cmdline->noninteractive) { fputs("Syntax error in noninteractive mode, giving up.\n", stderr); exit(1); } /* Syntax error */ for (;;) { switch (choose("What now?", "eQ?", "(Type '?' for help.)")) { case 'e': edit_pos(data, pos); goto retry; case 'Q': exit(0); case '?': puts("Commands:\n" " Q -- discard changes and quit\n" " e -- open editor again\n" " ? -- this help"); break; } } } static void commit(tparser *p, LDAP *ld, GArray *offsets, char *clean, char *data, LDAPControl **ctrls, int verbose, int noquestions, int continuous, cmdline *cmdline) { struct ldapmodify_context ctx; static thandler ldapmodify_handler = { ldapmodify_change, ldapmodify_rename, ldapmodify_add, ldapmodify_delete, ldapmodify_rename0 }; ctx.ld = ld; ctx.controls = ctrls; ctx.verbose = verbose; ctx.noquestions = noquestions; ctx.continuous = continuous; switch (compare(p, &ldapmodify_handler, &ctx, offsets, clean, data, 0, cmdline)) { case 0: if (!cmdline->quiet) puts("Done."); write_ldapvi_history(); exit(0); case -1: yourfault("unexpected syntax error!"); case -2: /* user error */ break; default: abort(); } } static int getty(int fd) { if (close(fd) == -1) syserr(); if (open("/dev/tty", O_RDWR) != fd) return -1; return 0; } static int fixup_streams(FILE **source, FILE **target) { int rc = 0; /* find a terminal and restore fds 0, 1 to a sensible value for * reading the password. Save the original streams for later use.*/ if (!isatty(0)) { /* user has redirected stdout */ int in = dup(fileno(stdin)); if (in == -1) syserr(); *source = fdopen(in, "r"); if (getty(0) == -1) rc = -1; } if (!isatty(1)) { /* user has redirected stdout */ int out = dup(fileno(stdout)); if (out == -1) syserr(); *target = fdopen(out, "w"); if (getty(1) == -1) rc = -1; } return rc; } static int ndecimalp(char *str) { char *ptr; strtol(str, &ptr, 10); return !*ptr; } static void skip(tparser *p, char *dataname, GArray *offsets, cmdline *cmdline) { long pos; char *key; FILE *s; if ( !(s = fopen(dataname, "r"))) syserr(); p->skip(s, 0, &key); if ( (pos = ftell(s)) == -1) syserr(); if (fclose(s) == EOF) syserr(); if (key) { cut_datafile(dataname, pos, cmdline); if (ndecimalp(key)) g_array_index(offsets, long, atoi(key)) = -1; free(key); } else { /* Im Normalfall wollen wir einen Eintrag in data * ueberspringen. Wenn aber in data nichts mehr steht, * sind wir ueber die eigentlichen Aenderungen schon * hinweg und es handelt sich um eine Loeschung. In * diesem Fall muessen wir nur das Offset aus der * Tabelle entfernen. */ int n; for (n = 0; n < offsets->len; n++) if (g_array_index(offsets, long, n) >= 0) { g_array_remove_index(offsets, n); break; } } } static tentroid * entroid_set_entry(LDAP *ld, tentroid *entroid, tentry *entry) { int i; tattribute *oc = entry_find_attribute(entry, "objectClass", 0); GPtrArray *values; if (!oc) return 0; entroid_reset(entroid); values = attribute_values(oc); for (i = 0; i < values->len; i++) { GArray *av = g_ptr_array_index(values, i); LDAPObjectClass *cls; { char zero = 0; /* PFUSCH! die GArrays muessen absolut weg! */ g_array_append_val(av, zero); av->len--; } cls = entroid_request_class(entroid, av->data); if (!cls) { g_string_append(entroid->comment, "# "); g_string_append(entroid->comment, entroid->error->str); return entroid; } } if (compute_entroid(entroid) == -1) { g_string_append(entroid->comment, "# "); g_string_append(entroid->comment, entroid->error->str); return entroid; } return entroid; } struct annotation_context { LDAP *ld; FILE *out; tparser *parser; tentroid *entroid; }; static void annotate_entry(char *key, tentry *entry, void *userdata) { struct annotation_context *ctx = userdata; tentroid *entroid = entroid_set_entry(ctx->ld, ctx->entroid, entry); ctx->parser->print(ctx->out, entry, key, entroid); } static void rewrite_comments(LDAP *ld, char *dataname, cmdline *cmdline) { FILE *in; FILE *out; char *tmpname; tparser *p = &ldapvi_parser; thandler *h = &vdif_handler; struct annotation_context ctx; int addp = cmdline->ldapmodify_add; tschema *schema = schema_new(ld); if (!schema) { fputs("Error: Failed to read schema.\n", stderr); return; } tmpname = append(dataname, ".tmp"); if ( !(in = fopen(dataname, "r"))) syserr(); if ( !(out = fopen(tmpname, "w"))) syserr(); write_file_header(out, cmdline); if (cmdline->ldif) { p = &ldif_parser; h = &ldif_handler; } ctx.ld = ld; ctx.out = out; ctx.entroid = entroid_new(schema); ctx.parser = p; parse_file(in, p, h, out, annotate_entry, &ctx, addp); if (fclose(in) == EOF) syserr(); if (fclose(out) == EOF) syserr(); rename(tmpname, dataname); free(tmpname); schema_free(schema); } static void forget_deletions(tparser *p, GArray *offsets, char *clean, char *data) { int i; GArray *deletions = g_array_new(0, 0, sizeof(int)); compare(p, &forget_deletions_handler, deletions, offsets, clean, data, 0, 0); for (i = 0; i < deletions->len; i++) { int n = g_array_index(deletions, int, i); g_array_index(offsets, long, n) = -1; } g_array_free(deletions, 1); } static void append_sort_control(LDAP *ld, GPtrArray *ctrls, char *keystring) { LDAPControl *ctrl; LDAPSortKey **keylist; if (ldap_create_sort_keylist(&keylist, keystring)) ldaperr(ld, "ldap_create_sort_keylist"); if (ldap_create_sort_control(ld, keylist, 1, &ctrl)) ldaperr(ld, "ldap_create_sort_keylist"); g_ptr_array_add(ctrls, ctrl); } static GArray * read_offsets(tparser *p, char *file) { GArray *offsets = g_array_new(0, 0, sizeof(long)); FILE *s; if ( !(s = fopen(file, "r"))) syserr(); for (;;) { long offset; char *key, *ptr; int n; tentry *entry; key = 0; if (p->entry(s, -1, &key, &entry, &offset) == -1) exit(1); if (!key) break; n = strtol(key, &ptr, 10); if (*ptr) { fprintf(stderr, "Error: Invalid key: `%s'.\n", key); exit(1); } if (n != offsets->len) { fprintf(stderr, "Error: Unexpected key: `%s'.\n", key); exit(1); } free(key); entry_free(entry); g_array_append_val(offsets, offset); } if (fclose(s) == -1) syserr(); return offsets; } static void offline_diff(tparser *p, char *a, char *b) { GArray *offsets = read_offsets(p, a); compare(p, &ldif_handler, stdout, offsets, a, b, 0, 0); g_array_free(offsets, 1); } void write_config(LDAP *ld, FILE *f, cmdline *cmdline) { char *user = cmdline->bind_options.user; char *server = cmdline->server; int limit; if (!f) f = stdout; fputs("# ldap.conf(5)\n", f); fputs("# edit this as needed and paste into ~/.ldaprc\n", f); /* URI/HOST */ fputc('\n', f); fputs("# server name\n", f); fputs("# (for parameterless operation, make sure to include at" " least this line)\n", f); if (!server) ldap_get_option(ld, LDAP_OPT_URI, &server); if (!server) ldap_get_option(ld, LDAP_OPT_HOST_NAME, &server); if (server) if (strstr(server, "://")) fprintf(f, "URI %s\n", server); else fprintf(f, "HOST %s\n", server); /* BASE */ fputc('\n', f); fputs("# default search base\n", f); if (cmdline->basedns->len) { GPtrArray *basedns = cmdline->basedns; int i; if (basedns->len > 1) fputs("### multiple namingcontexts found (uncomment" " one of these lines):\n", f); for (i = 0; i < basedns->len; i++) { if (basedns->len > 1) fputc('#', f); fprintf(f, "BASE %s\n", g_ptr_array_index(basedns, i)); } } else { if (!cmdline->discover) fputs("### no search base specified, retry with" " --discover?\n", f); fputs("#BASE \n", f); } /* BINDDN */ fputc('\n', f); fputs("# user to bind as\n", f); if (user && user[0] == '(') user = find_user(ld, user); if (user) fprintf(f, "BINDDN %s\n", user); else fputs("#BINDDN \n", f); /* search options */ fputc('\n', f); fputs("# search parameters (uncomment as needed)\n", f); switch (cmdline->deref) { case LDAP_DEREF_NEVER: fputs("#DEREF never\n", f); break; case LDAP_DEREF_SEARCHING: fputs("#DEREF searcing\n", f); break; case LDAP_DEREF_FINDING: fputs("#DEREF finding\n", f); break; case LDAP_DEREF_ALWAYS: fputs("#DEREF always\n", f); break; } ldap_get_option(ld, LDAP_OPT_SIZELIMIT, &limit); fprintf(f, "#SIZELIMIT %d\n", limit); ldap_get_option(ld, LDAP_OPT_TIMELIMIT, &limit); fprintf(f, "#TIMELIMIT %d\n", limit); } static void add_changerecord(FILE *s, cmdline *cmdline) { switch (cmdline->mode) { case ldapvi_mode_delete: { char **ptr; for (ptr = cmdline->delete_dns; *ptr; ptr++) if (cmdline->ldif) print_ldif_delete(s, *ptr); else print_ldapvi_delete(s, *ptr); break; } case ldapvi_mode_rename: if (cmdline->ldif) print_ldif_rename(s, cmdline->rename_old, cmdline->rename_new, cmdline->rename_dor); else print_ldapvi_rename(s, cmdline->rename_old, cmdline->rename_new, cmdline->rename_dor); break; case ldapvi_mode_modrdn: if (cmdline->ldif) print_ldif_modrdn(s, cmdline->rename_old, cmdline->rename_new, cmdline->rename_dor); else print_ldapvi_modrdn(s, cmdline->rename_old, cmdline->rename_new, cmdline->rename_dor); break; default: abort(); } } static void add_template(LDAP *ld, FILE *s, GPtrArray *wanted, char *base) { int i; tentroid *entroid; LDAPObjectClass *cls; LDAPAttributeType *at; tschema *schema = schema_new(ld); if (!schema) { fputs("Error: Failed to read schema, giving up.\n", stderr); exit(1); } entroid = entroid_new(schema); for (i = 0; i < wanted->len; i++) { char *name = g_ptr_array_index(wanted, i); cls = entroid_request_class(entroid, name); if (!cls) { fputs(entroid->error->str, stderr); exit(1); } if (cls->oc_kind == LDAP_SCHEMA_ABSTRACT) { g_string_append(entroid->comment, "### NOTE: objectclass is abstract: "); g_string_append(entroid->comment, name); g_string_append_c(entroid->comment, '\n'); } } if (compute_entroid(entroid) == -1) { fputs(entroid->error->str, stderr); exit(1); } fputc('\n', s); fputs(entroid->comment->str, s); fprintf(s, "add %s\n", base ? base : ""); for (i = 0; i < entroid->classes->len; i++) { cls = g_ptr_array_index(entroid->classes, i); fprintf(s, "objectClass: %s\n", objectclass_name(cls)); } for (i = 0; i < entroid->must->len; i++) { at = g_ptr_array_index(entroid->must, i); if (strcmp(at->at_oid, "2.5.4.0")) fprintf(s, "%s: \n", attributetype_name(at)); } for (i = 0; i < entroid->may->len; i++) { at = g_ptr_array_index(entroid->may, i); if (strcmp(at->at_oid, "2.5.4.0")) fprintf(s, "#%s: \n", attributetype_name(at)); } entroid_free(entroid); schema_free(schema); } static void parse_file(FILE *in, tparser *p, thandler *h, void *userdata, handler_entry hentry, void *entrydata, int addp) { char *key = 0; for (;;) { long pos; if (p->peek(in, -1, &key, &pos) == -1) exit(1); if (!key) break; if (ndecimalp(key)) { tentry *entry; if (p->entry(in, pos, 0, &entry, 0) == -1) exit(1); if (hentry) hentry(key, entry, entrydata); entry_free(entry); } else { char *k = key; if (!strcmp(key, "add") && !addp) k = "replace"; if (process_immediate(p, h, userdata, in, pos, k) < 0) exit(1); } free(key); } } static int write_file_header(FILE *s, cmdline *cmdline) { int nlines = 0; if (print_binary_mode == PRINT_UTF8 && !cmdline->ldif) { fputs("# -*- coding: utf-8 -*- vim:encoding=utf-8:\n", s); nlines++; } if (cmdline->ldif) { fputs("# " RFC_2849_URL "\n" "# " MANUAL_LDIF_URL "\n", s); nlines += 2; } else { fputs("# " MANUAL_SYNTAX_URL "\n", s); nlines++; } return nlines; } static void cut_datafile(char *dataname, long pos, cmdline *cmdline) { FILE *in; FILE *out; char *tmpname = append(dataname, ".tmp"); if ( !(in = fopen(dataname, "r"))) syserr(); if ( !(out = fopen(tmpname, "w"))) syserr(); if (fseek(in, pos, SEEK_SET) == -1) syserr(); write_file_header(out, cmdline); fputc('\n', out); fcopy(in, out); if (fclose(in) == EOF) syserr(); if (fclose(out) == EOF) syserr(); rename(tmpname, dataname); free(tmpname); } static int can_seek(FILE *s) { long pos; if ( (pos = ftell(s)) == -1) return 0; if (fseek(s, pos, SEEK_SET) == -1) return 0; return 1; } static int copy_sasl_output(FILE *out, char *sasl) { struct stat st; FILE *in; int have_sharpsign = 0; int line = 0; int c; if (lstat(sasl, &st) == -1) return; if ( !(in = fopen(sasl, "r"))) syserr(); if (st.st_size > 0) { fputs("\n# SASL output:\n", out); line += 2; } for (;;) { switch ( c = getc_unlocked(in)) { case 0: case '\r': break; case '\n': if (!have_sharpsign) fputc('#', out); line++; have_sharpsign = 0; fputc(c, out); break; case EOF: if (have_sharpsign) { line++; fputc('\n', out); } if (fclose(in) == EOF) syserr(); return line; default: if (!have_sharpsign) { have_sharpsign = 1; fputs("# ", out); } fputc(c, out); } } } static GArray * main_write_files( LDAP *ld, cmdline *cmdline, char *clean, char *data, char *sasl, GPtrArray *ctrls, FILE *source, int *nlines) { FILE *s; int line; GArray *offsets; if ( !(s = fopen(data, "w"))) syserr(); line = write_file_header(s, cmdline); line += copy_sasl_output(s, sasl); if (cmdline->mode == ldapvi_mode_in) { tparser *p = &ldif_parser; thandler *h = &vdif_handler; FILE *tmp = 0; if (cmdline->in_file) { if ( !(source = fopen(cmdline->in_file, "r+"))) syserr(); } else { if (!source) source = stdin; if (!can_seek(source)) { /* einfach clean als tmpfile nehmen */ if ( !(tmp = fopen(clean, "w+"))) syserr(); fcopy(source, tmp); if (fseek(tmp, 0, SEEK_SET) == -1) syserr(); source = tmp; /* source war stdin, kann offen bleiben */ } } if (cmdline->ldif) h = &ldif_handler; if (cmdline->ldapvi) p = &ldapvi_parser; parse_file(source, p, h, s, 0, 0, cmdline->ldapmodify_add); if (cmdline->in_file) if (fclose(source) == EOF) syserr(); if (tmp) if (unlink(clean) == -1) syserr(); if (fclose(s) == EOF) syserr(); cp("/dev/null", clean, 0, 0); offsets = g_array_new(0, 0, sizeof(long)); } else if (cmdline->classes || cmdline->mode != ldapvi_mode_edit) { if (!cmdline->classes) add_changerecord(s, cmdline); else if (cmdline->classes->len) { char *base = 0; if (cmdline->basedns->len > 0) base = g_ptr_array_index(cmdline->basedns, 0); add_template(ld, s, cmdline->classes, base); } else fputc('\n', s); if (fclose(s) == EOF) syserr(); cp("/dev/null", clean, 0, 0); offsets = g_array_new(0, 0, sizeof(long)); } else { offsets = search(s, ld, cmdline, (void *) ctrls->pdata, 0, cmdline->ldif); if (fclose(s) == EOF) syserr(); cp(data, clean, 0, 0); } *nlines = line; return offsets; } static int main_loop(LDAP *ld, cmdline *cmdline, tparser *parser, GArray *offsets, char *clean, char *data, GPtrArray *ctrls, char *dir) { int changed = 1; int continuous = cmdline->continuous; for (;;) { if (changed) if (!analyze_changes( parser, offsets, clean, data, cmdline)) { write_ldapvi_history(); return 0; } changed = 0; switch (choose("Action?", "yYqQvVebB*rsf+? ", "(Type '?' for help.)")) { case 'Y': continuous = 1; /* fall through */ case 'y': commit(parser, ld, offsets, clean, data, (void *) ctrls->pdata, cmdline->verbose, 0, continuous, cmdline); changed = 1; break; /* reached only on user error */ case 'q': if (save_ldif(parser, offsets, clean, data, cmdline->server, cmdline->bind_options.user, cmdline->managedsait)) break; write_ldapvi_history(); return 0; case 'Q': write_ldapvi_history(); return 0; case 'v': view_ldif(parser, dir, offsets, clean, data); break; case 'V': view_vdif(parser, dir, offsets, clean, data); break; case 'e': edit(data, 0); changed = 1; break; case 'b': rebind(ld, &cmdline->bind_options, 1, 0, 1); changed = 1; /* print stats again */ break; case '*': change_mechanism(&cmdline->bind_options); puts("Type 'b' to log in."); break; case 'B': toggle_sasl(&cmdline->bind_options); puts("Type 'b' to log in."); break; case 'r': ldap_unbind_s(ld); ld = do_connect( cmdline->server, &cmdline->bind_options, cmdline->referrals, cmdline->starttls, cmdline->tls, cmdline->deref, 1, 0); printf("Connected to %s.\n", cmdline->server); changed = 1; /* print stats again */ break; case 's': skip(parser, data, offsets, cmdline); changed = 1; break; case 'f': forget_deletions(parser, offsets, clean, data); changed = 1; break; case '+': rewrite_comments(ld, data, cmdline); edit(data, 0); changed = 1; break; case 'L' - '@': { char *clear = tigetstr("clear"); if (clear && clear != (char *) -1) putp(clear); } break; case '?': puts("Commands:\n" " y -- commit changes\n" " Y -- commit, ignoring all errors\n" " q -- save changes as LDIF and quit\n" " Q -- discard changes and quit\n" " v -- view changes as LDIF change records\n" " V -- view changes as ldapvi change records\n" " e -- open editor again\n" " b -- show login dialog and rebind\n" " B -- toggle SASL\n" " * -- set SASL mechanism\n" " r -- reconnect to server\n" " s -- skip one entry\n" " f -- forget deletions\n" " + -- rewrite file to include schema comments\n" " ? -- this help"); break; } } } int main(int argc, const char **argv) { LDAP *ld; cmdline cmdline; GPtrArray *ctrls = g_ptr_array_new(); static char dir[] = "/tmp/ldapvi-XXXXXX"; char *clean; char *data; char *sasl; GArray *offsets; FILE *source_stream = 0; FILE *target_stream = 0; tparser *parser; int nlines; init_cmdline(&cmdline); if (argc >= 2 && !strcmp(argv[1], "--diff")) { if (argc != 4) { fputs("wrong number of arguments to --diff\n", stderr); usage(2, 1); } offline_diff(&ldapvi_parser, (char *) argv[2], (char *) argv[3]); exit(0); } parse_arguments(argc, argv, &cmdline, ctrls); if (fixup_streams(&source_stream, &target_stream) == -1) cmdline.noninteractive = 1; if (cmdline.noninteractive) { cmdline.noquestions = 1; cmdline.quiet = 1; cmdline.bind_options.dialog = BD_NEVER; } if (cmdline.ldif) parser = &ldif_parser; else parser = &ldapvi_parser; read_ldapvi_history(); setupterm(0, 1, 0); ld = do_connect(cmdline.server, &cmdline.bind_options, cmdline.referrals, cmdline.starttls, cmdline.tls, cmdline.deref, cmdline.profileonlyp, dir); if (!ld) { write_ldapvi_history(); exit(1); } if (cmdline.sortkeys) append_sort_control(ld, ctrls, cmdline.sortkeys); g_ptr_array_add(ctrls, 0); if (cmdline.discover) { if (cmdline.basedns->len > 0) yourfault("Conflicting options given:" " --base and --discover."); discover_naming_contexts(ld, cmdline.basedns); } if (cmdline.config) { write_config(ld, target_stream, &cmdline); write_ldapvi_history(); exit(0); } if (cmdline.mode == ldapvi_mode_out || (cmdline.mode == ldapvi_mode_edit && target_stream)) { if (cmdline.classes) yourfault("Cannot edit entry templates noninteractively."); if (!target_stream) target_stream = stdout; search(target_stream, ld, &cmdline, (void *) ctrls->pdata, 1, cmdline.mode == ldapvi_mode_out ? !cmdline.ldapvi : cmdline.ldif); write_ldapvi_history(); exit(0); } ensure_tmp_directory(dir); clean = append(dir, "/clean"); data = append(dir, "/data"); sasl = append(dir, "/sasl"); offsets = main_write_files( ld, &cmdline, clean, data, sasl, ctrls, source_stream, &nlines); if (!cmdline.noninteractive) { if (target_stream) { FILE *tmp = fopen(data, "r"); if (!tmp) syserr(); fcopy(tmp, target_stream); write_ldapvi_history(); exit(0); } edit(data, nlines + 1); } else if (cmdline.mode == ldapvi_mode_edit) yourfault("Cannot edit entries noninteractively."); if (cmdline.noquestions) { if (!analyze_changes(parser, offsets, clean, data, &cmdline)) { write_ldapvi_history(); return 0; } commit(parser, ld, offsets, clean, data, (void *) ctrls->pdata, cmdline.verbose, 1, cmdline.continuous, &cmdline); fputs("Error in noninteractive mode, giving up.\n", stderr); return 1; } return main_loop( ld, &cmdline, parser, offsets, clean, data, ctrls, dir); } ldapvi-1.7/mkinstalldirs0000644000175000017500000000132210617054666014414 0ustar daviddavid#! /bin/sh # mkinstalldirs --- make directory hierarchy # Author: Noah Friedman # Created: 1993-05-16 # Public domain # $Id: mkinstalldirs,v 1.13 1999/01/05 03:18:55 bje Exp $ errstatus=0 for file do set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` shift pathcomp= for d do pathcomp="$pathcomp$d" case "$pathcomp" in -* ) pathcomp=./$pathcomp ;; esac if test ! -d "$pathcomp"; then echo "mkdir $pathcomp" mkdir "$pathcomp" || lasterr=$? if test ! -d "$pathcomp"; then errstatus=$lasterr fi fi pathcomp="$pathcomp/" done done exit $errstatus # mkinstalldirs ends here ldapvi-1.7/base64.c0000644000175000017500000001705510617054666013053 0ustar daviddavid/* * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved. * COPYING RESTRICTIONS APPLY, see COPYRIGHT file */ /* * Copyright (c) 1996, 1998 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ /* * Portions Copyright (c) 1995 by International Business Machines, Inc. * * International Business Machines, Inc. (hereinafter called IBM) grants * permission under its copyrights to use, copy, modify, and distribute this * Software with or without fee, provided that the above copyright notice and * all paragraphs of this notice appear in all copies, and that the name of IBM * not be used in connection with the marketing of any product incorporating * the Software or modifications thereof, without specific, written prior * permission. * * To the extent it has a right to do so, IBM grants an immunity from suit * under its patents, if any, for the use, sale or manufacture of products to * the extent that such products are used for performing Domain Name System * dynamic updates in TCP/IP networks by means of the Software. No immunity is * granted for any product per se or for any other function of any product. * * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. */ #include #include #include #include #include "common.h" static const char Base64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; static const char Pad64 = '='; void print_base64( unsigned char const *src, size_t srclength, FILE *s) { unsigned char input[3]; unsigned char output[4]; size_t i; int col = 0; while (2 < srclength) { input[0] = *src++; input[1] = *src++; input[2] = *src++; srclength -= 3; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; if (col >= 76) { fputs("\n ", s); col = 0; } col += 4; fputc(Base64[output[0]], s); fputc(Base64[output[1]], s); fputc(Base64[output[2]], s); fputc(Base64[output[3]], s); } /* Now we worry about padding. */ if (0 != srclength) { /* Get what's left. */ input[0] = input[1] = input[2] = '\0'; for (i = 0; i < srclength; i++) input[i] = *src++; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); fputc(Base64[output[0]], s); fputc(Base64[output[1]], s); if (srclength == 1) fputc(Pad64, s); else fputc(Base64[output[2]], s); fputc(Pad64, s); } } /* na toll, copy und paste von oben */ void g_string_append_base64( GString *string, unsigned char const *src, size_t srclength) { unsigned char input[3]; unsigned char output[4]; size_t i; int col = 0; while (2 < srclength) { input[0] = *src++; input[1] = *src++; input[2] = *src++; srclength -= 3; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); output[3] = input[2] & 0x3f; if (col >= 76) { g_string_append(string, "\n "); col = 0; } col += 4; g_string_append_c(string, Base64[output[0]]); g_string_append_c(string, Base64[output[1]]); g_string_append_c(string, Base64[output[2]]); g_string_append_c(string, Base64[output[3]]); } /* Now we worry about padding. */ if (0 != srclength) { /* Get what's left. */ input[0] = input[1] = input[2] = '\0'; for (i = 0; i < srclength; i++) input[i] = *src++; output[0] = input[0] >> 2; output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); g_string_append_c(string, Base64[output[0]]); g_string_append_c(string, Base64[output[1]]); if (srclength == 1) g_string_append_c(string, Pad64); else g_string_append_c(string, Base64[output[2]]); g_string_append_c(string, Pad64); } } int read_base64( char const *src, unsigned char *target, size_t targsize) { int tarindex, state, ch; char *pos; state = 0; tarindex = 0; while ((ch = *src++) != '\0') { if (isascii(ch) && isspace(ch)) /* Skip whitespace anywhere. */ continue; if (ch == Pad64) break; pos = strchr(Base64, ch); if (pos == 0) /* A non-base64 character. */ return (-1); switch (state) { case 0: if (target) { if ((size_t)tarindex >= targsize) return (-1); target[tarindex] = (pos - Base64) << 2; } state = 1; break; case 1: if (target) { if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= (pos - Base64) >> 4; target[tarindex+1] = ((pos - Base64) & 0x0f) << 4 ; } tarindex++; state = 2; break; case 2: if (target) { if ((size_t)tarindex + 1 >= targsize) return (-1); target[tarindex] |= (pos - Base64) >> 2; target[tarindex+1] = ((pos - Base64) & 0x03) << 6; } tarindex++; state = 3; break; case 3: if (target) { if ((size_t)tarindex >= targsize) return (-1); target[tarindex] |= (pos - Base64); } tarindex++; state = 0; break; default: abort(); } } /* * We are done decoding Base-64 chars. Let's see if we ended * on a byte boundary, and/or with erroneous trailing characters. */ if (ch == Pad64) { /* We got a pad char. */ ch = *src++; /* Skip it, get next. */ switch (state) { case 0: /* Invalid = in first position */ case 1: /* Invalid = in second position */ return (-1); case 2: /* Valid, means one byte of info */ /* Skip any number of spaces. */ for ((void)NULL; ch != '\0'; ch = *src++) if (! (isascii(ch) && isspace(ch))) break; /* Make sure there is another trailing = sign. */ if (ch != Pad64) return (-1); ch = *src++; /* Skip the = */ /* Fall through to "single trailing =" case. */ /* FALLTHROUGH */ case 3: /* Valid, means two bytes of info */ /* * We know this char is an =. Is there anything but * whitespace after it? */ for ((void)NULL; ch != '\0'; ch = *src++) if (! (isascii(ch) && isspace(ch))) return (-1); /* * Now make sure for cases 2 and 3 that the "extra" * bits that slopped past the last full byte were * zeros. If we don't check them, they become a * subliminal channel. */ if (target && target[tarindex] != 0) return (-1); } } else { /* * We ended by seeing the end of the string. Make sure we * have no partial bytes lying around. */ if (state != 0) return (-1); } return (tarindex); } ldapvi-1.7/autogen.sh0000755000175000017500000000005110617054666013610 0ustar daviddavid#!/bin/sh autoconf rm -rf autom4te.cache