Simplify handling of /DETACH socket path
init_socketpath() was building a sprintf() format string intended to be used by /DETACH to create the socket file name. This included the actual socket path, plus a %d for the port, plus the sanitised tty name and hostname. Only one caller needed all this though - the /DETACH command - and the other callers (in scr-bx.c) just wanted to truncate it to the actual socket path. The format string also wasn't safe - if the home directory path, hostname or ttyname contained % characters these werent being escaped. It simplifies things to have init_socketpath() just return the actual socket path, after creating the 'screens' directory if necessary. This lets the code in scr-bx.c use it as-is, and removes the need for the global socket_path variable. The code to include the sanitised tty name and hostname in the socket file name can be moved to the create_ipc_socket() function. There's no need to check access() for the socket path before trying to create it - just call mkdir() regardless, since it will fail if the path already exists, which is fine. This commit also adds error handling to the create_ipc_socket() function for the case where creation of the socket file fails, and switches the chmod() and chown() for the opened file to the more appropriate fchmod() and fchown().
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
[Changes 1.2.2]
|
||||
|
||||
* Simplify handling of /DETACH socket path. (caf)
|
||||
|
||||
* Remove netfinger client code (no-one is running fingerd anymore) and
|
||||
repurpose /FINGER command to send a CTCP FINGER instead. (caf)
|
||||
|
||||
|
||||
@@ -344,7 +344,7 @@ extern short ospeed;
|
||||
#endif
|
||||
|
||||
void reattach_tty(char *, char *);
|
||||
void init_socketpath(void);
|
||||
const char *init_socketpath(void);
|
||||
void kill_attached_if_needed(int);
|
||||
void setup_pid();
|
||||
|
||||
|
||||
@@ -2379,7 +2379,6 @@ extern HMQ hmq;
|
||||
|
||||
#if !defined(__EMX__) && !defined(WINNT) && !defined(GUI) && defined(WANT_DETACH)
|
||||
#ifndef PUBLIC_ACCESS
|
||||
extern char socket_path[];
|
||||
extern char *old_pass;
|
||||
|
||||
int displays = 0;
|
||||
@@ -2531,11 +2530,12 @@ void make_cookie(void)
|
||||
|
||||
static int create_ipc_socket(void)
|
||||
{
|
||||
int s = -1, u = -1;
|
||||
int s, u;
|
||||
unsigned short port = 0;
|
||||
char buf[BIG_BUFFER_SIZE+1];
|
||||
|
||||
init_socketpath();
|
||||
char buf[BIG_BUFFER_SIZE];
|
||||
char host[BIG_BUFFER_SIZE];
|
||||
char *p;
|
||||
const char *socket_path = init_socketpath();
|
||||
|
||||
if ((s = connect_by_number("127.0.0.1", &port, SERVICE_SERVER, PROTOCOL_TCP, 0)) < 0)
|
||||
{
|
||||
@@ -2543,19 +2543,33 @@ static int create_ipc_socket(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
sprintf(buf, socket_path, port);
|
||||
if ((u = open(buf, O_CREAT|O_WRONLY, 0600)) != -1)
|
||||
gethostname(host, sizeof host);
|
||||
if ((p = strchr(host, '.')))
|
||||
*p = 0;
|
||||
|
||||
snprintf(buf, sizeof buf, "%s/%u.%s.%s", socket_path, (unsigned)port, stripdev(attach_ttyname), host);
|
||||
|
||||
if (strlen(socket_path) + 1 < sizeof buf)
|
||||
for (p = buf + strlen(socket_path) + 1; *p; p++)
|
||||
if (*p == '/')
|
||||
*p = '-';
|
||||
|
||||
if ((u = open(buf, O_CREAT|O_WRONLY, 0600)) < 0)
|
||||
{
|
||||
chmod(buf, SOCKMODE);
|
||||
chown(buf, getuid(), getgid());
|
||||
bitchsay("Error creating IPC file: %s", strerror(errno));
|
||||
new_close(s);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fchmod(u, SOCKMODE);
|
||||
fchown(u, getuid(), getgid());
|
||||
make_cookie();
|
||||
write(u, connect_cookie, strlen(connect_cookie));
|
||||
write(u, "\n", 1);
|
||||
close(u);
|
||||
}
|
||||
|
||||
set_non_blocking(s);
|
||||
add_socketread(s, port, 0, socket_path, handle_reconnect, NULL);
|
||||
add_socketread(s, port, 0, NULL, handle_reconnect, NULL);
|
||||
save_ipc = s;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -165,7 +165,6 @@ char *invite_channel = NULL, /* last channel of an INVITE */
|
||||
realname[REALNAME_LEN + 1], /* real name of user */
|
||||
username[NAME_LEN + 1], /* usernameof user */
|
||||
attach_ttyname[500], /* ttyname for this term */
|
||||
socket_path[500], /* ttyname for this term */
|
||||
*forwardnick = NULL, /* used for /forward */
|
||||
*send_umode = NULL, /* sent umode */
|
||||
*args_str = NULL, /* list of command line args */
|
||||
@@ -1502,7 +1501,6 @@ int main(int argc, char *argv[], char *envp[])
|
||||
|
||||
channel = parse_args(argv, argc, envp);
|
||||
check_pid();
|
||||
init_socketpath();
|
||||
|
||||
#ifdef WANT_TCL
|
||||
tcl_interp = Tcl_CreateInterp();
|
||||
|
||||
@@ -2871,38 +2871,16 @@ char *BX_stripdev(char *ttynam)
|
||||
return ttynam;
|
||||
}
|
||||
|
||||
|
||||
void init_socketpath(void)
|
||||
const char *init_socketpath(void)
|
||||
{
|
||||
#if !defined(__EMX__) && !defined(WINNT)
|
||||
struct stat st;
|
||||
extern char socket_path[], attach_ttyname[];
|
||||
static char socket_path[BIG_BUFFER_SIZE];
|
||||
|
||||
snprintf(socket_path, sizeof socket_path, "%s/.BitchX/screens", my_path);
|
||||
|
||||
sprintf(socket_path, "%s/.BitchX/screens", my_path);
|
||||
if (access(socket_path, F_OK))
|
||||
{
|
||||
if (mkdir(socket_path, 0700) != -1)
|
||||
(void)chown(socket_path, getuid(), getgid());
|
||||
else
|
||||
return;
|
||||
}
|
||||
if (stat(socket_path, &st) != -1)
|
||||
{
|
||||
char host[BIG_BUFFER_SIZE+1];
|
||||
char *ap;
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return;
|
||||
gethostname(host, BIG_BUFFER_SIZE);
|
||||
if ((ap = strchr(host, '.')))
|
||||
*ap = 0;
|
||||
ap = &socket_path[strlen(socket_path)];
|
||||
sprintf(ap, "/%%d.%s.%s", stripdev(attach_ttyname), host);
|
||||
ap++;
|
||||
for ( ; *ap; ap++)
|
||||
if (*ap == '/')
|
||||
*ap = '-';
|
||||
}
|
||||
#endif
|
||||
|
||||
return socket_path;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -44,9 +44,7 @@ unsigned char transToClient[256]; /* Server to client translation. */
|
||||
int dumb_mode = 0;
|
||||
int already_detached = 1;
|
||||
int do_check_pid = 0;
|
||||
char socket_path[500];
|
||||
char attach_ttyname[500];
|
||||
|
||||
char *my_path;
|
||||
|
||||
struct param
|
||||
{
|
||||
@@ -177,22 +175,18 @@ char *q;
|
||||
return ttypath;
|
||||
}
|
||||
|
||||
void display_socket_list(char *path, int unl, char *arg)
|
||||
void display_socket_list(const char *path, int unl, char *arg)
|
||||
{
|
||||
DIR *dptr;
|
||||
struct dirent *dir;
|
||||
struct stat st;
|
||||
char buffer[2000];
|
||||
char *new_path, *p;
|
||||
int count = 0;
|
||||
int doit = 0;
|
||||
|
||||
new_path = LOCAL_COPY(path);
|
||||
if ((p = strrchr(new_path, '/')))
|
||||
*p = 0;
|
||||
if (!(dptr = opendir(new_path)))
|
||||
if (!(dptr = opendir(path)))
|
||||
{
|
||||
fprintf(stderr, "No such directory %s\r\n ", new_path);
|
||||
fprintf(stderr, "No such directory %s\n", path);
|
||||
exit(1);
|
||||
}
|
||||
while ((dir = readdir(dptr)))
|
||||
@@ -202,7 +196,7 @@ int doit = 0;
|
||||
continue;
|
||||
if (dir->d_name[0] == '.')
|
||||
continue;
|
||||
sprintf(buffer, "%s/%s", new_path, dir->d_name);
|
||||
sprintf(buffer, "%s/%s", path, dir->d_name);
|
||||
if ((stat(buffer, &st) == -1))
|
||||
continue;
|
||||
if (arg && strstr(dir->d_name, arg))
|
||||
@@ -229,20 +223,15 @@ int doit = 0;
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *find_detach_socket(char *path, char *name)
|
||||
char *find_detach_socket(const char *path, char *name)
|
||||
{
|
||||
char *new_path;
|
||||
DIR *dptr;
|
||||
struct dirent *dir;
|
||||
struct stat st;
|
||||
char *ret = NULL, *p;
|
||||
int count = 0;
|
||||
new_path = LOCAL_COPY(path);
|
||||
if ((p = strrchr(new_path, '/')))
|
||||
*p = 0;
|
||||
else
|
||||
return NULL;
|
||||
if (!(dptr = opendir(new_path)))
|
||||
|
||||
if (!(dptr = opendir(path)))
|
||||
return NULL;
|
||||
ret = malloc(2000);
|
||||
*ret = 0;
|
||||
@@ -253,7 +242,7 @@ int count = 0;
|
||||
continue;
|
||||
if (dir->d_name[0] == '.')
|
||||
continue;
|
||||
sprintf(ret, "%s/%s", new_path, dir->d_name);
|
||||
sprintf(ret, "%s/%s", path, dir->d_name);
|
||||
p = strrchr(ret, '/'); p++;
|
||||
if ((stat(ret, &st) == -1) || (st.st_uid != getuid()) || S_ISDIR(st.st_mode))
|
||||
{
|
||||
@@ -320,7 +309,7 @@ SIGNAL_HANDLER(handle_pipe)
|
||||
term_cr();
|
||||
term_clear_to_eol();
|
||||
term_reset2();
|
||||
fprintf(stdout, "\rdetached from %s. To re-attach type scr-bx %s\n\r", attach_ttyname, old_pass? "password":"");
|
||||
fprintf(stdout, "\rdetached from %s. To re-attach type scr-bx %s\n\r", ttyname(0), old_pass? "password":"");
|
||||
fflush(stdout);
|
||||
exit(0);
|
||||
}
|
||||
@@ -396,6 +385,8 @@ int port = 0;
|
||||
#if defined (TIOCGWINSZ)
|
||||
struct winsize window;
|
||||
#endif
|
||||
const char *socket_path = init_socketpath();
|
||||
|
||||
memset(&parm, 0, sizeof(struct param));
|
||||
|
||||
if (!(name = find_detach_socket(socket_path, tty)))
|
||||
@@ -528,53 +519,17 @@ struct winsize window;
|
||||
return; /* error return */
|
||||
}
|
||||
|
||||
char *stripdev(char *ttynam)
|
||||
const char *init_socketpath(void)
|
||||
{
|
||||
if (ttynam == NULL)
|
||||
return NULL;
|
||||
#ifdef SVR4
|
||||
/* unixware has /dev/pts012 as synonym for /dev/pts/12 */
|
||||
if (!strncmp(ttynam, "/dev/pts", 8) && ttynam[8] >= '0' && ttynam[8] <= '9')
|
||||
{
|
||||
static char b[13];
|
||||
sprintf(b, "pts/%d", atoi(ttynam + 8));
|
||||
return b;
|
||||
}
|
||||
#endif /* SVR4 */
|
||||
if (!strncmp(ttynam, "/dev/", 5))
|
||||
return ttynam + 5;
|
||||
return ttynam;
|
||||
}
|
||||
static char socket_path[BIG_BUFFER_SIZE];
|
||||
|
||||
snprintf(socket_path, sizeof socket_path, "%s/.BitchX/screens", my_path);
|
||||
|
||||
void init_socketpath(void)
|
||||
{
|
||||
#if !defined(__EMX__) && !defined(WINNT)
|
||||
struct stat st;
|
||||
extern char socket_path[], attach_ttyname[];
|
||||
if (mkdir(socket_path, 0700) != -1)
|
||||
(void)chown(socket_path, getuid(), getgid());
|
||||
|
||||
sprintf(socket_path, "%s/.BitchX/screens", getenv("HOME"));
|
||||
if (access(socket_path, F_OK))
|
||||
return;
|
||||
if (stat(socket_path, &st) != -1)
|
||||
{
|
||||
char host[BIG_BUFFER_SIZE+1];
|
||||
char *ap;
|
||||
if (!S_ISDIR(st.st_mode))
|
||||
return;
|
||||
gethostname(host, BIG_BUFFER_SIZE);
|
||||
if ((ap = strchr(host, '.')))
|
||||
*ap = 0;
|
||||
ap = &socket_path[strlen(socket_path)];
|
||||
sprintf(ap, "/%%d.%s.%s", stripdev(attach_ttyname), host);
|
||||
ap++;
|
||||
for ( ; *ap; ap++)
|
||||
if (*ap == '/')
|
||||
*ap = '-';
|
||||
return socket_path;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
char *old_tty = NULL;
|
||||
void parse_args(int argc, char **argv)
|
||||
@@ -618,7 +573,7 @@ int disp_sock = 0;
|
||||
}
|
||||
}
|
||||
if (disp_sock)
|
||||
display_socket_list(socket_path, disp_sock - 1, old_tty);
|
||||
display_socket_list(init_socketpath(), disp_sock - 1, old_tty);
|
||||
}
|
||||
|
||||
|
||||
@@ -627,9 +582,7 @@ int main(int argc, char **argv)
|
||||
#ifdef MEM_DEBUG
|
||||
dmalloc_debug(0x1df47dfb);
|
||||
#endif
|
||||
*socket_path = 0;
|
||||
strcpy(attach_ttyname, ttyname(0));
|
||||
init_socketpath();
|
||||
my_path = getenv("HOME");
|
||||
parse_args(argc, argv);
|
||||
chdir(getenv("HOME"));
|
||||
reattach_tty(old_tty, old_pass);
|
||||
|
||||
Reference in New Issue
Block a user