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

Annotation of src/usr.bin/rup/rup.c, Revision 1.1

1.1     ! deraadt     1: /*-
        !             2:  * Copyright (c) 1993, John Brezak
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  * 3. All advertising materials mentioning features or use of this software
        !            14:  *    must display the following acknowledgement:
        !            15:  *     This product includes software developed by the University of
        !            16:  *     California, Berkeley and its contributors.
        !            17:  * 4. Neither the name of the University nor the names of its contributors
        !            18:  *    may be used to endorse or promote products derived from this software
        !            19:  *    without specific prior written permission.
        !            20:  *
        !            21:  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
        !            22:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
        !            23:  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
        !            24:  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
        !            25:  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
        !            26:  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
        !            27:  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
        !            28:  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
        !            29:  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
        !            30:  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
        !            31:  * SUCH DAMAGE.
        !            32:  */
        !            33:
        !            34: #ifndef lint
        !            35: static char rcsid[] = "$Id: rup.c,v 1.10 1994/02/05 14:58:14 pk Exp $";
        !            36: #endif /* not lint */
        !            37:
        !            38: #include <stdio.h>
        !            39: #include <stdlib.h>
        !            40: #include <string.h>
        !            41: #include <time.h>
        !            42: #include <sys/param.h>
        !            43: #include <sys/socket.h>
        !            44: #include <netdb.h>
        !            45: #include <rpc/rpc.h>
        !            46: #include <arpa/inet.h>
        !            47: #include <err.h>
        !            48:
        !            49: #undef FSHIFT                  /* Use protocol's shift and scale values */
        !            50: #undef FSCALE
        !            51: #include <rpcsvc/rstat.h>
        !            52:
        !            53: #define HOST_WIDTH 24
        !            54:
        !            55: int printtime;                 /* print the remote host(s)'s time */
        !            56:
        !            57: struct host_list {
        !            58:        struct host_list *next;
        !            59:        struct in_addr addr;
        !            60: } *hosts;
        !            61:
        !            62: int
        !            63: search_host(addr)
        !            64:        struct in_addr addr;
        !            65: {
        !            66:        struct host_list *hp;
        !            67:
        !            68:        if (!hosts)
        !            69:                return(0);
        !            70:
        !            71:        for (hp = hosts; hp != NULL; hp = hp->next) {
        !            72:                if (hp->addr.s_addr == addr.s_addr)
        !            73:                        return(1);
        !            74:        }
        !            75:        return(0);
        !            76: }
        !            77:
        !            78: void
        !            79: remember_host(addr)
        !            80:        struct in_addr addr;
        !            81: {
        !            82:        struct host_list *hp;
        !            83:
        !            84:        if (!(hp = (struct host_list *)malloc(sizeof(struct host_list)))) {
        !            85:                err(1, NULL);
        !            86:                /* NOTREACHED */
        !            87:        }
        !            88:        hp->addr.s_addr = addr.s_addr;
        !            89:        hp->next = hosts;
        !            90:        hosts = hp;
        !            91: }
        !            92:
        !            93:
        !            94: 
        !            95: struct rup_data {
        !            96:        char *host;
        !            97:        struct statstime statstime;
        !            98: };
        !            99: struct rup_data *rup_data;
        !           100: int rup_data_idx = 0;
        !           101: int rup_data_max = 0;
        !           102:
        !           103: enum sort_type {
        !           104:        SORT_NONE,
        !           105:        SORT_HOST,
        !           106:        SORT_LDAV,
        !           107:        SORT_UPTIME
        !           108: };
        !           109: enum sort_type sort_type;
        !           110:
        !           111: compare(d1, d2)
        !           112:        struct rup_data *d1;
        !           113:        struct rup_data *d2;
        !           114: {
        !           115:        switch(sort_type) {
        !           116:        case SORT_HOST:
        !           117:                return strcmp(d1->host, d2->host);
        !           118:        case SORT_LDAV:
        !           119:                return d1->statstime.avenrun[0]
        !           120:                        - d2->statstime.avenrun[0];
        !           121:        case SORT_UPTIME:
        !           122:                return d1->statstime.boottime.tv_sec
        !           123:                        - d2->statstime.boottime.tv_sec;
        !           124:        default:
        !           125:                /* something's really wrong here */
        !           126:                abort();
        !           127:        }
        !           128: }
        !           129:
        !           130: void
        !           131: remember_rup_data(host, st)
        !           132:        char *host;
        !           133:        struct statstime *st;
        !           134: {
        !           135:         if (rup_data_idx >= rup_data_max) {
        !           136:                 rup_data_max += 16;
        !           137:                 rup_data = realloc (rup_data,
        !           138:                                rup_data_max * sizeof(struct rup_data));
        !           139:                 if (rup_data == NULL) {
        !           140:                         err (1, NULL);
        !           141:                        /* NOTREACHED */
        !           142:                 }
        !           143:         }
        !           144:
        !           145:        rup_data[rup_data_idx].host = strdup(host);
        !           146:        rup_data[rup_data_idx].statstime = *st;
        !           147:        rup_data_idx++;
        !           148: }
        !           149:
        !           150:
        !           151: int
        !           152: rstat_reply(replyp, raddrp)
        !           153:        char *replyp;
        !           154:        struct sockaddr_in *raddrp;
        !           155: {
        !           156:        struct hostent *hp;
        !           157:        char *host;
        !           158:        statstime *host_stat = (statstime *)replyp;
        !           159:
        !           160:        if (!search_host(raddrp->sin_addr)) {
        !           161:                hp = gethostbyaddr((char *)&raddrp->sin_addr.s_addr,
        !           162:                        sizeof(struct in_addr), AF_INET);
        !           163:
        !           164:                if (hp)
        !           165:                        host = hp->h_name;
        !           166:                else
        !           167:                        host = inet_ntoa(raddrp->sin_addr);
        !           168:
        !           169:                remember_host(raddrp->sin_addr);
        !           170:
        !           171:                if (sort_type != SORT_NONE) {
        !           172:                        remember_rup_data(host, host_stat);
        !           173:                } else {
        !           174:                        print_rup_data(host, host_stat);
        !           175:                }
        !           176:        }
        !           177:
        !           178:        return (0);
        !           179: }
        !           180:
        !           181:
        !           182: int
        !           183: print_rup_data(host, host_stat)
        !           184:        char *host;
        !           185:        statstime *host_stat;
        !           186: {
        !           187:        struct tm *tmp_time;
        !           188:        struct tm host_time;
        !           189:        struct tm host_uptime;
        !           190:        char days_buf[16];
        !           191:        char hours_buf[16];
        !           192:
        !           193:        printf("%-*.*s", HOST_WIDTH, HOST_WIDTH, host);
        !           194:
        !           195:        tmp_time = localtime((time_t *)&host_stat->curtime.tv_sec);
        !           196:        host_time = *tmp_time;
        !           197:
        !           198:        host_stat->curtime.tv_sec -= host_stat->boottime.tv_sec;
        !           199:
        !           200:        tmp_time = gmtime((time_t *)&host_stat->curtime.tv_sec);
        !           201:        host_uptime = *tmp_time;
        !           202:
        !           203:        if (host_uptime.tm_yday != 0)
        !           204:                sprintf(days_buf, "%3d day%s, ", host_uptime.tm_yday,
        !           205:                        (host_uptime.tm_yday > 1) ? "s" : "");
        !           206:        else
        !           207:                days_buf[0] = '\0';
        !           208:
        !           209:        if (host_uptime.tm_hour != 0)
        !           210:                sprintf(hours_buf, "%2d:%02d, ",
        !           211:                        host_uptime.tm_hour, host_uptime.tm_min);
        !           212:        else
        !           213:                if (host_uptime.tm_min != 0)
        !           214:                        sprintf(hours_buf, "%2d mins, ", host_uptime.tm_min);
        !           215:                else
        !           216:                        hours_buf[0] = '\0';
        !           217:
        !           218:        if (printtime)
        !           219:                printf(" %2d:%02d%cm", host_time.tm_hour % 12,
        !           220:                        host_time.tm_min,
        !           221:                        (host_time.tm_hour >= 12) ? 'p' : 'a');
        !           222:
        !           223:        printf(" up %9.9s%9.9s load average: %.2f %.2f %.2f\n",
        !           224:                days_buf, hours_buf,
        !           225:                (double)host_stat->avenrun[0]/FSCALE,
        !           226:                (double)host_stat->avenrun[1]/FSCALE,
        !           227:                (double)host_stat->avenrun[2]/FSCALE);
        !           228:
        !           229:        return(0);
        !           230: }
        !           231:
        !           232:
        !           233: void
        !           234: onehost(host)
        !           235:        char *host;
        !           236: {
        !           237:        CLIENT *rstat_clnt;
        !           238:        statstime host_stat;
        !           239:        static struct timeval timeout = {25, 0};
        !           240:
        !           241:        rstat_clnt = clnt_create(host, RSTATPROG, RSTATVERS_TIME, "udp");
        !           242:        if (rstat_clnt == NULL) {
        !           243:                warnx("%s", clnt_spcreateerror(host));
        !           244:                return;
        !           245:        }
        !           246:
        !           247:        bzero((char *)&host_stat, sizeof(host_stat));
        !           248:        if (clnt_call(rstat_clnt, RSTATPROC_STATS, xdr_void, NULL, xdr_statstime, &host_stat, timeout) != RPC_SUCCESS) {
        !           249:                warnx("%s",  clnt_sperror(rstat_clnt, host));
        !           250:                return;
        !           251:        }
        !           252:
        !           253:        print_rup_data(host, &host_stat);
        !           254:        clnt_destroy(rstat_clnt);
        !           255: }
        !           256:
        !           257: void
        !           258: allhosts()
        !           259: {
        !           260:        statstime host_stat;
        !           261:        enum clnt_stat clnt_stat;
        !           262:        size_t i;
        !           263:
        !           264:        if (sort_type != SORT_NONE) {
        !           265:                printf("collecting responses...");
        !           266:                fflush(stdout);
        !           267:        }
        !           268:
        !           269:        clnt_stat = clnt_broadcast(RSTATPROG, RSTATVERS_TIME, RSTATPROC_STATS,
        !           270:                                   xdr_void, NULL,
        !           271:                                   xdr_statstime, &host_stat, rstat_reply);
        !           272:        if (clnt_stat != RPC_SUCCESS && clnt_stat != RPC_TIMEDOUT) {
        !           273:                warnx("%s", clnt_sperrno(clnt_stat));
        !           274:                exit(1);
        !           275:        }
        !           276:
        !           277:        if (sort_type != SORT_NONE) {
        !           278:                putchar('\n');
        !           279:                qsort(rup_data, rup_data_idx, sizeof(struct rup_data), compare);
        !           280:
        !           281:                for (i = 0; i < rup_data_idx; i++) {
        !           282:                        print_rup_data(rup_data[i].host, &rup_data[i].statstime);
        !           283:                }
        !           284:        }
        !           285: }
        !           286:
        !           287:
        !           288: main(argc, argv)
        !           289:        int argc;
        !           290:        char *argv[];
        !           291: {
        !           292:        int ch;
        !           293:        extern int optind;
        !           294:
        !           295:        sort_type = SORT_NONE;
        !           296:        while ((ch = getopt(argc, argv, "dhlt")) != -1)
        !           297:                switch (ch) {
        !           298:                case 'd':
        !           299:                        printtime = 1;
        !           300:                        break;
        !           301:                case 'h':
        !           302:                        sort_type = SORT_HOST;
        !           303:                        break;
        !           304:                case 'l':
        !           305:                        sort_type = SORT_LDAV;
        !           306:                        break;
        !           307:                case 't':
        !           308:                        sort_type = SORT_UPTIME;
        !           309:                        break;
        !           310:                default:
        !           311:                        usage();
        !           312:                        /*NOTREACHED*/
        !           313:                }
        !           314:
        !           315:        setlinebuf(stdout);
        !           316:
        !           317:        if (argc == optind)
        !           318:                allhosts();
        !           319:        else {
        !           320:                for (; optind < argc; optind++)
        !           321:                        onehost(argv[optind]);
        !           322:        }
        !           323:
        !           324:        exit(0);
        !           325: }
        !           326:
        !           327:
        !           328: usage()
        !           329: {
        !           330:        fprintf(stderr, "Usage: rup [-dhlt] [hosts ...]\n");
        !           331:        exit(1);
        !           332: }