Probiotics (in bot form) for programming.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.

177 lines
4.1KB

  1. /* main.c */
  2. #define VERSION_STRING "1"
  3. /* Parses the format username[:password]@server[:port] */
  4. #define GENCOPY(dst,src,l) \
  5. do \
  6. { \
  7. dst = malloc(sep + 1); \
  8. if (dst) \
  9. { \
  10. strncpy(dst,src,l); \
  11. dst[len] = '\0'; \
  12. } \
  13. else \
  14. { return 1; } \
  15. } while (0)
  16. DECL int
  17. parse_url(char const * url)
  18. {
  19. size_t len = strlen(url);
  20. size_t sep = 0, ls = 0, rs;
  21. while (++sep < len && url[sep] != '@');
  22. while (++ls < len && url[ls] != ':')
  23. {
  24. if (ls >= sep)
  25. { ls = 0; break; }
  26. }
  27. rs = sep;
  28. while (++rs < len && url[rs] != ':');
  29. if (rs == len)
  30. { rs = 0; }
  31. GENCOPY(creds.username, url, ls ? ls : sep);
  32. if (ls)
  33. {
  34. GENCOPY(creds.password, url + ls + 1, sep - ls - 1);
  35. }
  36. if (rs)
  37. {
  38. GENCOPY(creds.server, url + sep + 1, rs - sep - 1);
  39. creds.port = atoi(url + rs + 1);
  40. }
  41. else
  42. {
  43. GENCOPY(creds.server, url + sep + 1, len - sep - 1);
  44. }
  45. return 0;
  46. }
  47. #undef GENCOPY
  48. DECL void
  49. rope(void)
  50. {
  51. if (session)
  52. { irc_destroy_session(session); }
  53. api_rope();
  54. }
  55. DECL int
  56. init(void)
  57. {
  58. srand(time(NULL));
  59. if(api_init())
  60. { ERR(DB_ERROR, "Error initializing database."); }
  61. memset(&callbacks, 0, sizeof(callbacks));
  62. callbacks.event_connect = event_connect;
  63. callbacks.event_channel = event_channel;
  64. session = irc_create_session(&callbacks);
  65. if (!session)
  66. {
  67. ERRMSG("Error creating IRC session");
  68. goto fail;
  69. }
  70. atexit(rope);
  71. assert(creds.username != NULL);
  72. assert(creds.server != NULL);
  73. if (irc_connect(session,
  74. creds.server, creds.port, creds.password,
  75. creds.username, creds.username, creds.username))
  76. {
  77. fprintf(stderr, "IRC ERROR: %s\n", irc_strerror(irc_errno(session)));
  78. exit(1);
  79. }
  80. FULL_FREE(creds.password);
  81. return 0;
  82. fail:
  83. FULL_FREE(creds.password);
  84. return 1;
  85. }
  86. DECL int
  87. loop(void)
  88. {
  89. /* We should figure out how the failure happens so we can tell the user that. */
  90. if (irc_run(session) != 0)
  91. { ERR(1, "Error running IRC session\nPossible issue: bad URL,"
  92. " no network connection, bad port, refused connection."); }
  93. return 0;
  94. }
  95. DECL void
  96. help(void)
  97. {
  98. ERRMSG(PROGN ": usage\n"
  99. "-channel CHANNEL - Sets the target channel\n"
  100. "-url URL - Sets the target URL\n"
  101. "-db DBFILE - Sets the database file (default: probotic_data.sqlite)\n"
  102. "-identify PASSWORD - Identifies against NickServ\n"
  103. "-version - Prints Version information\n"
  104. "-help - Prints this information\n"
  105. "\nUse format username[:password]@server[:port], port defaults to 6667.\n");
  106. }
  107. DECL void
  108. version(void)
  109. {
  110. ERRMSG(PROGN ": " VERSION_STRING);
  111. }
  112. int
  113. main (int argc,
  114. char ** argv)
  115. {
  116. if (argc > 1)
  117. {
  118. char * arg;
  119. while (++argv, --argc)
  120. {
  121. arg = *argv;
  122. if (*arg == '-')
  123. {
  124. ++arg;
  125. if (strcmp(arg, "version") == 0)
  126. {
  127. version();
  128. return 1;
  129. }
  130. else if (strcmp(arg, "help") == 0)
  131. { goto help; }
  132. if (argc < 2)
  133. { goto help; }
  134. if (strcmp(arg, "db") == 0)
  135. { db = argv[1]; }
  136. else if (strcmp(arg, "url") == 0)
  137. { parse_url(argv[1]); }
  138. else if (strcmp(arg, "channel") == 0)
  139. { free(creds.channel); creds.channel = strdup(argv[1]); }
  140. else if (strcmp(arg, "identify") == 0)
  141. { ident_password = argv[1]; }
  142. else
  143. {
  144. ERR(1,"Unknown command provided");
  145. }
  146. ++argv; --argc;
  147. }
  148. else
  149. { goto help; }
  150. }
  151. }
  152. atexit(creds_free);
  153. fprintf(stderr, "Connecting to %s:%s@%s:%d\nChannel: %s\n",
  154. creds.username, creds.password,
  155. creds.server, creds.port, creds.channel);
  156. if (init())
  157. { return 1; }
  158. return loop();
  159. help:
  160. help();
  161. return 1;
  162. }