Probiotics (in bot form) for programming.
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
此仓库已存档。您可以查看文件和克隆,但不能推送或创建工单/合并请求。

299 行
7.8KB

  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. IRC_GREEN "!poll " IRC_STOP " : Start the democratic process (N message ...])\n"
  39. IRC_GREEN "!vote " IRC_STOP " : Casts a vote (y/n [message ...])\n"
  40. IRC_GREEN "!stop " IRC_STOP " : Stop the current polling\n"
  41. IRC_BLUE "!magic " IRC_STOP " : A random value at or below 100 or (N)\n";
  42. DECL void parse_command(char const * cmd);
  43. DECL size_t parse_secondary_username(char const * msg);
  44. DECL char *
  45. get_username(const char * origin)
  46. {
  47. const char USERNAME_TERMINATOR = '!';
  48. int i = 0;
  49. char * r;
  50. while (origin[i] != USERNAME_TERMINATOR)
  51. { i++; }
  52. r = (char *) malloc(i + 1);
  53. if (r)
  54. {
  55. strncpy(r, origin, i);
  56. r[i] = '\00';
  57. }
  58. return r;
  59. }
  60. DECL void
  61. ircmsg(char const * reciever, char const * fmt,
  62. ...)
  63. {
  64. va_list args;
  65. char * fmtdmsg;
  66. char * swp;
  67. const char * delim = "\n";
  68. char * data;
  69. if(!strcmp(fmt, "") || fmt == NULL)
  70. { return; }
  71. va_start(args, fmt);
  72. if(vasprintf(&fmtdmsg, fmt, args) == -1)
  73. { exit(1); }
  74. puts(fmtdmsg);
  75. data = strtok(fmtdmsg, delim);
  76. do
  77. {
  78. swp = irc_color_convert_to_mirc(data);
  79. irc_cmd_msg(session, reciever, swp);
  80. free(swp);
  81. } while((data = strtok(NULL, delim), data));
  82. free(fmtdmsg);
  83. va_end(args);
  84. }
  85. DECL void
  86. event_connect(irc_session_t * lsession,
  87. char const * event,
  88. char const * origin,
  89. char const ** params,
  90. unsigned int count)
  91. {
  92. (void) event;
  93. (void) origin;
  94. (void) params;
  95. (void) count;
  96. /* msg ChanServ IDENTIFY? */
  97. irc_cmd_join(lsession, creds.channel, 0);
  98. if (ident_password)
  99. {
  100. ircmsg("NickServ", "IDENTIFY %s", ident_password);
  101. memset(ident_password, '\0', strlen(ident_password));
  102. }
  103. #ifdef INITIAL_ASSIGNMENT_MESSAGE
  104. if(is_no_assignment(creds.channel))
  105. {
  106. ircmsg(creds.channel,
  107. IRC_RED "No assignment for this channel. Finding a new..." IRC_STOP);
  108. random_assign(creds.channel);
  109. }
  110. ircmsg(creds.channel, remind(creds.channel));
  111. #endif /* INITIAL_ASSIGNMENT_MESSAGE */
  112. }
  113. DECL void
  114. event_channel(irc_session_t * lsession,
  115. char const * event,
  116. char const * origin,
  117. char const ** params,
  118. unsigned int count)
  119. {
  120. /* char const * channel = params[0]; */
  121. char const * message = params[1];
  122. (void) lsession;
  123. (void) event;
  124. (void) origin;
  125. (void) message;
  126. (void) count;
  127. /* fetches username and logs message */
  128. if (!(current_username = get_username(origin)))
  129. { return; }
  130. printf("<%s> %s\n", current_username, message);
  131. /* Detects any respecified names */
  132. /* message += parse_secondary_username(message); */
  133. /* Parse commands */
  134. if (*message == PREFIX_COMMAND_CHAR &&
  135. message[1] != '\0')
  136. { parse_command(message+1); }
  137. free(current_username);
  138. current_username = NULL;
  139. }
  140. /* 'abc' SINGLE
  141. 'def ' SINGLE
  142. 'ghi jkl' MULTI */
  143. DECL int
  144. has_arg(char const * cmd)
  145. {
  146. char const * start = cmd;
  147. while (isalnum(*cmd))
  148. {
  149. if (*cmd == '\0')
  150. { break; }
  151. ++cmd;
  152. }
  153. while (*cmd != '\0')
  154. {
  155. if (!isspace(*cmd))
  156. { return cmd - start; }
  157. ++cmd;
  158. }
  159. return 0;
  160. }
  161. DECL void
  162. parse_command(char const * cmd)
  163. {
  164. static int vote_count;
  165. size_t i = 0;
  166. char * msgswp = NULL;
  167. /* size_t len = strlen(cmd); */
  168. if (!(i = has_arg(cmd)))
  169. {
  170. printf("NARG Handling '%s'\n", cmd);
  171. /* NO ARGUMENTS */
  172. if (strncmp(cmd, "remind", 6) == 0)
  173. {
  174. msgswp = remind(current_username);
  175. ircmsg(creds.channel, "%s: %s", current_username, msgswp);
  176. }
  177. else if (strncmp(cmd, "help", 4) == 0)
  178. { ircmsg(creds.channel, help_msg); }
  179. else if (strncmp(cmd, "magic", 5) == 0)
  180. { ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % 100) + 1); }
  181. #ifndef NO_VULN_COMMANDS
  182. else if (strncmp(cmd, "dump", 4) == 0)
  183. {
  184. ircmsg(creds.channel, "%s: All projects:", current_username);
  185. msgswp = dump();
  186. ircmsg(creds.channel, msgswp);
  187. }
  188. #endif /* !NO_VULN_COMMANDS */
  189. else if (strncmp(cmd, "reroll", 6) == 0)
  190. {
  191. purge_assignments(current_username);
  192. random_assign(current_username);
  193. ircmsg(creds.channel, "%s: %s", current_username, remind(current_username));
  194. }
  195. else if (strncmp(cmd, "stop", 4) == 0)
  196. {
  197. if (vote_count)
  198. {
  199. ircmsg(creds.channel, "poll: stop");
  200. vote_count = 0;
  201. }
  202. }
  203. }
  204. else /* HAS ARGUMENTS */
  205. {
  206. printf("ARG Handling '%s'\n", cmd);
  207. static int yes, no;
  208. char const * const arg = cmd + i;
  209. /* fprintf(stderr, "argoff: %p; i: %ld; arg: %sEOA\n", cmd + i + 1, i, arg); */
  210. #ifndef NO_VULN_COMMANDS
  211. if (strncmp(cmd, "raw", 3) == 0)
  212. {
  213. printf("RAW\n");
  214. ircmsg(creds.channel, "%s: Executing SQL `%s'.", current_username, arg);
  215. msgswp = raw(arg);
  216. ircmsg(creds.channel, msgswp);
  217. } else
  218. #endif /* !NO_VULN_COMMANDS */
  219. #if 0
  220. if (strncmp(cmd, "repo", 4) == 0)
  221. {
  222. /* ircmsg(creds.channel, "%s: Setting project repository...", current_username); */
  223. set_repo(creds.channel, arg);
  224. msgswp = remind(creds.channel);
  225. ircmsg(creds.channel, "%s: %s", current_username, msgswp);
  226. }
  227. #endif /* 0 */
  228. if (strncmp(cmd, "magic", 5) == 0)
  229. { ircmsg(creds.channel, "%s: " IRC_YELLOW "%d" IRC_STOP, current_username, (rand() % atoi(arg)) + 1); }
  230. else if (strncmp(cmd, "echo", 3) == 0)
  231. { ircmsg(creds.channel, "%s", arg); }
  232. else if (strncmp(cmd, "poll", 4) == 0)
  233. {
  234. yes = no = 0;
  235. vote_count = atoi(arg);
  236. if (!vote_count)
  237. { ircmsg(creds.channel, "!poll NUMBER_OF_VOTES What your voting on ..."); }
  238. else
  239. { ircmsg(creds.channel, "poll: start"); }
  240. }
  241. else if (strncmp(cmd, "vote", 4) == 0)
  242. {
  243. /* fprintf(stderr, "y%d n%d vote_count %d\n", yes, no, vote_count); */
  244. if (vote_count)
  245. {
  246. switch (*arg)
  247. {
  248. case 'Y': case 'y': ++yes; break;
  249. case 'N': case 'n': ++no; break;
  250. default: ircmsg(creds.channel, "Unknown: '%c', use y/n", *arg); goto stop;
  251. }
  252. if (--vote_count)
  253. { ircmsg(creds.channel, "Votes remaining: %d", vote_count); }
  254. else
  255. { ircmsg(creds.channel, "poll: %s", MAX(yes,no) ? "PASSED" : "REJECTED"); }
  256. }
  257. }
  258. }
  259. stop:
  260. free(msgswp);
  261. }
  262. /* mutates current_username and returns positional offset to the first character that isn't related to the uname */
  263. DECL size_t
  264. parse_secondary_username(char const * msg)
  265. {
  266. int ret = 0;
  267. #define SECONDARY_NAMES_BOT "cnile"
  268. if (strcmp(current_username,SECONDARY_NAMES_BOT) == 0)
  269. if (*msg == '<')
  270. { while (msg[++ret] != '\0' ||
  271. msg[ret] != '>'); }
  272. fprintf(stderr, "msg[ret] = %c", msg[ret]);
  273. return ret;
  274. }