[BACK]Return to getent.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / getent

Annotation of src/usr.bin/getent/getent.c, Revision 1.2

1.2     ! deraadt     1: /*     $OpenBSD$       */
1.1       otto        2: /*     $NetBSD: getent.c,v 1.7 2005/08/24 14:31:02 ginsbach Exp $      */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2004 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Luke Mewburn.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the NetBSD
                     22:  *     Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/types.h>
                     41: #include <sys/socket.h>
                     42:
                     43: #include <ctype.h>
                     44: #include <errno.h>
                     45: #include <grp.h>
                     46: #include <limits.h>
                     47: #include <netdb.h>
                     48: #include <pwd.h>
                     49: #include <stdio.h>
                     50: #include <stdarg.h>
                     51: #include <stdlib.h>
                     52: #include <string.h>
                     53: #include <unistd.h>
                     54:
                     55: #include <arpa/inet.h>
                     56: #include <arpa/nameser.h>
                     57:
                     58: #include <net/if.h>
                     59: #include <netinet/in.h>                /* for INET6_ADDRSTRLEN */
                     60: #include <netinet/if_ether.h>
                     61:
                     62: #include <rpc/rpc.h>
                     63:
                     64: static int     usage(void);
                     65: static int     ethers(int, char *[]);
                     66: static int     group(int, char *[]);
                     67: static int     hosts(int, char *[]);
                     68: static int     networks(int, char *[]);
                     69: static int     passwd(int, char *[]);
                     70: static int     protocols(int, char *[]);
                     71: static int     rpc(int, char *[]);
                     72: static int     services(int, char *[]);
                     73: static int     shells(int, char *[]);
1.2     ! deraadt    74: extern char *__progname;
1.1       otto       75:
                     76: enum {
                     77:        RV_OK           = 0,
                     78:        RV_USAGE        = 1,
                     79:        RV_NOTFOUND     = 2,
1.2     ! deraadt    80:        RV_NOENUM       = 3
1.1       otto       81: };
                     82:
                     83: static struct getentdb {
                     84:        const char      *name;
1.2     ! deraadt    85:        int             (*fn)(int, char *[]);
1.1       otto       86: } databases[] = {
                     87:        {       "ethers",       ethers,         },
                     88:        {       "group",        group,          },
                     89:        {       "hosts",        hosts,          },
                     90:        {       "networks",     networks,       },
                     91:        {       "passwd",       passwd,         },
                     92:        {       "protocols",    protocols,      },
                     93:        {       "rpc",          rpc,            },
                     94:        {       "services",     services,       },
                     95:        {       "shells",       shells,         },
                     96:
                     97:        {       NULL,           NULL,           },
                     98: };
                     99:
                    100: int
                    101: main(int argc, char *argv[])
                    102: {
                    103:        struct getentdb *curdb;
                    104:
                    105:        if (argc < 2)
                    106:                usage();
                    107:        for (curdb = databases; curdb->name != NULL; curdb++) {
                    108:                if (strcmp(curdb->name, argv[1]) == 0) {
1.2     ! deraadt   109:                        exit(curdb->fn(argc, argv));
1.1       otto      110:                        break;
                    111:                }
                    112:        }
1.2     ! deraadt   113:        fprintf(stderr, "%s: unknown database: %s\n", __progname, argv[1]);
1.1       otto      114:        return RV_USAGE;
                    115: }
                    116:
                    117: static int
                    118: usage(void)
                    119: {
1.2     ! deraadt   120:        fprintf(stderr, "usage: %s database [key ...]\n", __progname);
1.1       otto      121:        exit(RV_USAGE);
                    122:        /* NOTREACHED */
                    123: }
                    124:
                    125: /*
                    126:  * printfmtstrings --
                    127:  *     vprintf(format, ...),
                    128:  *     then the aliases (beginning with prefix, separated by sep),
                    129:  *     then a newline
                    130:  */
                    131: static void
                    132: printfmtstrings(char *strings[], const char *prefix, const char *sep,
                    133:        const char *fmt, ...)
                    134: {
                    135:        va_list         ap;
                    136:        const char      *curpref;
                    137:        int             i;
                    138:
                    139:        va_start(ap, fmt);
                    140:        vprintf(fmt, ap);
1.2     ! deraadt   141:        va_end(ap);
1.1       otto      142:
                    143:        curpref = prefix;
                    144:        for (i = 0; strings[i] != NULL; i++) {
                    145:                printf("%s%s", curpref, strings[i]);
                    146:                curpref = sep;
                    147:        }
                    148:        printf("\n");
                    149: }
                    150:
1.2     ! deraadt   151: #define ETHERSPRINT    printf("%-17s  %s\n", ether_ntoa(eap), hp)
1.1       otto      152:
                    153: static int
                    154: ethers(int argc, char *argv[])
                    155: {
1.2     ! deraadt   156:        char            hostname[MAXHOSTNAMELEN], *hp;
        !           157:        int             i, rv = RV_OK;
1.1       otto      158:        struct ether_addr ea, *eap;
                    159:
                    160:        if (argc == 2) {
1.2     ! deraadt   161:                fprintf(stderr, "%s: Enumeration not supported on ethers\n",
        !           162:                    __progname);
1.1       otto      163:                rv = RV_NOENUM;
                    164:        } else {
                    165:                for (i = 2; i < argc; i++) {
                    166:                        if ((eap = ether_aton(argv[i])) == NULL) {
                    167:                                eap = &ea;
                    168:                                hp = argv[i];
                    169:                                if (ether_hostton(hp, eap) != 0) {
                    170:                                        rv = RV_NOTFOUND;
                    171:                                        break;
                    172:                                }
                    173:                        } else {
                    174:                                hp = hostname;
                    175:                                if (ether_ntohost(hp, eap) != 0) {
                    176:                                        rv = RV_NOTFOUND;
                    177:                                        break;
                    178:                                }
                    179:                        }
                    180:                        ETHERSPRINT;
                    181:                }
                    182:        }
                    183:        return rv;
                    184: }
                    185:
1.2     ! deraadt   186: #define GROUPPRINT     \
        !           187:        printfmtstrings(gr->gr_mem, ":", ",", "%s:%s:%u", \
        !           188:            gr->gr_name, gr->gr_passwd, gr->gr_gid)
1.1       otto      189:
                    190: static int
                    191: group(int argc, char *argv[])
                    192: {
1.2     ! deraadt   193:        int             i, rv = RV_OK;
1.1       otto      194:        struct group    *gr;
                    195:
                    196:        setgroupent(1);
                    197:        if (argc == 2) {
                    198:                while ((gr = getgrent()) != NULL)
                    199:                        GROUPPRINT;
                    200:        } else {
                    201:                for (i = 2; i < argc; i++) {
1.2     ! deraadt   202:                        const char      *err;
        !           203:                        long long id = strtonum(argv[i], 0, UINT_MAX, &err);
        !           204:
        !           205:                        if (!err)
1.1       otto      206:                                gr = getgrgid((gid_t)id);
                    207:                        else
                    208:                                gr = getgrnam(argv[i]);
                    209:                        if (gr != NULL)
                    210:                                GROUPPRINT;
                    211:                        else {
                    212:                                rv = RV_NOTFOUND;
                    213:                                break;
                    214:                        }
                    215:                }
                    216:        }
                    217:        endgrent();
                    218:        return rv;
                    219: }
                    220:
                    221: static void
                    222: hostsprint(const struct hostent *he)
                    223: {
                    224:        char    buf[INET6_ADDRSTRLEN];
                    225:
                    226:        if (inet_ntop(he->h_addrtype, he->h_addr, buf, sizeof(buf)) == NULL)
                    227:                strlcpy(buf, "# unknown", sizeof(buf));
                    228:        printfmtstrings(he->h_aliases, "  ", " ", "%-16s  %s", buf, he->h_name);
                    229: }
                    230:
                    231: static int
                    232: hosts(int argc, char *argv[])
                    233: {
1.2     ! deraadt   234:        char            addr[IN6ADDRSZ];
        !           235:        int             i, rv = RV_OK;
1.1       otto      236:        struct hostent  *he;
                    237:
                    238:        sethostent(1);
                    239:        if (argc == 2) {
                    240:                while ((he = gethostent()) != NULL)
                    241:                        hostsprint(he);
                    242:        } else {
                    243:                for (i = 2; i < argc; i++) {
                    244:                        if (inet_pton(AF_INET6, argv[i], (void *)addr) > 0)
                    245:                                he = gethostbyaddr(addr, IN6ADDRSZ, AF_INET6);
                    246:                        else if (inet_pton(AF_INET, argv[i], (void *)addr) > 0)
                    247:                                he = gethostbyaddr(addr, INADDRSZ, AF_INET);
                    248:                        else
                    249:                                he = gethostbyname(argv[i]);
                    250:                        if (he != NULL)
                    251:                                hostsprint(he);
                    252:                        else {
                    253:                                rv = RV_NOTFOUND;
                    254:                                break;
                    255:                        }
                    256:                }
                    257:        }
                    258:        endhostent();
                    259:        return rv;
                    260: }
                    261:
                    262: static void
                    263: networksprint(const struct netent *ne)
                    264: {
                    265:        char            buf[INET6_ADDRSTRLEN];
1.2     ! deraadt   266:        struct in_addr  ianet;
1.1       otto      267:
                    268:        ianet = inet_makeaddr(ne->n_net, 0);
                    269:        if (inet_ntop(ne->n_addrtype, &ianet, buf, sizeof(buf)) == NULL)
                    270:                strlcpy(buf, "# unknown", sizeof(buf));
                    271:        printfmtstrings(ne->n_aliases, "  ", " ", "%-16s  %s", ne->n_name, buf);
                    272: }
                    273:
                    274: static int
                    275: networks(int argc, char *argv[])
                    276: {
1.2     ! deraadt   277:        int             i, rv = RV_OK;
1.1       otto      278:        struct netent   *ne;
                    279:        in_addr_t       net;
                    280:
                    281:        setnetent(1);
                    282:        if (argc == 2) {
                    283:                while ((ne = getnetent()) != NULL)
                    284:                        networksprint(ne);
                    285:        } else {
                    286:                for (i = 2; i < argc; i++) {
                    287:                        net = inet_network(argv[i]);
                    288:                        if (net != INADDR_NONE)
                    289:                                ne = getnetbyaddr(net, AF_INET);
                    290:                        else
                    291:                                ne = getnetbyname(argv[i]);
                    292:                        if (ne != NULL)
                    293:                                networksprint(ne);
                    294:                        else {
                    295:                                rv = RV_NOTFOUND;
                    296:                                break;
                    297:                        }
                    298:                }
                    299:        }
                    300:        endnetent();
                    301:        return rv;
                    302: }
                    303:
1.2     ! deraadt   304: #define PASSWDPRINT    \
        !           305:        printf("%s:%s:%u:%u:%s:%s:%s\n", \
        !           306:            pw->pw_name, pw->pw_passwd, pw->pw_uid, \
        !           307:            pw->pw_gid, pw->pw_gecos, pw->pw_dir, pw->pw_shell)
1.1       otto      308:
                    309: static int
                    310: passwd(int argc, char *argv[])
                    311: {
1.2     ! deraadt   312:        int             i, rv = RV_OK;
1.1       otto      313:        struct passwd   *pw;
                    314:
                    315:        setpassent(1);
                    316:        if (argc == 2) {
                    317:                while ((pw = getpwent()) != NULL)
                    318:                        PASSWDPRINT;
                    319:        } else {
                    320:                for (i = 2; i < argc; i++) {
1.2     ! deraadt   321:                        const char      *err;
        !           322:                        long long id = strtonum(argv[i], 0, UINT_MAX, &err);
        !           323:
        !           324:                        if (!err)
1.1       otto      325:                                pw = getpwuid((uid_t)id);
                    326:                        else
                    327:                                pw = getpwnam(argv[i]);
                    328:                        if (pw != NULL)
                    329:                                PASSWDPRINT;
                    330:                        else {
                    331:                                rv = RV_NOTFOUND;
                    332:                                break;
                    333:                        }
                    334:                }
                    335:        }
                    336:        endpwent();
                    337:        return rv;
                    338: }
                    339:
1.2     ! deraadt   340: #define PROTOCOLSPRINT \
        !           341:        printfmtstrings(pe->p_aliases, "  ", " ", \
        !           342:            "%-16s  %5d", pe->p_name, pe->p_proto)
1.1       otto      343:
                    344: static int
                    345: protocols(int argc, char *argv[])
                    346: {
                    347:        struct protoent *pe;
1.2     ! deraadt   348:        int             i, rv = RV_OK;
1.1       otto      349:
                    350:        setprotoent(1);
                    351:        if (argc == 2) {
                    352:                while ((pe = getprotoent()) != NULL)
                    353:                        PROTOCOLSPRINT;
                    354:        } else {
                    355:                for (i = 2; i < argc; i++) {
1.2     ! deraadt   356:                        const char      *err;
        !           357:                        long long id = strtonum(argv[i], 0, UINT_MAX, &err);
        !           358:
        !           359:                        if (!err)
1.1       otto      360:                                pe = getprotobynumber((int)id);
                    361:                        else
                    362:                                pe = getprotobyname(argv[i]);
                    363:                        if (pe != NULL)
                    364:                                PROTOCOLSPRINT;
                    365:                        else {
                    366:                                rv = RV_NOTFOUND;
                    367:                                break;
                    368:                        }
                    369:                }
                    370:        }
                    371:        endprotoent();
                    372:        return rv;
                    373: }
                    374:
1.2     ! deraadt   375: #define RPCPRINT       \
        !           376:        printfmtstrings(re->r_aliases, "  ", " ", \
        !           377:            "%-16s  %6d", re->r_name, re->r_number)
1.1       otto      378:
                    379: static int
                    380: rpc(int argc, char *argv[])
                    381: {
                    382:        struct rpcent   *re;
1.2     ! deraadt   383:        int             i, rv = RV_OK;
1.1       otto      384:
                    385:        setrpcent(1);
                    386:        if (argc == 2) {
                    387:                while ((re = getrpcent()) != NULL)
                    388:                        RPCPRINT;
                    389:        } else {
                    390:                for (i = 2; i < argc; i++) {
1.2     ! deraadt   391:                        const char      *err;
        !           392:                        long long id = strtonum(argv[i], 0, UINT_MAX, &err);
        !           393:
        !           394:                        if (!err)
1.1       otto      395:                                re = getrpcbynumber((int)id);
                    396:                        else
                    397:                                re = getrpcbyname(argv[i]);
                    398:                        if (re != NULL)
                    399:                                RPCPRINT;
                    400:                        else {
                    401:                                rv = RV_NOTFOUND;
                    402:                                break;
                    403:                        }
                    404:                }
                    405:        }
                    406:        endrpcent();
                    407:        return rv;
                    408: }
                    409:
1.2     ! deraadt   410: #define SERVICESPRINT  \
        !           411:        printfmtstrings(se->s_aliases, "  ", " ", \
        !           412:            "%-16s  %5d/%s", se->s_name, ntohs(se->s_port), se->s_proto)
1.1       otto      413:
                    414: static int
                    415: services(int argc, char *argv[])
                    416: {
                    417:        struct servent  *se;
1.2     ! deraadt   418:        int             i, rv = RV_OK;
1.1       otto      419:
                    420:        setservent(1);
                    421:        if (argc == 2) {
                    422:                while ((se = getservent()) != NULL)
                    423:                        SERVICESPRINT;
                    424:        } else {
                    425:                for (i = 2; i < argc; i++) {
1.2     ! deraadt   426:                        const char      *err;
        !           427:                        long long       id;
        !           428:                        char *proto = strchr(argv[i], '/');
        !           429:
1.1       otto      430:                        if (proto != NULL)
                    431:                                *proto++ = '\0';
1.2     ! deraadt   432:                        id = strtonum(argv[i], 0, UINT_MAX, &err);
        !           433:                        if (!err)
1.1       otto      434:                                se = getservbyport((int)id, proto);
                    435:                        else
                    436:                                se = getservbyname(argv[i], proto);
                    437:                        if (se != NULL)
                    438:                                SERVICESPRINT;
                    439:                        else {
                    440:                                rv = RV_NOTFOUND;
                    441:                                break;
                    442:                        }
                    443:                }
                    444:        }
                    445:        endservent();
                    446:        return rv;
                    447: }
                    448:
1.2     ! deraadt   449: #define SHELLSPRINT    printf("%s\n", sh)
1.1       otto      450:
                    451: static int
                    452: shells(int argc, char *argv[])
                    453: {
                    454:        const char      *sh;
1.2     ! deraadt   455:        int             i, rv = RV_OK;
1.1       otto      456:
                    457:        setusershell();
                    458:        if (argc == 2) {
                    459:                while ((sh = getusershell()) != NULL)
                    460:                        SHELLSPRINT;
                    461:        } else {
                    462:                for (i = 2; i < argc; i++) {
                    463:                        setusershell();
                    464:                        while ((sh = getusershell()) != NULL) {
                    465:                                if (strcmp(sh, argv[i]) == 0) {
                    466:                                        SHELLSPRINT;
                    467:                                        break;
                    468:                                }
                    469:                        }
                    470:                        if (sh == NULL) {
                    471:                                rv = RV_NOTFOUND;
                    472:                                break;
                    473:                        }
                    474:                }
                    475:        }
                    476:        endusershell();
                    477:        return rv;
                    478: }