#include "RxI.h"
#include "XUrls.h"
#include <sys/utsname.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <stdlib.h>
#include <limits.h>
#include <errno.h>
#ifndef MAXHOSTNAMELEN
# define MAXHOSTNAMELEN 256
#endif
static char*
MyBestHostname (
char* myname,
int myname_len,
char* display_name,
char* dest_url)
{
struct utsname host;
*myname = '\0';
if (display_name[0] == ':') {
#if !(defined(sun) && defined(SVR4))
struct sockaddr_in local, remote;
struct hostent* hp;
int s, rv, namelen;
char dest_hostname[MAXHOSTNAMELEN + 1];
ParseHostname (dest_url, dest_hostname, sizeof dest_hostname);
hp = gethostbyname (dest_hostname);
if (hp) {
memcpy (&remote.sin_addr, hp->h_addr_list[0], sizeof remote.sin_addr);
remote.sin_port = htons(60000);
remote.sin_family = AF_INET;
#ifdef BSD44SOCKETS
remote.sin_len = sizeof remote;
#endif
local.sin_addr.s_addr = htonl(INADDR_ANY);
local.sin_port = htons(60000);
local.sin_family = AF_INET;
#ifdef BSD44SOCKETS
local.sin_len = sizeof remote;
#endif
s = socket(PF_INET, SOCK_DGRAM, 0);
if (s != -1) {
do {
rv = bind (s, (struct sockaddr*) &local, sizeof local);
local.sin_port = htons (ntohs (local.sin_port) + 1);
} while (rv == -1 && errno == EADDRINUSE);
if (rv != -1) {
do {
rv = connect (s, (struct sockaddr*) &remote, sizeof remote);
remote.sin_port = htons (ntohs (remote.sin_port) + 1);
} while (rv == -1 && errno == EADDRINUSE);
if (rv != -1) {
namelen = sizeof local;
rv = getsockname (s, (struct sockaddr*) &local, (void *)&namelen);
if (rv != -1) {
hp = gethostbyaddr ((char*) &local.sin_addr.s_addr,
sizeof local.sin_addr.s_addr,
AF_INET);
if (hp) {
strncpy (myname, hp->h_name, myname_len);
myname[MAXHOSTNAMELEN] = '\0';
close (s);
return display_name;
}
}
}
}
close (s);
}
}
#endif
uname(&host);
strncpy (myname, host.nodename, myname_len);
myname[MAXHOSTNAMELEN] = '\0';
} else {
char *ptr;
ptr = strrchr(display_name, ':');
if (ptr == NULL) {
strncpy(myname, display_name, myname_len);
myname[MAXHOSTNAMELEN] = '\0';
} else {
strncpy(myname, display_name, ptr - display_name);
myname[ptr - display_name] = '\0';
return ptr;
}
}
return display_name;
}
char *
GetXUrl(char *display_name, char *auth, char* dest_url)
{
char *dpy_name, *proto = NULL;
char *url, *ptr;
char *name;
struct hostent *host;
int len, proto_len, dpy_len, name_len, auth_len;
char hostname[MAXHOSTNAMELEN + 1];
len = 5;
if (strncmp(display_name, "x11:", 4) == 0)
dpy_name = display_name + 4;
else
dpy_name = display_name;
ptr = strchr(dpy_name, '/');
if (ptr != NULL) {
proto = dpy_name;
proto_len = ptr - dpy_name;
dpy_name = ptr + 1;
if (strncmp(proto, "local", proto_len) == 0)
proto_len = 0;
} else
proto_len = 0;
if (strncmp(dpy_name, "unix", 4) == 0)
dpy_name += 4;
dpy_name = MyBestHostname (hostname, MAXHOSTNAMELEN, dpy_name, dest_url);
host = gethostbyname(hostname);
name = host->h_name;
name_len = strlen(name);
dpy_len = dpy_name == NULL ? 0 : strlen(dpy_name);
auth_len = auth == NULL ? 0 : 6 + strlen(auth);
len += proto_len + 1 + name_len + dpy_len + auth_len;
url = ptr = (char *)Malloc(len);
if (url == NULL)
return NULL;
strcpy(ptr, "x11:");
ptr += 4;
if (proto_len != 0) {
strncpy(ptr, proto, proto_len + 1);
ptr += proto_len + 1;
}
if (name_len != 0) {
strcpy(ptr, name);
ptr += name_len;
}
if (dpy_len != 0) {
strcpy(ptr, dpy_name);
ptr += dpy_len;
}
if (auth_len != 0)
sprintf(ptr, ";auth=%s", auth);
else
*ptr = '\0';
return url;
}
char *
GetXPrintUrl(char *display_name, char *printer, char *auth, char* dest_url)
{
char *dpy_name, *proto = NULL;
char *url, *ptr;
char *name;
struct hostent *host;
int len, proto_len, dpy_len, name_len, auth_len, printer_len;
char hostname[MAXHOSTNAMELEN + 1];
len = 7;
if (strncmp(display_name, "xprint:", 7) == 0)
dpy_name = display_name + 7;
else
dpy_name = display_name;
ptr = strchr(dpy_name, '/');
if (ptr != NULL) {
proto = dpy_name;
proto_len = ptr - dpy_name;
dpy_name = ptr + 1;
if (strncmp(proto, "local", proto_len) == 0)
proto_len = 0;
} else
proto_len = 0;
if (strncmp(dpy_name, "unix", 4) == 0)
dpy_name += 4;
dpy_name = MyBestHostname (hostname, MAXHOSTNAMELEN, dpy_name, dest_url);
host = gethostbyname(hostname);
name = host->h_name;
ptr = strchr(dpy_name, '.');
if (ptr != NULL)
dpy_len = ptr - dpy_name;
else
dpy_len = strlen(dpy_name);
name_len = strlen(name);
printer_len = printer ? strlen(printer) : 0;
auth_len = auth == NULL ? 0 : 6 + strlen(auth);
len += printer_len + 1 + proto_len + 1 + name_len + dpy_len + auth_len;
url = ptr = (char *)Malloc(len);
if (url == NULL)
return NULL;
strcpy(ptr, "xprint:");
ptr += 7;
if (printer_len != 0) {
strcpy(ptr, printer);
ptr += printer_len;
*ptr++ = '@';
}
if (proto_len != 0) {
strncpy(ptr, proto, proto_len + 1);
ptr += proto_len + 1;
}
if (name_len != 0) {
strcpy(ptr, name);
ptr += name_len;
}
if (dpy_len != 0) {
strncpy(ptr, dpy_name, dpy_len);
ptr += dpy_len;
}
if (auth_len != 0)
sprintf(ptr, ";auth=%s", auth);
else
*ptr = '\0';
return url;
}
int
ParseHostname(char *url, char *buf, int buflen)
{
char *ptr, *begin;
if (url == NULL)
return 0;
ptr = strchr(url, ':');
if (ptr != NULL)
ptr++;
else
ptr = url;
while (*ptr && *ptr == '/')
ptr++;
begin = ptr;
if (*ptr == '[') {
begin++;
while (*ptr && (*ptr != ']')) {
ptr++;
}
} else {
ptr = strchr(begin, ':');
if (ptr == NULL) {
ptr = strchr(begin, '/');
if (ptr == NULL)
ptr += strlen(begin);
}
}
if (ptr - begin < buflen) {
strncpy(buf, begin, ptr - begin);
buf[ptr - begin] = '\0';
return ptr - begin;
} else
return 0;
}