socat/xio-gopen.c

135 lines
3.8 KiB
C
Raw Normal View History

2008-01-28 21:37:16 +00:00
/* source: xio-gopen.c */
/* Copyright Gerhard Rieger and contributors (see file CHANGES) */
2008-01-27 12:00:08 +00:00
/* Published under the GNU General Public License V.2, see file COPYING */
/* this file contains the source for opening addresses of generic open type */
#include "xiosysincludes.h"
#include "xioopen.h"
#include "xio-named.h"
#include "xio-unix.h"
#include "xio-gopen.h"
#if WITH_GOPEN
static int xioopen_gopen(int argc, const char *argv[], struct opt *opts, int xioflags, xiofile_t *fd, const struct addrdesc *addrdesc);
2008-01-27 12:00:08 +00:00
const struct addrdesc xioaddr_gopen = { "GOPEN", 3, xioopen_gopen, GROUP_FD|GROUP_FIFO|GROUP_CHR|GROUP_BLK|GROUP_REG|GROUP_NAMED|GROUP_OPEN|GROUP_FILE|GROUP_TERMIOS|GROUP_SOCKET|GROUP_SOCK_UNIX, 0, 0, 0 HELP(":<filename>") };
2008-01-27 12:00:08 +00:00
static int xioopen_gopen(
int argc,
const char *argv[],
struct opt *opts,
int xioflags,
xiofile_t *xxfd,
const struct addrdesc *addrdesc)
{
2023-07-13 07:06:08 +00:00
struct single *sfd = &xxfd->stream;
2008-01-27 12:00:08 +00:00
const char *filename = argv[1];
flags_t openflags = (xioflags & XIO_ACCMODE);
mode_t st_mode;
bool exists;
bool opt_unlink_close = false;
int result;
if ((result =
_xioopen_named_early(argc, argv, xxfd, GROUP_NAMED|addrdesc->groups, &exists,
opts, addrdesc->syntax))
< 0) {
2008-01-27 12:00:08 +00:00
return result;
}
st_mode = result;
if (exists) {
/* file (or at least named entry) exists */
if ((xioflags&XIO_ACCMODE) != XIO_RDONLY) {
openflags |= O_APPEND;
}
} else {
openflags |= O_CREAT;
}
/* note: when S_ISSOCK was undefined, it always gives 0 */
if (exists && S_ISSOCK(st_mode)) {
#if WITH_UNIX
2008-09-20 21:47:06 +00:00
union sockaddr_union us;
socklen_t uslen = sizeof(us);
2008-01-27 12:00:08 +00:00
char infobuff[256];
Info1("\"%s\" is a socket, connecting to it", filename);
2008-09-20 21:47:06 +00:00
result =
_xioopen_unix_client(sfd, xioflags, addrdesc->groups, 0, opts,
filename, addrdesc);
2008-09-20 21:47:06 +00:00
if (result < 0) {
return result;
2008-01-27 12:00:08 +00:00
}
applyopts_named(filename, opts, PH_PASTOPEN); /* unlink-late */
2023-07-13 07:06:08 +00:00
if (Getsockname(sfd->fd, (struct sockaddr *)&us, &uslen) < 0) {
2008-01-27 12:00:08 +00:00
Warn4("getsockname(%d, %p, {%d}): %s",
2023-07-13 07:06:08 +00:00
sfd->fd, &us, uslen, strerror(errno));
2008-01-27 12:00:08 +00:00
} else {
Notice1("successfully connected via %s",
2008-09-20 21:47:06 +00:00
sockaddr_unix_info(&us.un, uslen,
infobuff, sizeof(infobuff)));
2008-01-27 12:00:08 +00:00
}
#else
Error("\"%s\" is a socket, but UNIX socket support is not compiled in");
return -1;
#endif /* WITH_UNIX */
} else {
/* a file name */
Info1("\"%s\" is not a socket, open()'ing it", filename);
retropt_bool(opts, OPT_UNLINK_CLOSE, &opt_unlink_close);
if (opt_unlink_close) {
2023-07-13 07:06:08 +00:00
if ((sfd->unlink_close = strdup(filename)) == NULL) {
2008-01-27 12:00:08 +00:00
Error1("strdup(\"%s\"): out of memory", filename);
}
2023-07-13 07:06:08 +00:00
sfd->opt_unlink_close = true;
2008-01-27 12:00:08 +00:00
}
Notice3("opening %s \"%s\" for %s",
filetypenames[(st_mode&S_IFMT)>>12], filename, ddirection[(xioflags&XIO_ACCMODE)]);
if ((result = _xioopen_open(filename, openflags, opts)) < 0)
return result;
#ifdef I_PUSH
2022-01-02 20:34:10 +00:00
if (S_ISCHR(st_mode) && Ioctl(result, I_FIND, "ldterm\0") == 0) {
Ioctl(result, I_PUSH, "ptem\0\0\0"); /* pad string length ... */
Ioctl(result, I_PUSH, "ldterm\0"); /* ... to requirements of ... */
Ioctl(result, I_PUSH, "ttcompat"); /* ... AdressSanitizer */
2008-01-27 12:00:08 +00:00
}
#endif
2023-07-13 07:06:08 +00:00
sfd->fd = result;
2008-01-27 12:00:08 +00:00
#if WITH_TERMIOS
2023-07-13 07:06:08 +00:00
if (Isatty(sfd->fd)) {
if (Tcgetattr(sfd->fd, &sfd->savetty) < 0) {
2008-01-27 12:00:08 +00:00
Warn2("cannot query current terminal settings on fd %d: %s",
2023-07-13 07:06:08 +00:00
sfd->fd, strerror(errno));
2008-01-27 12:00:08 +00:00
} else {
2023-07-13 07:06:08 +00:00
sfd->ttyvalid = true;
2008-01-27 12:00:08 +00:00
}
}
#endif /* WITH_TERMIOS */
applyopts_named(filename, opts, PH_FD);
2023-07-13 07:06:08 +00:00
applyopts(sfd, -1, opts, PH_FD);
applyopts_cloexec(sfd->fd, opts);
2008-01-27 12:00:08 +00:00
}
2023-07-13 07:06:08 +00:00
if ((result = applyopts2(sfd, -1, opts, PH_PASTSOCKET, PH_CONNECTED)) < 0)
2008-01-27 12:00:08 +00:00
return result;
2023-07-13 07:06:08 +00:00
if ((result = _xio_openlate(sfd, opts)) < 0)
2008-01-27 12:00:08 +00:00
return result;
return 0;
}
#endif /* WITH_GOPEN */