update.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. #define MODULE_NAME "update"
  2. #define MAKING_update
  3. #include "src/mod/module.h"
  4. #include <netinet/in.h>
  5. #include <arpa/inet.h>
  6. #include <sys/stat.h>
  7. #include <pwd.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include <unistd.h>
  11. #include "transfer.mod/transfer.h"
  12. #include "compress.mod/compress.h"
  13. static Function *global = NULL, *transfer_funcs = NULL, *compress_funcs =
  14. NULL, *uncompress_funcs = NULL;
  15. extern int egg_numver;
  16. static void start_sending_binary (int);
  17. static void cancel_user_xfer (int, void *);
  18. #include "update.h"
  19. #ifdef HUB
  20. int bupdating = 0;
  21. #endif
  22. #ifdef LEAF
  23. int updated = 0;
  24. #endif
  25. static void
  26. update_ufno (int idx, char *par)
  27. {
  28. putlog (LOG_BOTS, "*", "binary file rejected by %s: %s", dcc[idx].nick,
  29. par);
  30. dcc[idx].status &= ~STAT_OFFEREDU;
  31. } static void
  32. update_ufyes (int idx, char *par)
  33. {
  34. if (dcc[idx].status & STAT_OFFEREDU)
  35. {
  36. start_sending_binary (idx);
  37. }
  38. }
  39. static void
  40. update_fileq (int idx, char *par)
  41. {
  42. if (dcc[idx].status & STAT_GETTINGU)
  43. return;
  44. #ifdef LEAF
  45. if (updated)
  46. return;
  47. if (localhub)
  48. {
  49. #else
  50. if (!isupdatehub ())
  51. {
  52. #endif
  53. dprintf (idx, "sb uy\n");
  54. }
  55. else if (isupdatehub ())
  56. {
  57. dprintf (idx, "sb un I am the update hub, NOT YOU.\n");
  58. }
  59. }
  60. static void
  61. update_ufsend (int idx, char *par)
  62. {
  63. char *ip = NULL, *port;
  64. char s[1024];
  65. int i, sock;
  66. FILE *f;
  67. putlog (LOG_BOTS, "*", "Downloading updated binary from %s", dcc[idx].nick);
  68. #ifdef HUB
  69. egg_snprintf (s, sizeof s, "%s.update.%s.hub", tempdir, botnetnick);
  70. #else
  71. egg_snprintf (s, sizeof s, "%s.update.%s.leaf", tempdir, botnetnick);
  72. #endif
  73. unlink (s);
  74. if (dcc_total == max_dcc)
  75. {
  76. putlog (LOG_MISC, "*",
  77. "NO MORE DCC CONNECTIONS -- can't grab new binary");
  78. dprintf (idx, "sb e I can't open a DCC to you; I'm full.\n");
  79. zapfbot (idx);
  80. }
  81. else if (!(f = fopen (s, "wb")))
  82. {
  83. putlog (LOG_MISC, "*", "CAN'T WRITE BINARY DOWNLOAD FILE!");
  84. zapfbot (idx);
  85. }
  86. else
  87. {
  88. ip = newsplit (&par);
  89. port = newsplit (&par);
  90. sock = getsock (SOCK_BINARY, getprotocol (ip));
  91. if (sock < 0 || open_telnet_dcc (sock, ip, port) < 0)
  92. {
  93. killsock (sock);
  94. putlog (LOG_BOTS, "*", "Asynchronous connection failed!");
  95. dprintf (idx, "sb e Can't connect to you!\n");
  96. zapfbot (idx);
  97. }
  98. else
  99. {
  100. putlog (LOG_DEBUG, "*", "Connecting to %s:%s for new binary.", ip,
  101. port);
  102. i = new_dcc (&DCC_FORK_SEND, sizeof (struct xfer_info));
  103. dcc[i].addr = my_atoul (ip);
  104. dcc[i].port = atoi (port);
  105. strcpy (dcc[i].nick, "*binary");
  106. dcc[i].u.xfer->filename = nmalloc (strlen (s) + 1);
  107. strcpy (dcc[i].u.xfer->filename, s);
  108. dcc[i].u.xfer->origname = dcc[i].u.xfer->filename;
  109. dcc[i].u.xfer->length = atoi (par);
  110. dcc[i].u.xfer->f = f;
  111. dcc[i].sock = sock;
  112. strcpy (dcc[i].host, dcc[idx].nick);
  113. dcc[idx].status |= STAT_GETTINGU;
  114. }}} static void
  115. update_version (int idx, char *par)
  116. {
  117. return;
  118. #ifdef HUB
  119. if (bupdating)
  120. return;
  121. dcc[idx].status &= ~(STAT_GETTINGU | STAT_SENDINGU | STAT_OFFEREDU);
  122. if ((dcc[idx].u.bot->numver < egg_numver) && (isupdatehub ()))
  123. {
  124. dprintf (idx, "sb u?\n");
  125. dcc[idx].status |= STAT_OFFEREDU;
  126. }
  127. #endif
  128. }
  129. static botcmd_t C_update[] =
  130. { {"u?", (Function) update_fileq}, {"un", (Function) update_ufno}, {"us",
  131. (Function)
  132. update_ufsend},
  133. {"uy", (Function) update_ufyes}, {"v", (Function) update_version}, {NULL,
  134. NULL} };
  135. static void
  136. got_nu (char *botnick, char *code, char *par)
  137. {
  138. int newver = 0;
  139. #ifdef LEAF
  140. tand_t *bot;
  141. struct bot_addr *bi, *obi;
  142. struct userrec *u1;
  143. bot = tandbot;
  144. if (!strcmp (bot->bot, botnick))
  145. return;
  146. if (!localhub)
  147. return;
  148. if (localhub && updated)
  149. return;
  150. #endif
  151. if (!par[0])
  152. return;
  153. newver = atoi (newsplit (&par));
  154. if (newver > egg_numver)
  155. {
  156. Context;
  157. #ifdef LEAF
  158. u1 = get_user_by_handle (userlist, botnetnick);
  159. obi = get_user (&USERENTRY_BOTADDR, u1);
  160. bi = user_malloc (sizeof (struct bot_addr));
  161. bi->uplink = user_malloc (strlen (botnick) + 1);
  162. strcpy (bi->uplink, botnick);
  163. bi->address = user_malloc (strlen (obi->address) + 1);
  164. strcpy (bi->address, obi->address);
  165. bi->telnet_port = obi->telnet_port;
  166. bi->relay_port = obi->relay_port;
  167. bi->hublevel = obi->hublevel;
  168. set_user (&USERENTRY_BOTADDR, u1, bi);
  169. putlog (LOG_MISC, "*", "Changed uplink to %s for update.", botnick);
  170. botunlink (-2, bot->bot, "Restructure for update.");
  171. usleep (1000 * 500);
  172. botlink ("", -3, botnick);
  173. #else
  174. putlog (LOG_MISC, "*", "I need to be updated with %d", newver);
  175. #endif
  176. }
  177. }
  178. static cmd_t update_bot[] =
  179. { {"nu?", "", (Function) got_nu, NULL}, {0, 0, 0, 0} };
  180. static void
  181. updatein_mod (int idx, char *msg)
  182. {
  183. char *code;
  184. int f, i;
  185. code = newsplit (&msg);
  186. for (f = 0, i = 0; C_update[i].name && !f; i++)
  187. {
  188. int y = egg_strcasecmp (code, C_update[i].name);
  189. if (!y)
  190. (C_update[i].func) (idx, msg);
  191. if (y < 0)
  192. f = 1;
  193. }
  194. }
  195. static void
  196. finish_update (int idx)
  197. {
  198. struct passwd *pw;
  199. uid_t id;
  200. char buf[1024];
  201. char *buf2;
  202. int i, j = -1;
  203. id = geteuid ();
  204. pw = getpwuid (id);
  205. for (i = 0; i < dcc_total; i++)
  206. if (!egg_strcasecmp (dcc[i].nick, dcc[idx].host)
  207. && (dcc[i].type->flags & DCT_BOT))
  208. j = i;
  209. if (j == -1)
  210. return;
  211. sprintf (buf, "%s%s", pw->pw_dir, strrchr (dcc[idx].u.xfer->filename, '/'));
  212. movefile (dcc[idx].u.xfer->filename, buf);
  213. chmod (buf, S_IRUSR | S_IWUSR | S_IXUSR);
  214. sprintf (buf, "%s", strrchr (buf, '/'));
  215. buf2 = buf;
  216. buf2++;
  217. putlog (LOG_MISC, "*", "Updating with binary: %s", buf2);
  218. Context;
  219. if (updatebin (0, buf2, 1))
  220. putlog (LOG_MISC, "*", "Failed to update to new binary..");
  221. #ifdef LEAF
  222. else
  223. updated = 1;
  224. #endif
  225. }
  226. static void
  227. start_sending_binary (int idx)
  228. {
  229. #ifdef HUB
  230. char update_file[1024];
  231. char buf2[1024], buf3[1024];
  232. struct stat sb;
  233. int i = 1;
  234. dcc[idx].status &= ~STAT_OFFEREDU;
  235. if (bupdating)
  236. return;
  237. bupdating = 1;
  238. dcc[idx].status |= STAT_SENDINGU;
  239. putlog (LOG_BOTS, "*", "Sending binary send request to %s", dcc[idx].nick);
  240. if (!strcmp ("*", dcc[idx].u.bot->sysname))
  241. {
  242. putlog (LOG_MISC, "*",
  243. "Cannot update \002%s\002 automatically, uname not returning os name.",
  244. dcc[idx].nick);
  245. return;
  246. }
  247. if (bot_hublevel (dcc[idx].user) == 999)
  248. {
  249. sprintf (buf2, "leaf");
  250. }
  251. else
  252. {
  253. sprintf (buf2, "hub");
  254. }
  255. sprintf (update_file, "%s.%s.%d", buf2, dcc[idx].u.bot->sysname,
  256. egg_numver);
  257. if (stat (update_file, &sb))
  258. {
  259. putlog (LOG_MISC, "*",
  260. "Need to update \002%s\002 with %s, but it cannot be accessed",
  261. dcc[idx].nick, update_file);
  262. return;
  263. }
  264. sprintf (buf3, "%s.%s", tempdir, update_file);
  265. unlink (buf3);
  266. copyfile (update_file, buf3);
  267. if ((i = raw_dcc_send (buf3, "*binary", "(binary)", buf3)) > 0)
  268. {
  269. putlog (LOG_BOTS, "*", "%s -- can't send new binary",
  270. i == DCCSEND_FULL ? "NO MORE DCC CONNECTIONS" : i ==
  271. DCCSEND_NOSOCK ? "CAN'T OPEN A LISTENING SOCKET" : i ==
  272. DCCSEND_BADFN ? "BAD FILE" : i ==
  273. DCCSEND_FEMPTY ? "EMPTY FILE" : "UNKNOWN REASON!");
  274. dcc[idx].status &= ~(STAT_SENDINGU);
  275. }
  276. else
  277. {
  278. dcc[idx].status |= STAT_SENDINGU;
  279. i = dcc_total - 1;
  280. strcpy (dcc[i].host, dcc[idx].nick);
  281. dprintf (idx, "sb us %lu %d %lu\n",
  282. iptolong (natip[0] ? (IP) inet_addr (natip) : getmyip ()),
  283. dcc[i].port, dcc[i].u.xfer->length);
  284. }
  285. #endif
  286. }
  287. static void (*def_dcc_bot_kill) (int, void *) = 0;
  288. static void
  289. cancel_user_xfer (int idx, void *x)
  290. {
  291. int i, j, k = 0;
  292. if (idx < 0)
  293. {
  294. idx = -idx;
  295. k = 1;
  296. updatebot (-1, dcc[idx].nick, '-', 0);
  297. }
  298. if (dcc[idx].status & STAT_SHARE)
  299. {
  300. if (dcc[idx].status & STAT_GETTINGU)
  301. {
  302. j = 0;
  303. for (i = 0; i < dcc_total; i++)
  304. if (!egg_strcasecmp (dcc[i].host, dcc[idx].nick)
  305. && ((dcc[i].type->flags & (DCT_FILETRAN | DCT_FILESEND)) ==
  306. (DCT_FILETRAN | DCT_FILESEND)))
  307. j = i;
  308. if (j != 0)
  309. {
  310. killsock (dcc[j].sock);
  311. unlink (dcc[j].u.xfer->filename);
  312. lostdcc (j);
  313. }
  314. putlog (LOG_BOTS, "*", "(Userlist download aborted.)");
  315. }
  316. if (dcc[idx].status & STAT_SENDINGU)
  317. {
  318. j = 0;
  319. for (i = 0; i < dcc_total; i++)
  320. if ((!egg_strcasecmp (dcc[i].host, dcc[idx].nick))
  321. && ((dcc[i].type->flags & (DCT_FILETRAN | DCT_FILESEND)) ==
  322. DCT_FILETRAN))
  323. j = i;
  324. if (j != 0)
  325. {
  326. killsock (dcc[j].sock);
  327. unlink (dcc[j].u.xfer->filename);
  328. lostdcc (j);
  329. }
  330. putlog (LOG_BOTS, "*", "(Userlist transmit aborted.)");
  331. }
  332. }
  333. if (!k)
  334. def_dcc_bot_kill (idx, x);
  335. }
  336. #ifdef HUB
  337. int cnt = 0;
  338. static void
  339. check_updates ()
  340. {
  341. int i;
  342. char buf[1024];
  343. if (!isupdatehub ())
  344. return;
  345. cnt++;
  346. if ((cnt > 5) && bupdating)
  347. bupdating = 0;
  348. if (bupdating)
  349. return;
  350. cnt = 0;
  351. for (i = 0; i < dcc_total; i++)
  352. {
  353. if (dcc[i].type->flags & DCT_BOT && (dcc[i].status & STAT_SHARE)
  354. && !(dcc[i].status & STAT_SENDINGU)
  355. && !(dcc[i].status & STAT_OFFEREDU)
  356. && !(dcc[i].status & STAT_UPDATED))
  357. {
  358. dcc[i].status &= ~(STAT_GETTINGU | STAT_SENDINGU | STAT_OFFEREDU);
  359. if ((dcc[i].u.bot->numver < egg_numver) && (isupdatehub ()))
  360. {
  361. dprintf (i, "sb u?\n");
  362. dcc[i].status |= STAT_OFFEREDU;
  363. }
  364. }
  365. }
  366. sprintf (buf, "nu? %d", egg_numver);
  367. botnet_send_zapf_broad (-1, botnetnick, NULL, buf);
  368. }
  369. #endif
  370. static char *
  371. update_close ()
  372. {
  373. module_undepend (MODULE_NAME);
  374. rem_builtins (H_bot, update_bot);
  375. #ifdef HUB
  376. del_hook (HOOK_30SECONDLY, (Function) check_updates);
  377. #endif
  378. del_hook (HOOK_SHAREUPDATEIN, (Function) updatein_mod);
  379. DCC_BOT.kill = def_dcc_bot_kill;
  380. return NULL;
  381. }
  382. static int
  383. update_expmem ()
  384. {
  385. int tot = 0;
  386. return tot;
  387. }
  388. static void
  389. update_report (int idx, int details)
  390. {
  391. int i, j;
  392. if (details)
  393. {
  394. dprintf (idx, " update module, using %d bytes.\n", update_expmem ());
  395. for (i = 0; i < dcc_total; i++)
  396. if (dcc[i].type == &DCC_BOT)
  397. {
  398. if (dcc[i].status & STAT_GETTINGU)
  399. {
  400. int ok = 0;
  401. for (j = 0; j < dcc_total; j++)
  402. if (((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND)) ==
  403. (DCT_FILETRAN | DCT_FILESEND))
  404. && !egg_strcasecmp (dcc[j].host, dcc[i].nick))
  405. {
  406. dprintf (idx,
  407. "Downloading binary from %s (%d%% done)\n",
  408. dcc[i].nick,
  409. (int) (100.0 * ((float) dcc[j].status) /
  410. ((float) dcc[j].u.xfer->length)));
  411. ok = 1;
  412. break;
  413. }
  414. if (!ok)
  415. dprintf (idx,
  416. "Download binary from %s (negotiating "
  417. "botentries)\n", dcc[i].nick);
  418. }
  419. else if (dcc[i].status & STAT_SENDINGU)
  420. {
  421. for (j = 0; j < dcc_total; j++)
  422. {
  423. if (((dcc[j].type->
  424. flags & (DCT_FILETRAN | DCT_FILESEND)) ==
  425. DCT_FILETRAN)
  426. && !egg_strcasecmp (dcc[j].host, dcc[i].nick))
  427. {
  428. if (dcc[j].type == &DCC_GET)
  429. dprintf (idx, "Sending binary to %s (%d%% done)\n",
  430. dcc[i].nick,
  431. (int) (100.0 * ((float) dcc[j].status) /
  432. ((float) dcc[j].u.xfer->length)));
  433. else
  434. dprintf (idx,
  435. "Sending binary to %s (waiting for connect)\n",
  436. dcc[i].nick);
  437. }
  438. }
  439. }
  440. }
  441. }
  442. }
  443. EXPORT_SCOPE char *update_start ();
  444. static Function update_table[] =
  445. { (Function) update_start, (Function) update_close,
  446. (Function) update_expmem, (Function) update_report, (Function) finish_update, (Function) 0, (Function) 0,
  447. #ifdef LEAF
  448. (Function) 0
  449. #else
  450. (Function) 0, (Function) & bupdating
  451. #endif
  452. };
  453. char *
  454. update_start (Function * global_funcs)
  455. {
  456. global = global_funcs;
  457. module_register (MODULE_NAME, update_table, 2, 3);
  458. if (!(transfer_funcs = module_depend (MODULE_NAME, "transfer", 2, 0)))
  459. {
  460. module_undepend (MODULE_NAME);
  461. return "This module requires transfer module 2.0 or later.";
  462. }
  463. if (!(compress_funcs = module_depend (MODULE_NAME, "compress", 0, 0)))
  464. {
  465. module_undepend (MODULE_NAME);
  466. return "This module requires the compression.";
  467. }
  468. if (!(uncompress_funcs = module_depend (MODULE_NAME, "compress", 0, 0)))
  469. {
  470. module_undepend (MODULE_NAME);
  471. return "This module requires the compression.";
  472. }
  473. add_builtins (H_bot, update_bot);
  474. #ifdef HUB
  475. add_hook (HOOK_30SECONDLY, (Function) check_updates);
  476. #endif
  477. add_hook (HOOK_SHAREUPDATEIN, (Function) updatein_mod);
  478. def_dcc_bot_kill = DCC_BOT.kill;
  479. DCC_BOT.kill = cancel_user_xfer;
  480. return NULL;
  481. }