aboutsummaryrefslogtreecommitdiffstats
path: root/erts/epmd/src/epmd_cli.c
blob: c12f711bc55709a4dd51ca1c78693971a048af7c (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
/*
 * %CopyrightBegin%
 * 
 * Copyright Ericsson AB 1998-2009. All Rights Reserved.
 * 
 * The contents of this file are subject to the Erlang Public License,
 * Version 1.1, (the "License"); you may not use this file except in
 * compliance with the License. You should have received a copy of the
 * Erlang Public License along with this software. If not, it can be
 * retrieved online at http://www.erlang.org/.
 * 
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
 * the License for the specific language governing rights and limitations
 * under the License.
 * 
 * %CopyrightEnd%
 */

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif
#include "epmd.h"     /* Renamed from 'epmd_r4.h' */
#include "epmd_int.h"

/* forward declarations */

static int conn_to_epmd(EpmdVars*);
static int read_fill(int,char*,int);


void kill_epmd(EpmdVars *g)
{
    char buf[5];
    int fd, rval;

    fd = conn_to_epmd(g);
    put_int16(1,buf);
    buf[2] = EPMD_KILL_REQ;
    if (write(fd, buf, 3) != 3) {
	printf("epmd: Can't write to epmd\n");
	epmd_cleanup_exit(g,1);
    }
    if ((rval = read_fill(fd,buf,2)) == 2) {
	printf("Killed\n");
	epmd_cleanup_exit(g,0);
    } else if (rval < 0) {
	printf("epmd: failed to read answer from local epmd\n");
	epmd_cleanup_exit(g,1);
    } else { 			/* rval is now 0 or 1 */
	buf[rval] = '\0';
	printf("epmd: local epmd responded with <%s>\n", buf);
	epmd_cleanup_exit(g,1);
    }
}

/* what == EPMD_NAMES_REQ || EPMD_DUMP_REQ */

void epmd_call(EpmdVars *g,int what)
{
    char buf[OUTBUF_SIZE];
    int rval,fd,i,j;
    
    fd = conn_to_epmd(g);
    put_int16(1,buf);
    buf[2] = what;
    write(fd,buf,3);
    if (read(fd,(char *)&i,4) != 4) {
	if (!g->silent)
	    printf("epmd: no response from local epmd\n");
	epmd_cleanup_exit(g,1);
    }
    j = ntohl(i);
    if (!g->silent)
	printf("epmd: up and running on port %d with data:\n", j);
    while(1) {
	if ((rval = read(fd,buf,1)) <= 0)  {
	    close(fd);
	    epmd_cleanup_exit(g,0);
	}
	buf[rval] = '\0';
	if (!g->silent)
	    printf("%s",buf);
    }
}



static int conn_to_epmd(EpmdVars *g)
{
    struct EPMD_SOCKADDR_IN address;
    int connect_sock;
    
    connect_sock = socket(FAMILY, SOCK_STREAM, 0);
    if (connect_sock<0)
	goto error;

    { /* store port number in unsigned short */
      unsigned short sport = g->port;
      SET_ADDR_LOOPBACK(address, FAMILY, sport);
    }

    if (connect(connect_sock, (struct sockaddr*)&address, sizeof address) < 0) 
	goto error;
    return connect_sock;

 error:
    if (!g->silent) {
	fprintf(stderr, "epmd: Cannot connect to local epmd\n");
    }
    epmd_cleanup_exit(g,1);
    return -1;
}

/* Fill buffer, return buffer length, 0 for EOF, < 0 for error. */
static int read_fill(int fd,char *buf,int len)
{
    int i;
    int got = 0;
    
    do {
	if ((i = read(fd, buf+got, len-got)) <= 0) 
	    return (i);
	got += i;
    } while (got < len);
    return (len);
}