head 1.10;
access;
symbols
L2_0_9_13:1.10
FSL_1_7_0:1.10
L2_0_9_12:1.10
LMTP2NNTP_1_4_1:1.10
LMTP2NNTP_1_4_0:1.10
FSL_1_6_1:1.10
L2_0_9_11:1.10
FSL_1_6_0:1.9
FSL_1_6b2:1.9
L2_0_9_10:1.9
FSL_1_6b1:1.9
L2_0_9_9:1.9
LMTP2NNTP_1_3_0:1.8
LMTP2NNTP_1_3b2:1.8
LMTP2NNTP_1_3b1:1.8
LMTP2NNTP_1_3a3:1.8
FSL_1_5_0:1.8
LMTP2NNTP_1_3a2:1.8
FSL_1_5a3:1.8
LMTP2NNTP_1_3a1:1.8
FSL_1_5a2:1.8
L2_0_9_8:1.8
FSL_1_5a1:1.8
L2_0_9_7:1.8
L2_0_9_6:1.8
FSL_1_4_0:1.8
FSL_1_4b1:1.8
L2_0_9_5:1.8
FSL_1_4a1:1.8
FSL_1_3_0:1.8
FSL_1_3b1:1.8
L2_0_9_4:1.8
FSL_1_2_1:1.8
L2_0_9_3:1.8
FSL_1_2_0:1.8
L2_0_9_2:1.8
FSL_1_1_0:1.8
FSL_1_1b1:1.8
WORKOFF:1.8.0.2
WORKOFF_BP:1.8
FSL_1_0_8:1.8
LMTP2NNTP_1_2_0:1.8
LMTP2NNTP_1_2b4:1.8
LMTP2NNTP_1_2b3:1.8
LMTP2NNTP_1_2b2:1.8
LMTP2NNTP_1_2b1:1.8
LMTP2NNTP_1_2a8:1.8
LMTP2NNTP_1_2a7:1.8
FSL_1_0_7:1.8
FSL_1_0_6:1.7
FSL_1_0_5:1.7
FSL_1_0_4:1.7
L2_0_9_1:1.7
FSL_1_0_3:1.7
LMTP2NNTP_1_2a6:1.7
FSL_1_0_2:1.7
FSL_1_0_1:1.7
FSL_1_0_0:1.7
FSL_0_9_0:1.7
L2_0_9_0:1.7
FSL_0_1_12:1.6
FSL_0_1_11:1.6
FSL_0_1_10:1.6
FSL_0_1_9:1.6
FSL_0_1_8:1.6
FSL_0_1_7:1.6
FSL_0_1_6:1.6
FSL_0_1_5:1.5
FSL_0_1_1:1.5
LMTP2NNTP_1_2a5:1.5
LMTP2NNTP_1_2a4:1.5
LMTP2NNTP_1_2a3:1.5
LMTP2NNTP_1_2a1:1.4
LMTP2NNTP_1_1_1:1.1
LMTP2NNTP_1_1_0:1.1
LMTP2NNTP_1_1b4:1.1
LMTP2NNTP_1_1b3:1.1
L2_CHANNEL_ONLY_REVAMPING_BEFORE:1.2
LMTP2NNTP_1_1b2:1.1
LMTP2NNTP_1_1b1:1.1;
locks; strict;
comment @ * @;
1.10
date 2005.10.03.08.08.11; author rse; state Exp;
branches;
next 1.9;
1.9
date 2005.01.24.15.03.17; author rse; state Exp;
branches;
next 1.8;
1.8
date 2003.01.06.11.41.51; author rse; state Exp;
branches;
next 1.7;
1.7
date 2002.07.30.19.08.24; author rse; state Exp;
branches;
next 1.6;
1.6
date 2002.07.25.13.33.00; author thl; state Exp;
branches;
next 1.5;
1.5
date 2002.01.02.17.07.38; author rse; state Exp;
branches;
next 1.4;
1.4
date 2001.11.07.13.05.20; author rse; state Exp;
branches;
next 1.3;
1.3
date 2001.11.07.11.37.18; author rse; state Exp;
branches;
next 1.2;
1.2
date 2001.10.19.13.06.35; author rse; state Exp;
branches;
next 1.1;
1.1
date 2001.10.04.14.58.29; author ms; state Exp;
branches;
next ;
desc
@@
1.10
log
@Adjust copyright messages for new year 2005.
@
text
@/*
** OSSP l2 - Flexible Logging
** Copyright (c) 2001-2005 Cable & Wireless
** Copyright (c) 2001-2005 The OSSP Project
** Copyright (c) 2001-2005 Ralf S. Engelschall
**
** This file is part of OSSP l2, a flexible logging library which
** can be found at http://www.ossp.org/pkg/lib/l2/.
**
** Permission to use, copy, modify, and distribute this software for
** any purpose with or without fee is hereby granted, provided that
** the above copyright notice and this permission notice appear in all
** copies.
**
** THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
** WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
** IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
** CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
** USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
** ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
** OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
**
** l2_ch_irc.c: Internet Relay Chat (IRC) channel implementation
*/
#include "l2.h"
#include "l2_p.h"
#include
#include
#include
#include
#include
/* declare private channel configuration */
typedef struct {
char *cpLocalProg;
char *cpLocalHost;
char *cpLocalUser;
char *cpPassword;
char *cpNickname;
char *cpUsername;
char *cpRealname;
char *cpChannel;
int bJoin;
char *cpHost;
char *cpPort;
long nTimeout;
sa_addr_t *saaServer;
sa_t *saServer;
} l2_ch_irc_t;
/* create channel */
static l2_result_t hook_create(l2_context_t *ctx, l2_channel_t *ch)
{
l2_ch_irc_t *cfg;
struct utsname uts;
struct passwd *pw;
/* allocate private channel configuration */
if ((cfg = (l2_ch_irc_t *)malloc(sizeof(l2_ch_irc_t))) == NULL)
return L2_ERR_ARG;
/* initialize configuration with reasonable defaults */
cfg->cpLocalProg = NULL;
if ((pw = getpwuid(getuid())) != NULL)
cfg->cpLocalUser = strdup(pw->pw_name);
else
cfg->cpLocalUser = l2_util_asprintf("uid#%d", getuid());
if (uname(&uts) == 0)
cfg->cpLocalHost = strdup(uts.nodename);
else
cfg->cpLocalHost = strdup("localhost");
cfg->cpPassword = strdup("*");
cfg->cpNickname = strdup(cfg->cpLocalUser);
cfg->cpUsername = l2_util_asprintf("%s@@%s", cfg->cpLocalUser, cfg->cpLocalHost);
cfg->cpRealname = strdup(cfg->cpUsername);
cfg->cpChannel = strdup("#l2");
cfg->bJoin = 1;
cfg->cpHost = NULL;
cfg->cpPort = strdup("6667"); /*FIXME[thl] better use getservbyname()*/
cfg->nTimeout = 30;
cfg->saaServer = NULL;
cfg->saServer = NULL;
/* link private channel configuration into channel context */
ctx->vp = cfg;
return L2_OK;
}
/* configure channel */
static l2_result_t hook_configure(l2_context_t *ctx, l2_channel_t *ch, const char *fmt, va_list ap)
{
l2_ch_irc_t *cfg = (l2_ch_irc_t *)ctx->vp;
l2_param_t pa[12];
l2_result_t rv;
l2_env_t *env;
/* feed and call generic parameter parsing engine */
L2_PARAM_SET(pa[0], progname, STR, &cfg->cpLocalProg);
L2_PARAM_SET(pa[1], localhost, STR, &cfg->cpLocalHost);
L2_PARAM_SET(pa[2], localuser, STR, &cfg->cpLocalUser);
L2_PARAM_SET(pa[3], nickname, STR, &cfg->cpNickname);
L2_PARAM_SET(pa[4], username, STR, &cfg->cpUsername);
L2_PARAM_SET(pa[5], realname, STR, &cfg->cpRealname);
L2_PARAM_SET(pa[6], channel, STR, &cfg->cpChannel);
L2_PARAM_SET(pa[7], join, INT, &cfg->bJoin);
L2_PARAM_SET(pa[8], host, STR, &cfg->cpHost);
L2_PARAM_SET(pa[9], port, STR, &cfg->cpPort);
L2_PARAM_SET(pa[10], timeout, INT, &cfg->nTimeout);
L2_PARAM_END(pa[11]);
l2_channel_env(ch, &env);
rv = l2_util_setparams(env, pa, fmt, ap);
return rv;
}
/* open channel */
static l2_result_t hook_open(l2_context_t *ctx, l2_channel_t *ch)
{
l2_ch_irc_t *cfg = (l2_ch_irc_t *)ctx->vp;
sa_rc_t rc;
/* make sure a path was set */
if (cfg->cpHost == NULL)
return L2_ERR_USE;
/* create socket address */
if ((rc = sa_addr_create(&cfg->saaServer)) != SA_OK)
return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
if ((rc = sa_addr_u2a(cfg->saaServer, "inet://%s:%s",
cfg->cpHost, cfg->cpPort)) != SA_OK)
return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
/* create socket */
if ((rc = sa_create(&cfg->saServer)) != SA_OK)
return (rc == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
/* configure socket parameters */
sa_timeout(cfg->saServer, SA_TIMEOUT_ALL, cfg->nTimeout, 0);
sa_timeout(cfg->saServer, SA_TIMEOUT_READ, 2, 0);
sa_buffer(cfg->saServer, SA_BUFFER_READ, 4096);
sa_buffer(cfg->saServer, SA_BUFFER_WRITE, 4096);
return L2_OK;
}
/* write to channel */
static l2_result_t hook_write(l2_context_t *ctx, l2_channel_t *ch,
l2_level_t level, const char *buf, size_t buf_size)
{
l2_ch_irc_t *cfg = (l2_ch_irc_t *)ctx->vp;
char caLine[1024];
sa_t *sa;
sa_addr_t *saa;
sa_rc_t sa_rv;
size_t n;
struct tm *tm;
time_t t;
char caDate[80];
/*
* Sample IRC client transaction for reference:
* | PASS secret
* | NICK rse
* | USER rse@@engelschall.com 0 * :Ralf S. Engelschall
* | :irc.engelschall.com 001 rse :Welcome to the Internet Relay Network rse!~rse@@dev10.dev.de.cw.net
* | :irc.engelschall.com 002 rse :Your host is irc.engelschall.com, running version 2.10.3p2
* | :irc.engelschall.com 003 rse :This server was created Wed Oct 17 2001 at 18:06:57 CEST
* | :irc.engelschall.com 004 rse irc.engelschall.com 2.10.3p2 aoOirwabeiIklmnoOpqrstv
* | :irc.engelschall.com 251 rse :There are 1 users and 0 services on 1 servers
* | :irc.engelschall.com 254 rse 11 :channels formed
* | :irc.engelschall.com 255 rse :I have 1 users, 0 services and 0 servers
* | :irc.engelschall.com 375 rse :- irc.engelschall.com Message of the Day -
* | :irc.engelschall.com 372 rse :- 17/10/2001 19:32
* | :irc.engelschall.com 372 rse :- Welcome to the Engelschall VISP IRC Service.
* | :irc.engelschall.com 376 rse :End of MOTD command.
* | :rse MODE rse :+i
* | JOIN #dev
* | :rse!~rse@@dev10.dev.de.cw.net JOIN :#dev
* | :irc.engelschall.com 353 rse = #dev :@@rse
* | :irc.engelschall.com 366 rse #dev :End of NAMES list.
* | PRIVMSG #dev :Sample log message line 1
* | PRIVMSG #dev :Sample log message line 2
* | PRIVMSG #dev :Sample log message line 3
* | QUIT
* | ERROR :Closing Link: rse[~rse@@dev10.dev.de.cw.net] (I Quit)
*
* For more details read:
* RFC 2812: Internet Relay Chat: Client Protocol; C. Kalt; April 2000.
*/
/* establish connection to server */
saa = cfg->saaServer;
sa = cfg->saServer;
if ((sa_rv = sa_connect(sa, saa)) != SA_OK)
return (sa_rv == SA_ERR_SYS ? L2_ERR_SYS : L2_ERR_INT);
/* determine current time */
t = time(NULL);
tm = localtime(&t);
strftime(caDate, sizeof(caDate), "%a, %d %b %Y %H:%M:%S %Z", tm);
/* write transaction to IRC server */
sa_writef(sa, "PASS %s\r\n", cfg->cpPassword);
sa_writef(sa, "NICK %s\r\n", cfg->cpNickname);
sa_writef(sa, "USER %s 0 * :%s\r\n", cfg->cpUsername, cfg->cpRealname);
if (cfg->bJoin)
sa_writef(sa, "JOIN %s\r\n", cfg->cpChannel);
sa_writef(sa, "PRIVMSG %s :", cfg->cpChannel);
if (cfg->cpLocalProg != NULL)
sa_writef(sa, "Program %s of user %s on host %s logged at %s:\r\n",
cfg->cpLocalProg, cfg->cpLocalUser, cfg->cpLocalHost, caDate);
else
sa_writef(sa, "A program of user %s on host %s logged at %s:\r\n",
cfg->cpLocalUser, cfg->cpLocalHost, caDate);
sa_writef(sa, "PRIVMSG %s :", cfg->cpChannel);
sa_write(sa, buf, buf_size-1, NULL);
sa_writef(sa, "\r\n");
if (cfg->bJoin)
sa_writef(sa, "PART %s\r\n", cfg->cpChannel);
sa_writef(sa, "QUIT\r\n");
sa_flush(sa);
/* shutdown write side of connection to server */
sa_shutdown(sa, "w");
/* still read server responses */
while (sa_readln(sa, caLine, sizeof(caLine), &n) == SA_OK)
;
/* shutdown read side of connection to server */
sa_shutdown(sa, "r");
return L2_OK;
}
/* close channel */
static l2_result_t hook_close(l2_context_t *ctx, l2_channel_t *ch)
{
l2_ch_irc_t *cfg = (l2_ch_irc_t *)ctx->vp;
/* destroy remote address */
if (cfg->saServer != NULL) {
sa_destroy(cfg->saServer);
cfg->saServer = NULL;
}
if (cfg->saaServer != NULL) {
sa_addr_destroy(cfg->saaServer);
cfg->saaServer = NULL;
}
return L2_OK;
}
/* destroy channel */
static l2_result_t hook_destroy(l2_context_t *ctx, l2_channel_t *ch)
{
l2_ch_irc_t *cfg = (l2_ch_irc_t *)ctx->vp;
/* destroy channel configuration */
if (cfg->cpLocalProg != NULL)
free(cfg->cpLocalProg);
if (cfg->cpLocalHost != NULL)
free(cfg->cpLocalHost);
if (cfg->cpLocalUser != NULL)
free(cfg->cpLocalUser);
if (cfg->cpPassword != NULL)
free(cfg->cpPassword);
if (cfg->cpNickname != NULL)
free(cfg->cpNickname);
if (cfg->cpUsername != NULL)
free(cfg->cpUsername);
if (cfg->cpRealname != NULL)
free(cfg->cpRealname);
if (cfg->cpChannel != NULL)
free(cfg->cpChannel);
if (cfg->cpHost != NULL)
free(cfg->cpHost);
if (cfg->cpPort != NULL)
free(cfg->cpPort);
free(cfg);
return L2_OK;
}
/* exported channel handler structure */
l2_handler_t l2_handler_irc = {
"irc",
L2_CHANNEL_OUTPUT,
hook_create,
hook_configure,
hook_open,
hook_write,
NULL,
hook_close,
hook_destroy
};
@
1.9
log
@Adjust copyright messages for new year 2005.
@
text
@d3 3
a5 3
** Copyright (c) 2001-2004 Cable & Wireless
** Copyright (c) 2001-2004 The OSSP Project
** Copyright (c) 2001-2004 Ralf S. Engelschall
@
1.8
log
@- remove trailing whitespaces
- adjust copyright messages
- consistently use "OSSP l2"
- consistently talk about "Flexible Logging"
- use standard OSSP ASCII-art
@
text
@d3 3
a5 3
** Copyright (c) 2001-2003 Cable & Wireless Deutschland GmbH
** Copyright (c) 2001-2003 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2003 Ralf S. Engelschall
@
1.7
log
@polish for release
@
text
@d2 4
a5 3
** OSSP l2 - Logging Library
** Copyright (c) 2001-2002 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001-2002 Cable & Wireless Deutschland (http://www.cw.com/de/)
d7 1
a7 1
** This file is part of OSSP L2, a flexible logging library which
d53 1
a53 1
long nTimeout;
d101 1
a101 1
l2_param_t pa[12];
d137 1
a137 1
if ((rc = sa_addr_u2a(cfg->saaServer, "inet://%s:%s",
d167 2
a168 2
/*
d180 1
a180 1
* | :irc.engelschall.com 375 rse :- irc.engelschall.com Message of the Day -
d187 1
a187 1
* | :irc.engelschall.com 353 rse = #dev :@@rse
d190 1
a190 1
* | PRIVMSG #dev :Sample log message line 2
d218 1
a218 1
sa_writef(sa, "Program %s of user %s on host %s logged at %s:\r\n",
d221 1
a221 1
sa_writef(sa, "A program of user %s on host %s logged at %s:\r\n",
@
1.6
log
@proposal to use getservbyname() or successor
@
text
@d2 1
a2 1
** L2 - OSSP Logging Library
d7 1
a7 1
** can be found at http://www.ossp.org/pkg/l2/.
@
1.5
log
@bump copyright year
@
text
@d85 1
a85 1
cfg->cpPort = strdup("6667");
@
1.4
log
@Hell, I've seldom seen that it is needed to prepare and adjust such a
lot of subtle details of existing code in order to make a new feature
implementable in a straight-forward way. Anyway, here comes one more
preparation change for the forthcoming channel tree specification
parser:
- change l2_util_setparam() to take an l2_env_t parameter
which allows the function to report better error messages.
- completely rewrite l2_util_setparam() to support calls
l2_channel_configure(ch, "n1=v1,n2=v2,n3=v3")
and/or
l2_channel_configure(ch, "n1=%x,n2=%x,n3=%x", v1, v2, v3)
instead of
l2_channel_configure(ch, "n1,n2,n3", v1, v2, v3)
This is both a step forward to make the interface of
l2_channel_configure() more flexible (because one now can directly
inline values instead of having them to be passed explicitly) and
allows the spec parser not having to know the type (integer, floating
point or string) of a parameter (which is important if one wants the
parser to be independent of the implementing channel handlers).
@
text
@d3 2
a4 2
** Copyright (c) 2001 The OSSP Project (http://www.ossp.org/)
** Copyright (c) 2001 Cable & Wireless Deutschland (http://www.cw.com/de/)
@
1.3
log
@More preparations for forthcoming channel tree specification parser
(especially to allow the parser to determine the handler structure
from a handler name without introducing another and this way redundant
sub-API):
- add "char *name" to l2_handler_t in order to tag each
handler structure with the corresponding channel name
- add l2_env_handler() function to add handler to
l2_env_t objects. All l2_handler_xxxx are automatically
pre-configured there after l2_env_create().
- change l2_channel_create() to take a "const char *name"
(handler name) instead of the "l2_handler_t *h" (handler
pointer) to make the stuff consistent and more clear.
- adjust l2_test.c to reflect the changes.
@
text
@d102 1
d105 11
a115 11
L2_PARAM_SET(pa[0], progname, STRING, &cfg->cpLocalProg);
L2_PARAM_SET(pa[1], localhost, STRING, &cfg->cpLocalHost);
L2_PARAM_SET(pa[2], localuser, STRING, &cfg->cpLocalUser);
L2_PARAM_SET(pa[3], nickname, STRING, &cfg->cpNickname);
L2_PARAM_SET(pa[4], username, STRING, &cfg->cpUsername);
L2_PARAM_SET(pa[5], realname, STRING, &cfg->cpRealname);
L2_PARAM_SET(pa[6], channel, STRING, &cfg->cpChannel);
L2_PARAM_SET(pa[7], join, INT, &cfg->bJoin);
L2_PARAM_SET(pa[8], host, STRING, &cfg->cpHost);
L2_PARAM_SET(pa[9], port, STRING, &cfg->cpPort);
L2_PARAM_SET(pa[10], timeout, INT, &cfg->nTimeout);
d117 2
a118 1
rv = l2_util_setparams(pa, fmt, ap);
@
1.2
log
@First cut for an IRC output channel. This beast is able to send the
message to the IRC channel, but the whole client/server communication is
not quite correct because I don't know how to correctly deal with the
server responses due to the fact that the IRC protocol (according to the
RFC) is asynchronous and there can be replies but there have no to be
replies. The effect is that currently we see:
| *** l2_test (~rse@@dev10.dev.de.cw.net) has joined channel #l2
| A program of user rse on host dev10.dev.de.cw.net logged at Fri, 19
| Oct 2001 15:01:27 CEST:
| 0Checking localhost foo [12345/myparm]
| <66:6f:6f:01:62:61:72>
| *** Signoff: l2_test (EOF From client)
As you can see, the "EOF from client" is the problem. Currently it is
caused by a sa_shutdown(), but I don't know how to program it. So, feel
free to jump in and fix the communication of this channel.
@
text
@d292 1
@
1.1
log
@Birth of IRC channel.
@
text
@d27 1
a27 1
** l2_ch_irc.c: internet relay chat channel implementation
d31 1
d33 25
d60 33
d96 1
d99 20
a118 1
return L2_OK;
d121 1
d124 24
d151 3
a153 1
static l2_result_t hook_write(l2_context_t *ctx, l2_channel_t *ch, l2_level_t level, const char *buf, size_t buf_size)
d155 83
d241 1
d244 12
d259 1
d262 25
d290 1
d297 1
@