Probiotics (in bot form) for programming.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
このリポジトリはアーカイブされています。 ファイルの閲覧とクローンは可能ですが、プッシュや、課題・プルリクエストのオープンはできません。

281 行
7.0KB

  1. /* irc.c - IRC interface */
  2. #define PREFIX_COMMAND_CHAR '!'
  3. #define IRCMSG(msg) irc_cmd_msg(session, creds.channel, msg)
  4. #define MAX(a,b) (a) > (b)
  5. typedef struct
  6. {
  7. char * username;
  8. char * password;
  9. char * channel;
  10. char * server;
  11. int port;
  12. } creds_t;
  13. VARDECL creds_t creds =
  14. {
  15. .username = NULL,
  16. .password = NULL,
  17. .channel = NULL,
  18. .server = NULL, /* localhost? */
  19. #ifndef IRC_SSL_SUPPORT
  20. .port = 6667
  21. #else
  22. .port = 6669
  23. #endif /* !IRC_SSL_SUPPORT */
  24. };
  25. VARDECL char * ident_password = NULL;
  26. VARDECL irc_session_t * session;
  27. VARDECL irc_callbacks_t callbacks;
  28. VARDECL char * current_username = NULL;
  29. VARDECL char const * help_msg =
  30. /* IRC_GREEN "!help " IRC_STOP " : This message\n" */
  31. IRC_GREEN "!remind " IRC_STOP " : Dump current assignment\n"
  32. IRC_GREEN "!reroll " IRC_STOP " : Rerolls assignment\n"
  33. /* IRC_GREEN "!repo <link>" IRC_STOP " : Sets project repository link\n" */
  34. /* IRC_GREEN "!raw <sql> " IRC_STOP " : Execute raw SQL\n" */
  35. /* IRC_GREEN "!dump " IRC_STOP " : List all possible projects\n" */
  36. IRC_GREEN "!request " IRC_STOP " : Request personal project\n"
  37. IRC_GREEN "!remind " IRC_STOP " : Prints your assignment\n";
  38. DECL void parse_command(char const * cmd);
  39. DECL char *
  40. get_username(const char * origin)
  41. {
  42. const char USERNAME_TERMINATOR = '!';
  43. int i = 0;
  44. char * r;
  45. while (origin[i] != USERNAME_TERMINATOR)
  46. { i++; }
  47. r = (char *) malloc(i + 1);
  48. if (r)
  49. {
  50. strncpy(r, origin, i);
  51. r[i] = '\00';
  52. }
  53. return r;
  54. }
  55. DECL void
  56. ircmsg(char const * reciever, char const * fmt,
  57. ...)
  58. {
  59. va_list args;
  60. char * fmtdmsg;
  61. char * swp;
  62. const char * delim = "\n";
  63. char * data;
  64. if(!strcmp(fmt, "") || fmt == NULL)
  65. { return; }
  66. va_start(args, fmt);
  67. if(vasprintf(&fmtdmsg, fmt, args) == -1)
  68. { exit(1); }
  69. puts(fmtdmsg);
  70. data = strtok(fmtdmsg, delim);
  71. do
  72. {
  73. swp = irc_color_convert_to_mirc(data);
  74. irc_cmd_msg(session, reciever, swp);
  75. free(swp);
  76. } while((data = strtok(NULL, delim), data));
  77. free(fmtdmsg);
  78. va_end(args);
  79. }
  80. DECL void
  81. event_connect(irc_session_t * lsession,
  82. char const * event,
  83. char const * origin,
  84. char const ** params,
  85. unsigned int count)
  86. {
  87. (void) event;
  88. (void) origin;
  89. (void) params;
  90. (void) count;
  91. /* msg ChanServ IDENTIFY? */
  92. irc_cmd_join(lsession, creds.channel, 0);
  93. if (ident_password)
  94. {
  95. ircmsg("NickServ", "IDENTIFY %s", ident_password);
  96. memset(ident_password, '\0', strlen(ident_password));
  97. }
  98. #ifdef INITIAL_ASSIGNMENT_MESSAGE
  99. if(is_no_assignment(creds.channel))
  100. {
  101. ircmsg(creds.channel, IRC_RED "No assignment for this channel. Finding a new..." IRC_STOP);
  102. random_assign(creds.channel);
  103. }
  104. ircmsg(creds.channel, remind(creds.channel));
  105. #endif /* INITIAL_ASSIGNMENT_MESSAGE */
  106. }
  107. DECL void
  108. event_channel(irc_session_t * lsession,
  109. char const * event,
  110. char const * origin,
  111. char const ** params,
  112. unsigned int count)
  113. {
  114. /* char const * channel = params[0]; */
  115. char const * message = params[1];
  116. (void) lsession;
  117. (void) event;
  118. (void) origin;
  119. /* (void) channel; */
  120. (void) message;
  121. (void) count;
  122. /* Logs the message */
  123. printf(message);
  124. /* parses the command */
  125. if (*message == PREFIX_COMMAND_CHAR)
  126. { current_username = get_username(origin); }
  127. if (!current_username ||
  128. message[1] == '\0')
  129. { return; }
  130. parse_command(message+1);
  131. free(current_username);
  132. current_username = NULL;
  133. }
  134. /* 'abc' SINGLE
  135. 'def ' SINGLE
  136. 'ghi jkl' MULTI */
  137. DECL int
  138. has_arg(char const * cmd)
  139. {
  140. char const * start = cmd;
  141. while (isalnum(*cmd))
  142. {
  143. if (*cmd == '\0')
  144. { break; }
  145. ++cmd;
  146. }
  147. while (*cmd != '\0')
  148. {
  149. if (!isspace(*cmd))
  150. { return cmd - start; }
  151. ++cmd;
  152. }
  153. return 0;
  154. }
  155. DECL void
  156. parse_command(char const * cmd)
  157. {
  158. size_t i = 0;
  159. static int vote_count;
  160. static int yes, no, undecided;
  161. static int vote_on = 0;
  162. char * msgswp = NULL;
  163. /* size_t len = strlen(cmd); */
  164. printf("Handling '%s'\n", cmd);
  165. if (!(i = has_arg(cmd)))
  166. {
  167. /* NO ARGUMENTS */
  168. if (strcmp(cmd, "remind") == 0)
  169. {
  170. msgswp = remind(current_username);
  171. ircmsg(creds.channel, "%s: %s", current_username, msgswp);
  172. }
  173. else if (strcmp(cmd, "help") == 0)
  174. { ircmsg(creds.channel, help_msg); }
  175. else if (strcmp(cmd, "magic") == 0)
  176. { ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % 100) + 1); }
  177. #ifndef NO_VULN_COMMANDS
  178. else if (strcmp(cmd, "dump") == 0)
  179. {
  180. ircmsg(creds.channel, "%s: All projects:", current_username);
  181. msgswp = dump();
  182. ircmsg(creds.channel, msgswp);
  183. }
  184. #endif /* !NO_VULN_COMMANDS */
  185. else if (strcmp(cmd, "reroll") == 0)
  186. {
  187. purge_assignments(current_username);
  188. random_assign(current_username);
  189. ircmsg(creds.channel, "%s: %s", current_username, remind(current_username));
  190. }
  191. else if (strcmp(cmd, "stop") == 0)
  192. {
  193. vote_on = vote_count = 0;
  194. ircmsg(creds.channel, "POLL STOP");
  195. }
  196. }
  197. else /* HAS ARGUMENTS */
  198. {
  199. char const * const arg = cmd + i;
  200. /* fprintf(stderr, "argoff: %p; i: %ld; arg: %sEOA\n", cmd + i + 1, i, arg); */
  201. #ifndef NO_VULN_COMMANDS
  202. if (strncmp(cmd, "raw", 3) == 0)
  203. {
  204. printf("RAW\n");
  205. ircmsg(creds.channel, "%s: Executing SQL `%s'.", current_username, arg);
  206. msgswp = raw(arg);
  207. ircmsg(creds.channel, msgswp);
  208. } else
  209. #endif /* !NO_VULN_COMMANDS */
  210. #if 0
  211. if (strncmp(cmd, "repo", 4) == 0)
  212. {
  213. /* ircmsg(creds.channel, "%s: Setting project repository...", current_username); */
  214. set_repo(creds.channel, arg);
  215. msgswp = remind(creds.channel);
  216. ircmsg(creds.channel, "%s: %s", current_username, msgswp);
  217. }
  218. #endif /* 0 */
  219. else if (strncmp(cmd, "magic", 5) == 0)
  220. { ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % atoi(arg)) + 1); }
  221. else if (strncmp(cmd, "poll", 4) == 0)
  222. {
  223. yes = no = undecided = 0;
  224. vote_on = 1;
  225. vote_count = atoi(arg);
  226. if (!vote_count)
  227. { ircmsg(creds.channel, "!poll NUMBER_OF_VOTES What your voting on ..."); }
  228. else
  229. { ircmsg(creds.channel, "poll: start"); }
  230. }
  231. else if (strncmp(cmd, "vote", 4) == 0)
  232. {
  233. /* fprintf(stderr, "y%d n%d u%d vote_count %d\n", yes, no, undecided, vote_count); */
  234. if (vote_on && vote_count)
  235. {
  236. switch (*arg)
  237. {
  238. case 'Y': case 'y': ERRMSG("YYY"); ++yes; break;
  239. case 'N': case 'n': ERRMSG("NNN"); ++no; break;
  240. case 'U': case 'u': ERRMSG("UUU"); ++undecided; break;
  241. default: ircmsg(creds.channel, "Unknown vote meaning: '%c'", *arg); goto stop;
  242. }
  243. if (--vote_count)
  244. { ircmsg(creds.channel, "Votes remaining: %d", vote_count); }
  245. else
  246. {
  247. ircmsg(creds.channel, "poll results: %s",
  248. MAX(undecided,MAX(yes,no)) ? "UNDECIDED" :
  249. MAX(yes,no) ? "PASSED" : "REJECTED");
  250. vote_on = 0;
  251. }
  252. }
  253. }
  254. }
  255. stop:
  256. free(msgswp);
  257. }