mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Add GDO_NAMES support
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@6919 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
3f025099d0
commit
dc170e38e4
3 changed files with 190 additions and 12 deletions
|
@ -1,7 +1,9 @@
|
|||
2000-07-18 Richard Frith-Macdonald <rfm@gnu.org>
|
||||
|
||||
* Tools/gdomap.h: Add new GDO_NAMES command.
|
||||
* Tools/gdomap.c: Incorporate MINGW port by Bjoern.Giesler@gmx.de
|
||||
after modifications to conform to coding standards.
|
||||
Add GDO_NAMES support to list all registered names.
|
||||
|
||||
2000-07-16 Fred Kiefer <FredKiefer@gmx.de>
|
||||
|
||||
|
|
191
Tools/gdomap.c
191
Tools/gdomap.c
|
@ -620,11 +620,11 @@ queue_pop()
|
|||
unsigned short next_port = IPPORT_USERRESERVED;
|
||||
|
||||
typedef struct {
|
||||
uptr name; /* Service name registered. */
|
||||
unsigned int port; /* Port it was mapped to. */
|
||||
uptr name; /* Service name registered. */
|
||||
unsigned int port; /* Port it was mapped to. */
|
||||
unsigned short size; /* Number of bytes in name. */
|
||||
unsigned char net; /* Type of port registered. */
|
||||
unsigned char svc; /* Type of port registered. */
|
||||
unsigned char net; /* Type of port registered. */
|
||||
unsigned char svc; /* Type of port registered. */
|
||||
} map_ent;
|
||||
|
||||
int map_used = 0;
|
||||
|
@ -2251,7 +2251,8 @@ handle_request(int desc)
|
|||
{
|
||||
fprintf(stderr, "request type '%c' from chan %d", type, desc);
|
||||
}
|
||||
if (type == GDO_PROBE || type == GDO_PREPLY)
|
||||
if (type == GDO_PROBE || type == GDO_PREPLY || type == GDO_SERVERS
|
||||
|| type == GDO_NAMES)
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
|
@ -2264,8 +2265,8 @@ handle_request(int desc)
|
|||
if (ptype != GDO_TCP_GDO && ptype != GDO_TCP_FOREIGN
|
||||
&& ptype != GDO_UDP_GDO && ptype != GDO_UDP_FOREIGN)
|
||||
{
|
||||
if (ptype != 0 || (type != GDO_PROBE && type != GDO_PREPLY &&
|
||||
type != GDO_SERVERS))
|
||||
if (ptype != 0 || (type != GDO_PROBE && type != GDO_PREPLY
|
||||
&& type != GDO_SERVERS && type != GDO_NAMES))
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
|
@ -2444,7 +2445,7 @@ handle_request(int desc)
|
|||
#ifndef __MINGW__
|
||||
int r = 1;
|
||||
if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR,
|
||||
(char*)&r, sizeof(r)) < 0)
|
||||
(char*)&r, sizeof(r)) < 0)
|
||||
{
|
||||
perror("unable to set socket options");
|
||||
}
|
||||
|
@ -2566,6 +2567,37 @@ handle_request(int desc)
|
|||
}
|
||||
w_info(desc)->len = 4 + (prb_used+1)*IASIZE;
|
||||
}
|
||||
else if (type == GDO_NAMES)
|
||||
{
|
||||
int bytes = 0;
|
||||
uptr ptr;
|
||||
int i;
|
||||
|
||||
free(w_info(desc)->buf);
|
||||
|
||||
/*
|
||||
* Size buffer for names.
|
||||
*/
|
||||
for (i = 0; i < map_used; i++)
|
||||
{
|
||||
bytes += 2 + strlen(map[i]->name);
|
||||
}
|
||||
/*
|
||||
* Allocate with space for number of names and set it up.
|
||||
*/
|
||||
w_info(desc)->buf = (char*)malloc(4 + bytes);
|
||||
*(unsigned long*)w_info(desc)->buf = htonl(bytes);
|
||||
ptr = (uptr)w_info(desc)->buf;
|
||||
ptr += 4;
|
||||
for (i = 0; i < map_used; i++)
|
||||
{
|
||||
ptr[0] = (unsigned char)strlen(map[i]->name);
|
||||
ptr[1] = (unsigned char)(map[i]->net | map[i]->svc);
|
||||
memcpy(&ptr[2], map[i]->name, ptr[0]);
|
||||
ptr += 2 + ptr[0];
|
||||
}
|
||||
w_info(desc)->len = 4 + bytes;
|
||||
}
|
||||
else if (type == GDO_PROBE)
|
||||
{
|
||||
/*
|
||||
|
@ -3286,6 +3318,47 @@ int ptype, struct sockaddr_in* addr, unsigned short* p, uptr*v)
|
|||
}
|
||||
*v = b;
|
||||
}
|
||||
/*
|
||||
* Special case for GDO_NAMES - allocate buffer and read list.
|
||||
*/
|
||||
else if (op == GDO_NAMES)
|
||||
{
|
||||
int len = port;
|
||||
uptr ptr;
|
||||
uptr b;
|
||||
|
||||
b = (uptr)malloc(len);
|
||||
if (tryRead(desc, 3, b, len) != len)
|
||||
{
|
||||
free(b);
|
||||
#ifdef __MINGW__
|
||||
e = WSAGetLastError();
|
||||
closesocket(desc);
|
||||
WSASetLastError(e);
|
||||
#else
|
||||
e = errno;
|
||||
close(desc);
|
||||
errno = e;
|
||||
#endif
|
||||
return 5;
|
||||
}
|
||||
/*
|
||||
* Count the number of registered names and return them.
|
||||
*/
|
||||
ptr = b;
|
||||
port = 0;
|
||||
while (ptr < &b[len])
|
||||
{
|
||||
ptr += 2 + ptr[0];
|
||||
port++;
|
||||
}
|
||||
if ((port & 0xffff) != port)
|
||||
{
|
||||
fprintf(stderr, "Insanely large number of registered names");
|
||||
port = 0;
|
||||
}
|
||||
*v = b;
|
||||
}
|
||||
|
||||
*p = (unsigned short)port;
|
||||
#ifdef __MINGW__
|
||||
|
@ -3310,13 +3383,13 @@ nameFail(int why)
|
|||
case 0: break;
|
||||
case 1:
|
||||
fprintf(stderr, "failed to contact name server - socket - %s",
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
case 2:
|
||||
fprintf(stderr, "failed to contact name server - socket - %s",
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
case 3:
|
||||
fprintf(stderr, "failed to contact name server - socket - %s",
|
||||
strerror(errno));
|
||||
strerror(errno));
|
||||
case 4:
|
||||
fprintf(stderr, "failed to contact name server - socket - %s",
|
||||
strerror(errno));
|
||||
|
@ -3526,6 +3599,95 @@ lookup(const char *name, const char *host, int ptype)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
donames()
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
struct servent* sp;
|
||||
struct hostent* hp;
|
||||
unsigned short p = htons(GDOMAP_PORT);
|
||||
unsigned short num = 0;
|
||||
int rval;
|
||||
uptr b;
|
||||
char *first_dot;
|
||||
const char *host;
|
||||
#ifdef __MINGW__
|
||||
char local_hostname[INTERNET_MAX_HOST_NAME_LENGTH];
|
||||
#else
|
||||
char local_hostname[MAXHOSTNAMELEN];
|
||||
#endif
|
||||
|
||||
#if GDOMAP_PORT_OVERRIDE
|
||||
p = htons(GDOMAP_PORT_OVERRIDE);
|
||||
#else
|
||||
/*
|
||||
* Ensure we have port number to connect to name server.
|
||||
* The TCP service name 'gdomap' overrides the default port.
|
||||
*/
|
||||
if ((sp = getservbyname("gdomap", "tcp")) != 0)
|
||||
{
|
||||
p = sp->s_port; /* Network byte order. */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* If no host name is given, we use the name of the local host.
|
||||
* NB. This should always be the case for operations other than lookup.
|
||||
*/
|
||||
|
||||
if (gethostname(local_hostname, sizeof(local_hostname)) < 0)
|
||||
{
|
||||
fprintf(stderr, "gethostname() failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
first_dot = strchr(local_hostname, '.');
|
||||
if (first_dot)
|
||||
{
|
||||
*first_dot = '\0';
|
||||
}
|
||||
host = local_hostname;
|
||||
if ((hp = gethostbyname(host)) == 0)
|
||||
{
|
||||
fprintf(stderr, "gethostbyname() failed: %s", strerror(errno));
|
||||
return;
|
||||
}
|
||||
if (hp->h_addrtype != AF_INET)
|
||||
{
|
||||
fprintf(stderr, "non-internet network not supported for %s\n", host);
|
||||
return;
|
||||
}
|
||||
|
||||
memset((char*)&sin, '\0', sizeof(sin));
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = p;
|
||||
memcpy(&sin.sin_addr, hp->h_addr, hp->h_length);
|
||||
|
||||
rval = tryHost(GDO_NAMES, 0, 0, 0, &sin, &num, (uptr*)&b);
|
||||
if (rval != 0)
|
||||
{
|
||||
fprintf(stderr, "failed to contact gdomap\n");
|
||||
return;
|
||||
}
|
||||
if (num == 0)
|
||||
{
|
||||
printf("No names currently registered with gdomap\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("Registered names are -\n");
|
||||
while (num-- > 0)
|
||||
{
|
||||
char buf[256];
|
||||
|
||||
memcpy(buf, &b[2], b[0]);
|
||||
buf[b[0]] = '\0';
|
||||
printf("%s\n", buf);
|
||||
b += 2 + b[0];
|
||||
}
|
||||
}
|
||||
free(b);
|
||||
}
|
||||
|
||||
static void
|
||||
doregister(const char *name, int port, int ptype)
|
||||
{
|
||||
|
@ -3568,7 +3730,7 @@ int
|
|||
main(int argc, char** argv)
|
||||
{
|
||||
extern char *optarg;
|
||||
char *options = "CHI:L:M:P:R:T:U:a:bc:dfi:p";
|
||||
char *options = "CHI:L:M:NP:R:T:U:a:bc:dfi:p";
|
||||
int c;
|
||||
int ptype = GDO_TCP_GDO;
|
||||
int port = 0;
|
||||
|
@ -3614,6 +3776,7 @@ main(int argc, char** argv)
|
|||
printf("-I pid file to write pid\n");
|
||||
printf("-L name perform lookup for name then quit.\n");
|
||||
printf("-M name machine name for L (default local)\n");
|
||||
printf("-N list all names registered on this host\n");
|
||||
printf("-P number port number required for R option.\n");
|
||||
printf("-R name register name locally then quit.\n");
|
||||
printf("-T type port type for L, R and U options -\n");
|
||||
|
@ -3680,6 +3843,10 @@ printf(
|
|||
machine = optarg;
|
||||
break;
|
||||
|
||||
case 'N':
|
||||
donames();
|
||||
exit(0);
|
||||
|
||||
case 'P':
|
||||
port = atoi(optarg);
|
||||
break;
|
||||
|
|
|
@ -82,6 +82,14 @@
|
|||
* NB. This response may not be possible over UDP as the
|
||||
* response length may exceed the maximum UDP packet size.
|
||||
*
|
||||
* GDO_NAMES Return a list of registered names known to the server.
|
||||
* Response is an unsigned long (in network byte order)
|
||||
* saying how many bytes of data are to follow,
|
||||
* followed by a list of the names each preceeded by the
|
||||
* name length (a single byte) and port type (a byte).
|
||||
* NB. This response may not be possible over UDP as the
|
||||
* response length may exceed the maximum UDP packet size.
|
||||
*
|
||||
* The following are used for communications between name servers -
|
||||
*
|
||||
* GDO_PROBE Requests a response
|
||||
|
@ -168,6 +176,7 @@
|
|||
#define GDO_SERVERS 'S'
|
||||
#define GDO_PROBE 'P'
|
||||
#define GDO_PREPLY 'p'
|
||||
#define GDO_NAMES 'N'
|
||||
|
||||
/*
|
||||
* Port type codes
|
||||
|
|
Loading…
Reference in a new issue