/* af2j 10/1/91 most of this code stolen from ka9q NOS.
 *
 *	Reboot NOS machines from a Unix machine.
 *
 * This code hasn't been extensively tested, but seems to work on
 * bsd-style machines.
 *
 * Joe Reinhardt
 * Department of Electrical Engineering
 * Pennsylvania State University
 * State College, PA  16801
 *
 * Office:    204 EEE
 * Telephone: 814-863-1340
 *
 * email:   jmr@ecl.psu.edu (preferred)
 * and:     jmr@af2j.ampr.org (AMPR 44.80.32.135)
 */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <netdb.h>
#include <strings.h>
#include <memory.h>

#define SOCK_NUM 1234 /* the default socket number */
#define SYS_RESET       1
#define SYS_EXIT        2
#define KICK_ME         3

struct sockaddr_in server;
struct hostent *hp;
int sock;

char *prog;
char *usage = "Usage: remote [-p port] [-a address] [-k key] <host> reset|exit|k
ickme";

extern char *optarg;
extern int optind, opterr;

main(argc, argv)
        int argc;
        char *argv[];
{
        int port = SOCK_NUM;
        char *data;
        char *cmd;
        char *key = '\0';
        int c, klen, len;
        char *hostname = '\0';
        char *remhost = '\0';

        prog = argv[0];

        optind = 1;
        while ((c = getopt(argc,argv,"a:p:k:")) != EOF) {
                switch (c) {
                case 'a':
                        remhost = optarg;
                        break;
                case 'p':
                        port = atoi(optarg);
                        break;
                case 'k':
                        key = optarg;
                        klen = strlen(key);
                        break;
                } /* switch */
        } /* while */

        if (optind > argc - 2) {
                fprintf(stderr,"%s\n",usage);
                exit(-1);
                }

        hostname = argv[optind++];
        cmd = argv[optind];

        hp = gethostbyname(hostname);
        if (hp == NULL) {
                fprintf(stderr,"%s: %s unknown host\n", prog,
hostname);
                exit (1);
                }

        bzero((char *)&server, sizeof(server));
        bcopy(hp->h_addr, (char *)&server.sin_addr, hp->h_length);
        server.sin_family = hp->h_addrtype;
        server.sin_port = htons(port);

        if (remhost) {
        hp = gethostbyname(remhost);
        if (hp == NULL) {
                fprintf(stderr,"%s: %s unknown host\n", prog, optarg);
                exit (1);
                } /* if */
        }

        sock = socket(AF_INET, SOCK_DGRAM, 0);
        if (sock < 0) {
                perror("socket open failed");
                exit (2);
                }

        len = 1;

        if (remhost)
                len += hp->h_length;
        if (key)
                len += klen;

        data = (char *)malloc(len);

        switch (cmd[0]) {
        case 'r':
                data[0] = SYS_RESET;
                if (key)
                        strncpy(&data[1],key,klen);
                break;
        case 'e':
                data[0] = SYS_EXIT;
                if (key)
                        strncpy(&data[1],key,klen);
                break;
        case 'k':
                data[0] = KICK_ME;
                if (remhost)
                        bcopy(hp->h_addr, &data[1],
hp->h_length);
                break;
        default:
                fprintf(stderr,"%s: unknown command %s\n",prog,cmd);
                exit(-1);
        } /* switch */

        if (sendto(sock, data, len, 0, &server, sizeof(server)) == -1)
{
                fprintf(stderr,"%s: sendto failed\n",prog);
                exit(-1);
                }

        free(data);

        close(sock);

        exit (0);

} /* main */




