This repository has been archived on 2024-03-02. You can view files and clone it, but cannot push or open issues or pull requests.
probotic/src/main.c
2023-08-17 04:24:29 -06:00

178 wiersze
3.8 KiB
C

/* main.c */
#define VERSION_STRING "2"
/* Parses the format username[:password]@server[:port]
* user:password@server:port = userNULpasswordNULserverNUL (port N/A)
*/
DECL int
parse_url(char * url)
{
size_t len = strlen(url);
size_t sep = 0, ls = 0, rs;
while (++sep < len && url[sep] != '@');
while (++ls < len && url[ls] != ':')
{
if (ls >= sep)
{ ls = 0; break; }
}
rs = sep;
while (++rs < len && url[rs] != ':');
if (rs == len)
{ rs = 0; }
creds.username = url;
url[ls ? ls : sep] = '\0';
if (ls)
{
creds.password = url + ls + 1;
url[sep] = '\0';
}
creds.server = url + sep + 1;
if (rs)
{
url[rs] = '\0';
creds.port = atoi(url + rs + 1);
}
return 0;
}
DECL void
rope(void)
{
if (session)
{ irc_destroy_session(session); }
api_rope();
}
/* All possible failures / successes wipe the password from memory. */
DECL int
init(void)
{
int ret = 0;
srand(time(NULL));
memset(&callbacks, 0, sizeof(callbacks));
callbacks.event_connect = event_connect;
callbacks.event_channel = event_channel;
if(!api_init())
{
session = irc_create_session(&callbacks);
if (!session)
{
ERRMSG("Error creating IRC session");
ret = 1;
}
else
{
atexit(rope);
if (creds.username == NULL ||
creds.server == NULL)
{ ERRMSG("Server and Username required. Stopping now");
exit(1); }
if (irc_connect(session,
creds.server, creds.port, creds.password,
creds.username, creds.username, creds.username))
{
fprintf(stderr, "IRC ERROR: %s\n", irc_strerror(irc_errno(session)));
ret = 1;
}
}
}
else
{
ERRMSG("Error initializing database.");
ret = 1;
}
if (creds.password)
{ memset(creds.password, '\0', strlen(creds.password)); }
return ret;
}
DECL int
loop(void)
{
/* We should figure out how the failure happens so we can tell the user that. */
if (irc_run(session) != 0)
{ ERR(1, "Error running IRC session\nPossible issue: bad URL,"
" no network connection, bad port, refused connection."); }
return 0;
}
DECL void
help(void)
{
ERRMSG(PROGN ": usage\n"
"-channel CHANNEL - Sets the target channel\n"
"-url URL - Sets the target URL\n"
"-db DBFILE - Sets the database file (default: probotic_data.sqlite)\n"
"-identify PASSWORD - Identifies against NickServ\n"
"-version - Prints version information\n"
"-help - Prints this information\n"
"\nUse format username[:password]@server[:port], port defaults to 6667.\n");
}
DECL void
version(void)
{
ERRMSG(PROGN ": " VERSION_STRING);
}
int
main (int argc,
char ** argv)
{
#ifdef NO_LOGGING
freopen(stdout, "/dev/null");
freopen(stderr, "/dev/null");
#endif
if (argc > 1)
{
char * arg;
while (++argv, --argc)
{
arg = *argv;
if (*arg == '-')
{
++arg;
if (strcmp(arg, "version") == 0)
{
version();
return 1;
}
else if (strcmp(arg, "help") == 0)
{ goto help; }
if (argc < 2)
{ goto help; }
if (strcmp(arg, "db") == 0)
{ db = argv[1]; }
else if (strcmp(arg, "url") == 0)
{ parse_url(argv[1]); }
else if (strcmp(arg, "channel") == 0)
{ creds.channel = argv[1]; }
else if (strcmp(arg, "identify") == 0)
{ ident_password = argv[1]; }
else
{
ERR(1,"Unknown command provided");
}
++argv; --argc;
}
else
{ goto help; }
}
}
fprintf(stderr, "Connecting to %s:%s@%s:%d\nChannel: %s\n",
creds.username, creds.password,
creds.server, creds.port, creds.channel);
if (init())
{ return 1; }
return loop();
help:
help();
return 1;
}