aboutsummaryrefslogtreecommitdiffstats
path: root/kirc.c
diff options
context:
space:
mode:
authorCristian Canedo <ccanedo@gmx.com>2022-02-14 20:23:56 -0500
committerGitHub <noreply@github.com>2022-02-14 20:23:56 -0500
commit5f8bab4648d5c9f1513711a17633255f8601cf2e (patch)
tree1266c1bc651938713afae964b9d65291f9110595 /kirc.c
parentreleased at 0.3.0 (diff)
downloadkirc-5f8bab4648d5c9f1513711a17633255f8601cf2e.tar.gz
kirc-5f8bab4648d5c9f1513711a17633255f8601cf2e.tar.bz2
kirc-5f8bab4648d5c9f1513711a17633255f8601cf2e.tar.xz
kirc-5f8bab4648d5c9f1513711a17633255f8601cf2e.tar.zst
kirc-5f8bab4648d5c9f1513711a17633255f8601cf2e.zip
Allow the option of parsing multiple post-connection commands. (#125)
* Allow the option of parsing multiple post-connection commands. * Initial change for multiple commands via stdin * Use MSG_MAX as the max length of additional commands * Include + 1 to MSG_MAX to account for newline characters * Rework loop to process commands to avoid seg fault, use strnlen * Remove swap file * Restore previous formatting, restore man description for -x for now * Enable additional commands via both stdin and option argument * Move misplaced malloc check to where it belongs * Simplify logic to read commands from stdin * Retain functionality to accept server command as option argument * Maintain same functionality as before when sending inic
Diffstat (limited to 'kirc.c')
-rw-r--r--kirc.c110
1 files changed, 67 insertions, 43 deletions
diff --git a/kirc.c b/kirc.c
index 6f1f943..8e7dfde 100644
--- a/kirc.c
+++ b/kirc.c
@@ -23,22 +23,25 @@
#define CHA_MAX 200
#define NIC_MAX 26
#define HIS_MAX 100
+#define CBUF_SIZ 1024
-static char cdef[MSG_MAX] = "?"; /* default PRIVMSG channel */
-static int conn; /* connection socket */
-static int verb = 0; /* verbose output */
-static int sasl = 0; /* SASL method */
-static int isu8 = 0; /* UTF-8 flag */
-static char *host = "irc.libera.chat"; /* host address */
-static char *port = "6667"; /* port */
-static char *chan = NULL; /* channel(s) */
-static char *nick = NULL; /* nickname */
-static char *pass = NULL; /* password */
-static char *user = NULL; /* user name */
-static char *auth = NULL; /* PLAIN SASL token */
-static char *real = NULL; /* real name */
-static char *olog = NULL; /* chat log path*/
-static char *inic = NULL; /* additional server command */
+static char cdef[MSG_MAX] = "?"; /* default PRIVMSG channel */
+static int conn; /* connection socket */
+static int verb = 0; /* verbose output */
+static int sasl = 0; /* SASL method */
+static int isu8 = 0; /* UTF-8 flag */
+static char *host = "irc.libera.chat"; /* host address */
+static char *port = "6667"; /* port */
+static char *chan = NULL; /* channel(s) */
+static char *nick = NULL; /* nickname */
+static char *pass = NULL; /* password */
+static char *user = NULL; /* user name */
+static char *auth = NULL; /* PLAIN SASL token */
+static char *real = NULL; /* real name */
+static char *olog = NULL; /* chat log path*/
+static char *inic = NULL; /* additional server command */
+static int cmds = 0; /* indicates additional server commands */
+static char cbuf[CBUF_SIZ]; /* additional stdin server commands */
struct Param {
char *prefix;
@@ -53,6 +56,7 @@ struct Param {
int nicklen;
};
+static int ttyinfd = STDIN_FILENO;
static struct termios orig;
static int rawmode = 0;
static int atexit_registered = 0;
@@ -92,14 +96,14 @@ static void freeHistory(void) {
}
static void disableRawMode(void) {
- if (rawmode && tcsetattr(STDIN_FILENO,TCSAFLUSH,&orig) != -1) {
+ if (rawmode && tcsetattr(ttyinfd,TCSAFLUSH,&orig) != -1) {
rawmode = 0;
}
freeHistory();
}
static int enableRawMode(int fd) {
- if (!isatty(STDIN_FILENO)) {
+ if (!isatty(ttyinfd)) {
goto fatal;
}
if (!atexit_registered) {
@@ -297,7 +301,7 @@ static void refreshLine(struct State *l) {
size_t posu8 = l->posu8;
size_t ch = plenu8, txtlenb = 0;
struct abuf ab;
- l->cols = getColumns(STDIN_FILENO, STDOUT_FILENO);
+ l->cols = getColumns(ttyinfd, STDOUT_FILENO);
while ((plenu8 + posu8) >= l->cols) {
buf += u8Next(buf, 0);
posu8--;
@@ -510,12 +514,12 @@ static void editEnter(void) {
}
static void editEscSequence(struct State *l, char seq[3]) {
- if (read(STDIN_FILENO, seq, 1) == -1) return;
- if (read(STDIN_FILENO, seq + 1, 1) == -1) return;
+ if (read(ttyinfd, seq, 1) == -1) return;
+ if (read(ttyinfd, seq + 1, 1) == -1) return;
if (seq[0] == '[') { /* ESC [ sequences. */
if ((seq[1] >= '0') && (seq[1] <= '9')) {
/* Extended escape, read additional byte. */
- if (read(STDIN_FILENO, seq + 2, 1) == -1) {
+ if (read(ttyinfd, seq + 2, 1) == -1) {
return;
}
if ((seq[2] == '~') && (seq[1] == 3)) {
@@ -542,7 +546,7 @@ static void editEscSequence(struct State *l, char seq[3]) {
static int edit(struct State *l) {
char c, seq[3];
int ret = 0;
- ssize_t nread = read(STDIN_FILENO, &c, 1);
+ ssize_t nread = read(ttyinfd, &c, 1);
if (nread <= 0) {
ret = 1;
} else {
@@ -577,7 +581,7 @@ static int edit(struct State *l) {
aux[0] = c;
int size = u8CharSize(c);
for (int i = 1; i < size; i++) {
- nread = read(STDIN_FILENO, aux + i, 1);
+ nread = read(ttyinfd, aux + i, 1);
if ((aux[i] & 0xC0) != 0x80) {
break;
}
@@ -803,7 +807,7 @@ static void rawParser(char *string) {
p.command = strtok(p.suffix, "#& ");
p.channel = strtok(NULL, " \r");
p.params = strtok(NULL, ":\r");
- p.maxcols = getColumns(STDIN_FILENO, STDOUT_FILENO);
+ p.maxcols = getColumns(ttyinfd, STDOUT_FILENO);
p.nicklen = (p.maxcols / 3 > NIC_MAX ? NIC_MAX : p.maxcols / 3);
p.offset = 0;
if (!strncmp(p.command, "001", 3) && chan != NULL) {
@@ -922,26 +926,41 @@ static void version(void) {
exit(0);
}
+static void opentty()
+{
+ if ((ttyinfd = open("/dev/tty", 0)) == -1) {
+ perror("failed to open /dev/tty");
+ exit(1);
+ }
+}
+
int main(int argc, char **argv) {
+ opentty();
int cval;
- while ((cval = getopt(argc, argv, "s:p:o:n:k:c:u:r:x:a:evV")) != -1) {
+ while ((cval = getopt(argc, argv, "s:p:o:n:k:c:u:r:a:exvV")) != -1) {
switch (cval) {
- case 'v' : version(); break;
- case 'V' : ++verb; break;
- case 'e' : ++sasl; break;
- case 's' : host = optarg; break;
- case 'p' : port = optarg; break;
- case 'r' : real = optarg; break;
- case 'u' : user = optarg; break;
- case 'a' : auth = optarg; break;
- case 'o' : olog = optarg; break;
- case 'n' : nick = optarg; break;
- case 'k' : pass = optarg; break;
- case 'c' : chan = optarg; break;
- case 'x' : inic = optarg; break;
+ case 'v' : version(); break;
+ case 'V' : ++verb; break;
+ case 'e' : ++sasl; break;
+ case 's' : host = optarg; break;
+ case 'p' : port = optarg; break;
+ case 'r' : real = optarg; break;
+ case 'u' : user = optarg; break;
+ case 'a' : auth = optarg; break;
+ case 'o' : olog = optarg; break;
+ case 'n' : nick = optarg; break;
+ case 'k' : pass = optarg; break;
+ case 'c' : chan = optarg; break;
+ case 'x' : cmds = 1; inic = argv[optind]; break;
case '?' : usage(); break;
}
}
+ if (cmds > 0) {
+ int flag = 0;
+ for (int i = 0; i < CBUF_SIZ && flag > -1; i++) {
+ flag = read(STDIN_FILENO, &cbuf[i], 1);
+ }
+ }
if (!nick) {
fputs("Nick not specified\n", stderr);
usage();
@@ -961,11 +980,16 @@ int main(int argc, char **argv) {
if (pass) {
raw("PASS %s\r\n", pass);
}
- if (inic) {
- raw("%s\r\n", inic);
+ if (cmds > 0) {
+ for (char *tok = strtok(cbuf, "\n"); tok; tok = strtok(NULL, "\n")) {
+ raw("%s\r\n", tok);
+ }
+ if (inic) {
+ raw("%s\r\n", inic);
+ }
}
struct pollfd fds[2];
- fds[0].fd = STDIN_FILENO;
+ fds[0].fd = ttyinfd;
fds[1].fd = conn;
fds[0].events = POLLIN;
fds[1].events = POLLIN;
@@ -976,10 +1000,10 @@ int main(int argc, char **argv) {
l.prompt = cdef;
stateReset(&l);
int rc, editReturnFlag = 0;
- if (enableRawMode(STDIN_FILENO) == -1) {
+ if (enableRawMode(ttyinfd) == -1) {
return 1;
}
- if (setIsu8_C(STDIN_FILENO, STDOUT_FILENO) == -1) {
+ if (setIsu8_C(ttyinfd, STDOUT_FILENO) == -1) {
return 1;
}
for (;;) {