Introduction
Introduction Statistics Contact Development Disclaimer Help
merged kris' changes into mainstream sic - sic - simple irc client
git clone git://git.suckless.org/sic
Log
Files
Refs
README
LICENSE
---
commit 1a4256ef71ddba6c3cbb28861e0321184860653f
parent 9c7027fcbf86f3082bf0609a7784cc6f6cfa87c7
Author: Anselm R Garbe <[email protected]>
Date: Sat, 28 Nov 2009 12:16:35 +0000
merged kris' changes into mainstream sic
Diffstat:
M LICENSE | 6 +++---
M config.mk | 2 +-
D kris/Makefile | 2 --
D kris/config.mk | 2 --
D kris/sic.c | 215 -----------------------------…
D kris/util.c | 86 ------------------------------
M sic.c | 308 +++++++++++++----------------…
A util.c | 81 ++++++++++++++++++++++++++++++
8 files changed, 218 insertions(+), 484 deletions(-)
---
diff --git a/LICENSE b/LICENSE
@@ -1,8 +1,8 @@
MIT/X Consortium License
-
-© 2005-2009 Anselm R Garbe <garbeam at gmail dot com>
-© 2008-2009 Jeroen Schot <schot at a-eskwadraat dot nl>
+© 2005-2009 Anselm R Garbe <[email protected]>
+© 2008-2009 Jeroen Schot <[email protected]>
+© 2007-2009 Kris Maglione <[email protected]>
© 2005 Nico Golde <nico at ngolde dot de>
Permission is hereby granted, free of charge, to any person obtaining a
diff --git a/config.mk b/config.mk
@@ -1,5 +1,5 @@
# sic version
-VERSION = 1.0
+VERSION = 1.1
# Customize below to fit your system
diff --git a/kris/Makefile b/kris/Makefile
@@ -1 +0,0 @@
-../Makefile
-\ No newline at end of file
diff --git a/kris/config.mk b/kris/config.mk
@@ -1 +0,0 @@
-../config.mk
-\ No newline at end of file
diff --git a/kris/sic.c b/kris/sic.c
@@ -1,215 +0,0 @@
-/* ? 2005-2007 Anselm R. Garbe <garbeam at gmail dot com>
- * ? 2007 Kris Maglione <[email protected]>
- * ? 2005 Nico Golde <nico at ngolde dot de>
- * See LICENSE file for license details.
- */
-#include <ctype.h>
-#include <errno.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#include <unistd.h>
-
-#define nil ((void*)0)
-typedef unsigned short ushort;
-
-#define PINGTIMEOUT 300
-
-static char* host = "irc.oftc.net";
-static char* port = "ircd";
-static char* password;
-static char nick[32];
-
-static char bufin[4096];
-static char bufout[4096];
-static char channel[256];
-static time_t trespond;
-static FILE *srv;
-
-#include "util.c"
-
-static void
-pout(char *channel, char *fmt, ...) {
- static char timestr[18];
- time_t t;
-
- va_buf(bufout, fmt);
-
- t = time(nil);
- strftime(timestr, sizeof timestr, "%D %R", localtime(&t));
- fprintf(stdout, "%-12s: %s %s\n", channel, timestr, bufout);
-}
-
-static void
-sout(char *fmt, ...) {
- va_buf(bufout, fmt);
- fprintf(srv, "%s\r\n", bufout);
-}
-
-static void
-privmsg(char *channel, char *msg) {
- if(channel[0] == '\0') {
- pout("", "No channel to send to");
- return;
- }
- pout(channel, "<%s> %s", nick, msg);
- sout("PRIVMSG %s :%s", channel, msg);
-}
-
-static void
-parsein(char *msg) {
- char *p;
- char c;
-
- if(msg[0] == '\0')
- return;
- msg = ctok(&msg, '\n');
- if(msg[0] != ':') {
- privmsg(channel, msg);
- return;
- }
- c = *++msg;
- if(!c || !isspace(msg[1]))
- sout("%s", msg);
- else {
- if(msg[1])
- msg += 2;
- switch(c) {
- case 'j':
- sout("JOIN %s", msg);
- if(channel[0] == '\0')
- strlcpy(channel, msg, sizeof channel);
- break;
- case 'l':
- p = tok(&msg);
- if(!*p)
- p = channel;
- if(!*msg)
- msg = "sic - 250 LOC are too much!";
- sout("PART %s :%s", p, msg);
- break;
- case 'm':
- p = tok(&msg);
- privmsg(p, msg);
- break;
- case 's':
- strlcpy(channel, msg, sizeof channel);
- break;
- default:
- sout("%c %s", c, msg);
- break;
- }
- }
-}
-
-static void
-parsesrv(char *msg) {
- char *cmd, *p, *usr, *txt;
-
- usr = host;
- if(!msg || !*msg)
- return;
- if(msg[0] == ':') {
- msg++;
- p = tok(&msg);
- if(!*msg)
- return;
- usr = ctok(&p, '!');
- }
- txt = ctok(&msg, '\r');
- msg = ctok(&txt, ':');
- cmd = tok(&msg);
- if(!strcmp("PONG", cmd))
- return;
- if(!strcmp("PRIVMSG", cmd))
- pout(msg, "<%s> %s", usr, txt);
- else if(!strcmp("PING", cmd))
- sout("PONG %s", txt);
- else {
- pout(usr, ">< %s: %s", cmd, txt);
- if(!strcmp("NICK", cmd) && !strcmp(usr, nick))
- strlcpy(nick, txt, sizeof nick);
- }
-}
-
-int
-main(int argc, char *argv[]) {
- int i, c;
- struct timeval tv;
- fd_set rd;
-
- strlcpy(nick, getenv("USER"), sizeof nick);
- for(i = 1; i < argc; i++) {
- c = argv[i][1];
- if(argv[i][0] != '-' || argv[i][2])
- c = -1;
- switch(c) {
- case 'h':
- if(++i < argc) host = argv[i];
- break;
- case 'p':
- if(++i < argc) port = argv[i];
- break;
- case 'n':
- if(++i < argc) strlcpy(nick, argv[i], sizeof nick);
- break;
- case 'k':
- if(++i < argc) password = argv[i];
- break;
- case 'v':
- eprint("sic-"VERSION", ©2005-2009 Kris Maglione, Anse…
- default:
- eprint("usage: sic [-h host] [-p port] [-n nick] [-k k…
- }
- }
-
- /* init */
- i = dial(host, port);
- srv = fdopen(i, "r+");
-
- /* login */
- if(password)
- sout("PASS %s", password);
- sout("NICK %s", nick);
- sout("USER %s localhost %s :%s", nick, host, nick);
- fflush(srv);
-
- setbuf(stdout, nil);
- setbuf(srv, nil);
-
- for(;;) { /* main loop */
- FD_ZERO(&rd);
- FD_SET(0, &rd);
- FD_SET(fileno(srv), &rd);
- tv.tv_sec = 120;
- tv.tv_usec = 0;
- i = select(fileno(srv) + 1, &rd, 0, 0, &tv);
- if(i < 0) {
- if(errno == EINTR)
- continue;
- eprint("sic: error on select():");
- }
- else if(i == 0) {
- if(time(nil) - trespond >= PINGTIMEOUT)
- eprint("sic shutting down: parse timeout\n");
- sout("PING %s", host);
- continue;
- }
- if(FD_ISSET(fileno(srv), &rd)) {
- if(fgets(bufin, sizeof bufin, srv) == nil)
- eprint("sic: remote host closed connection\n");
- parsesrv(bufin);
- trespond = time(nil);
- }
- if(FD_ISSET(0, &rd)) {
- if(fgets(bufin, sizeof bufin, stdin) == nil)
- eprint("sic: broken pipe\n");
- parsein(bufin);
- }
- }
- return 0;
-}
-
-
diff --git a/kris/util.c b/kris/util.c
@@ -1,86 +0,0 @@
-#include <netdb.h>
-#include <netinet/in.h>
-#include <sys/socket.h>
-
-#define va_buf(buf, fmt) {\
- va_list ap; \
- va_start(ap, fmt); \
- vsnprintf(buf, sizeof buf, fmt, ap); \
- va_end(ap); \
-}
-
-static void
-eprint(const char *fmt, ...) {
-
- va_buf(bufout, fmt);
- fprintf(stderr, "%s", bufout);
-
- if(fmt[0] && fmt[strlen(fmt)-1] == ':')
- fprintf(stderr, " %s\n", strerror(errno));
- exit(1);
-}
-
-static int
-dial(char *host, char *port) {
- static struct addrinfo hints;
- struct addrinfo *res, *r;
- int srv;
-
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- if(getaddrinfo(host, port, &hints, &res) != 0)
- eprint("error: cannot resolve hostname '%s':", host);
- for(r = res; r; r = r->ai_next) {
- if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)…
- continue;
- if(connect(srv, r->ai_addr, r->ai_addrlen) == 0)
- break;
- close(srv);
- }
- freeaddrinfo(res);
- if(!r)
- eprint("error: cannot connect to host '%s'\n", host);
- return srv;
-}
-
-#define strlcpy _strlcpy
-static void
-strlcpy(char *to, const char *from, int l) {
- memccpy(to, from, '\0', l);
- to[l-1] = '\0';
-}
-
-static void
-eat(char **s, int (*p)(int), int r) {
- char *q;
-
- for(q=*s; *q && p(*q) == r; q++)
- ;
- *s = q;
-}
-
-static char*
-tok(char **s) {
- char *p;
-
- eat(s, isspace, 1);
- p = *s;
- eat(s, isspace, 0);
- if(**s) *(*s)++ = '\0';
- return p;
-}
-
-static char*
-ctok(char **s, int c) {
- char *p, *q;
-
- q = *s;
- for(p=q; *p && *p != c; p++)
- ;
- if(*p) *p++ = '\0';
- *s = p;
- return q;
-}
-
-
diff --git a/sic.c b/sic.c
@@ -1,246 +1,204 @@
-/* See LICENSE file for license details. */
+ /* See LICENSE file for license details. */
+#include <ctype.h>
#include <errno.h>
-#include <netdb.h>
-#include <netinet/in.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/time.h>
-#define PINGTIMEOUT 300
-#define MAXMSG 4096
-#ifndef VERSION
-#define VERSION "dev"
-#endif
-
-static void die(const char *errstr, ...);
-static void printl(char *channel, char *msg);
-static void privmsg(char *channel, char *msg);
-static void parsein(char *msg);
-static void parsesrv(char *msg);
-static int readl(int fd, unsigned int len, char *buf);
-
-static char *host = "irc6.oftc.net";
-static char *port = "6667";
+static char *host = "irc.oftc.net";
+static char *port = "ircd";
+static char *password;
static char nick[32];
-
-static char bufin[MAXMSG], bufout[MAXMSG];
+static char bufin[4096];
+static char bufout[4096];
static char channel[256];
-static int srv;
static time_t trespond;
+static FILE *srv;
+
+#include "util.c"
-void
-die(const char *errstr, ...) {
+static void
+pout(char *channel, char *fmt, ...) {
+ static char timestr[18];
+ time_t t;
va_list ap;
- va_start(ap, errstr);
- vfprintf(stderr, errstr, ap);
+
+ va_start(ap, fmt);
+ vsnprintf(bufout, sizeof bufout, fmt, ap);
va_end(ap);
- exit(EXIT_FAILURE);
+ t = time(NULL);
+ strftime(timestr, sizeof timestr, "%D %R", localtime(&t));
+ fprintf(stdout, "%-12s: %s %s\n", channel, timestr, bufout);
}
-void
-printl(char *channel, char *msg) {
- static char timestr[18];
- time_t t = time(0);
- strftime(timestr, sizeof timestr, "%D %R", localtime(&t));
- fprintf(stdout, "%-12.12s: %s %s\n", channel, timestr, msg);
+static void
+sout(char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(bufout, sizeof bufout, fmt, ap);
+ va_end(ap);
+ fprintf(srv, "%s\r\n", bufout);
+ fprintf(stderr, "debug: %s\n", bufout);
}
-void
+static void
privmsg(char *channel, char *msg) {
- if(channel[0] == '\0')
+ if(channel[0] == '\0') {
+ pout("", "No channel to send to");
return;
- snprintf(bufout, sizeof bufout, "<%s> %s", nick, msg);
- printl(channel, bufout);
- snprintf(bufout, sizeof bufout, "PRIVMSG %s :%s\r\n", channel, msg);
- write(srv, bufout, strlen(bufout));
+ }
+ pout(channel, "<%s> %s", nick, msg);
+ sout("PRIVMSG %s :%s", channel, msg);
}
-void
+static void
parsein(char *msg) {
- char *p = NULL;
+ char *p;
+ char c;
+
if(msg[0] == '\0')
return;
+ msg = ctok(&msg, '\n');
if(msg[0] != ':') {
privmsg(channel, msg);
return;
}
- if(strncmp(msg + 1, "j ", 2) == 0 && (msg[3] == '#'))
- snprintf(bufout, sizeof bufout, "JOIN %s\r\n", msg + 3);
- else if(strncmp(msg + 1, "l ", 2) == 0)
- snprintf(bufout, sizeof bufout, "PART %s :sic - 250 LOC are to…
- else if(strncmp(msg + 1, "m ", 2) == 0 && (p = strchr(msg + 3, ' '))) {
- *(p++) = '\0';
- privmsg(msg + 3, p);
- return;
- }
- else if(strncmp(msg + 1, "s ", 2) == 0) {
- strncpy(channel, msg + 3, sizeof channel - 1);
- return;
+ c = *++msg;
+ if(!c || !isspace(msg[1]))
+ sout("%s", msg);
+ else {
+ if(msg[1])
+ msg += 2;
+ switch(c) {
+ case 'j':
+ sout("JOIN %s", msg);
+ if(channel[0] == '\0')
+ strlcpy(channel, msg, sizeof channel);
+ break;
+ case 'l':
+ p = tok(&msg);
+ if(!*p)
+ p = channel;
+ if(!*msg)
+ msg = "sic - 250 LOC are too much!";
+ sout("PART %s :%s", p, msg);
+ break;
+ case 'm':
+ p = tok(&msg);
+ privmsg(p, msg);
+ break;
+ case 's':
+ strlcpy(channel, msg, sizeof channel);
+ break;
+ default:
+ sout("%c %s", c, msg);
+ break;
+ }
}
- else
- snprintf(bufout, sizeof bufout, "%s\r\n", msg + 1);
- write(srv, bufout, strlen(bufout));
}
-void
+static void
parsesrv(char *msg) {
- char *chan, *cmd, *p, *txt, *usr;
+ char *cmd, *p, *usr, *txt;
- txt = NULL;
usr = host;
- if(msg == NULL || *msg == '\0' )
+ if(!msg || !*msg)
return;
- if(msg[0] != ':')
- cmd = msg;
- else {
- if(!(p = strchr(msg, ' ')))
+ if(msg[0] == ':') {
+ msg++;
+ p = tok(&msg);
+ if(!*msg)
return;
- *p = '\0';
- usr = msg + 1;
- cmd = ++p;
- if((p = strchr(usr, '!')))
- *p = '\0';
+ usr = ctok(&p, '!');
}
- for(p = cmd; *p != '\0'; p++) /* remove CRLFs */
- if(*p == '\r' || *p == '\n')
- *p = '\0';
- if((p = strchr(cmd, ':'))) {
- *p = '\0';
- txt = ++p;
- }
- if(strncmp("PONG", cmd, 4) == 0)
+ txt = ctok(&msg, '\r');
+ msg = ctok(&txt, ':');
+ cmd = tok(&msg);
+ if(!strcmp("PONG", cmd))
return;
- if(strncmp("PRIVMSG", cmd, 7) == 0 && txt != NULL) {
- if(!(p = strchr(cmd, ' ')))
- return;
- *p = '\0';
- chan = ++p;
- for(; *p != '\0' && *p != ' '; p++);
- *p = '\0';
- snprintf(bufout, sizeof bufout, "<%s> %s", usr, txt);
- printl(chan, bufout);
- }
- else if(strncmp("PING", cmd, 4) == 0 && txt != NULL) {
- snprintf(bufout, sizeof bufout, "PONG %s\r\n", txt);
- write(srv, bufout, strlen(bufout));
- }
+ if(!strcmp("PRIVMSG", cmd))
+ pout(msg, "<%s> %s", usr, txt);
+ else if(!strcmp("PING", cmd))
+ sout("PONG %s", txt);
else {
- if (txt != NULL)
- (void) snprintf(bufout, sizeof bufout, ">< %s: %s", cm…
- else
- (void) snprintf(bufout, sizeof bufout, ">< %s: ", cmd);
- printl(usr, bufout);
- if(strncmp("NICK", cmd, 4) == 0 && strncmp(usr, nick, sizeof n…
- strncpy(nick, txt, sizeof nick - 1);
+ pout(usr, ">< %s: %s", cmd, txt);
+ if(!strcmp("NICK", cmd) && !strcmp(usr, nick))
+ strlcpy(nick, txt, sizeof nick);
}
}
int
-readl(int fd, unsigned int len, char *buf) {
- unsigned int i = 0;
- char c = '\0';
-
- do {
- if(read(fd, &c, sizeof(char)) != (ssize_t) sizeof(char))
- return -1;
- buf[i++] = c;
- }
- while(c != '\n' && i < len);
- buf[i - 1] = '\0';
- return 0;
-}
-
-
-int
-main(const int argc, char *const argv[]) {
- int i;
+main(int argc, char *argv[]) {
+ int i, c;
struct timeval tv;
- static struct addrinfo hints, *res, *r;
- char ping[256];
fd_set rd;
- char *password = NULL;
- strncpy(nick, getenv("USER"), sizeof nick - 1);
- for(i = 1; i < argc; i++)
- if(strcmp(argv[i], "-h") == 0) {
+ strlcpy(nick, getenv("USER"), sizeof nick);
+ for(i = 1; i < argc; i++) {
+ c = argv[i][1];
+ if(argv[i][0] != '-' || argv[i][2])
+ c = -1;
+ switch(c) {
+ case 'h':
if(++i < argc) host = argv[i];
- }
- else if(strcmp(argv[i], "-p") == 0) {
+ break;
+ case 'p':
if(++i < argc) port = argv[i];
- }
- else if(strcmp(argv[i], "-n") == 0) {
- if(++i < argc) strncpy(nick, argv[i], sizeof nick - 1);
- }
- else if(strcmp(argv[i], "-k") == 0) {
+ break;
+ case 'n':
+ if(++i < argc) strlcpy(nick, argv[i], sizeof nick);
+ break;
+ case 'k':
if(++i < argc) password = argv[i];
- }
- else if(strcmp(argv[i], "-v") == 0)
- die("sic-%s, © 2005-2009 sic engineers\n", VERSION);
- else
- die("usage: sic [-h host] [-p port] [-n nick] [-k keyw…
-
- /* init */
- memset(&hints, 0, sizeof hints);
- hints.ai_family = AF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM;
- if(getaddrinfo(host, port, &hints, &res) != 0)
- die("error: cannot resolve hostname '%s'\n", host);
- for(r = res; r; r = r->ai_next) {
- if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)…
- continue;
- if(connect(srv, r->ai_addr, r->ai_addrlen) == 0)
break;
- close(srv);
+ case 'v':
+ eprint("sic-"VERSION", © 2005-2009 Kris Maglione, Ans…
+ default:
+ eprint("usage: sic [-h host] [-p port] [-n nick] [-k k…
+ }
}
- freeaddrinfo(res);
- if(!r)
- die("error: cannot connect to host '%s'\n", host);
-
+ /* init */
+ i = dial(host, port);
+ srv = fdopen(i, "r+");
/* login */
- if (password)
- snprintf(bufout, sizeof bufout,
- "PASS %s\r\nNICK %s\r\nUSER %s localhost %s :%s\r\n",
- password, nick, nick, host, nick);
- else
- snprintf(bufout, sizeof bufout, "NICK %s\r\nUSER %s localhost …
- nick, nick, host, nick);
- write(srv, bufout, strlen(bufout));
- snprintf(ping, sizeof ping, "PING %s\r\n", host);
- channel[0] = '\0';
- setbuf(stdout, NULL); /* unbuffered stdout */
-
+ if(password)
+ sout("PASS %s", password);
+ sout("NICK %s", nick);
+ sout("USER %s localhost %s :%s", nick, host, nick);
+ fflush(srv);
+ setbuf(stdout, NULL);
+ setbuf(srv, NULL);
for(;;) { /* main loop */
FD_ZERO(&rd);
FD_SET(0, &rd);
- FD_SET(srv, &rd);
+ FD_SET(fileno(srv), &rd);
tv.tv_sec = 120;
tv.tv_usec = 0;
- i = select(srv + 1, &rd, 0, 0, &tv);
+ i = select(fileno(srv) + 1, &rd, 0, 0, &tv);
if(i < 0) {
if(errno == EINTR)
continue;
- die("error: error on select()\n");
+ eprint("sic: error on select():");
}
else if(i == 0) {
- if(time(NULL) - trespond >= PINGTIMEOUT)
- die("error: sic shutting down: parse timeout\n…
- write(srv, ping, strlen(ping));
+ if(time(NULL) - trespond >= 300)
+ eprint("sic shutting down: parse timeout\n");
+ sout("PING %s", host);
continue;
}
- if(FD_ISSET(srv, &rd) != 0) {
- if(readl(srv, sizeof bufin, bufin) == -1)
- die("error: remote host closed connection\n");
+ if(FD_ISSET(fileno(srv), &rd)) {
+ if(fgets(bufin, sizeof bufin, srv) == NULL)
+ eprint("sic: remote host closed connection\n");
parsesrv(bufin);
trespond = time(NULL);
}
- if(FD_ISSET(0, &rd) != 0) {
- if(readl(0, sizeof bufin, bufin) == -1)
- die("error: broken pipe\n");
+ if(FD_ISSET(0, &rd)) {
+ if(fgets(bufin, sizeof bufin, stdin) == NULL)
+ eprint("sic: broken pipe\n");
parsein(bufin);
}
}
diff --git a/util.c b/util.c
@@ -0,0 +1,81 @@
+/* See LICENSE file for license details. */
+#include <netdb.h>
+#include <netinet/in.h>
+#include <sys/socket.h>
+
+static void
+eprint(const char *fmt, ...) {
+ va_list ap;
+
+ va_start(ap, fmt);
+ vsnprintf(bufout, sizeof bufout, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "%s", bufout);
+ if(fmt[0] && fmt[strlen(fmt) - 1] == ':')
+ fprintf(stderr, " %s\n", strerror(errno));
+ exit(1);
+}
+
+static int
+dial(char *host, char *port) {
+ static struct addrinfo hints;
+ int srv;
+ struct addrinfo *res, *r;
+
+ memset(&hints, 0, sizeof hints);
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM;
+ if(getaddrinfo(host, port, &hints, &res) != 0)
+ eprint("error: cannot resolve hostname '%s':", host);
+ for(r = res; r; r = r->ai_next) {
+ if((srv = socket(r->ai_family, r->ai_socktype, r->ai_protocol)…
+ continue;
+ if(connect(srv, r->ai_addr, r->ai_addrlen) == 0)
+ break;
+ close(srv);
+ }
+ freeaddrinfo(res);
+ if(!r)
+ eprint("error: cannot connect to host '%s'\n", host);
+ return srv;
+}
+
+#define strlcpy _strlcpy
+static void
+strlcpy(char *to, const char *from, int l) {
+ memccpy(to, from, '\0', l);
+ to[l-1] = '\0';
+}
+
+static void
+eat(char **s, int (*p)(int), int r) {
+ char *q;
+
+ for(q = *s; *q && p(*q) == r; q++)
+ ;
+ *s = q;
+}
+
+static char*
+tok(char **s) {
+ char *p;
+
+ eat(s, isspace, 1);
+ p = *s;
+ eat(s, isspace, 0);
+ if(**s)
+ *(*s)++ = '\0';
+ return p;
+}
+
+static char*
+ctok(char **s, int c) {
+ char *p, *q;
+
+ q = *s;
+ for(p = q; *p && *p != c; p++)
+ ;
+ if(*p) *p++ = '\0';
+ *s = p;
+ return q;
+}
You are viewing proxied material from suckless.org. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.