userent.c 25 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142
  1. /*
  2. * userent.c -- handles:
  3. * user-entry handling, new stylem more versatile.
  4. *
  5. */
  6. #include "common.h"
  7. #include "users.h"
  8. #include "src/mod/share.mod/share.h"
  9. #include "misc.h"
  10. #include "debug.h"
  11. #include "match.h"
  12. #include "dccutil.h"
  13. #include "crypt.h"
  14. #include "botmsg.h"
  15. extern int noshare, cfg_noshare, cfg_count;
  16. extern struct cfg_entry **cfg;
  17. extern struct userrec *userlist;
  18. extern struct dcc_t *dcc;
  19. extern time_t now;
  20. static struct user_entry_type *entry_type_list;
  21. void init_userent()
  22. {
  23. entry_type_list = 0;
  24. add_entry_type(&USERENTRY_COMMENT);
  25. add_entry_type(&USERENTRY_INFO);
  26. add_entry_type(&USERENTRY_LASTON);
  27. add_entry_type(&USERENTRY_BOTADDR);
  28. add_entry_type(&USERENTRY_PASS);
  29. add_entry_type(&USERENTRY_SECPASS);
  30. add_entry_type(&USERENTRY_HOSTS);
  31. add_entry_type(&USERENTRY_BOTFL);
  32. add_entry_type(&USERENTRY_STATS);
  33. add_entry_type(&USERENTRY_ADDED);
  34. add_entry_type(&USERENTRY_MODIFIED);
  35. add_entry_type(&USERENTRY_CONFIG);
  36. }
  37. void list_type_kill(struct list_type *t)
  38. {
  39. struct list_type *u = NULL;
  40. while (t) {
  41. u = t->next;
  42. if (t->extra)
  43. free(t->extra);
  44. free(t);
  45. t = u;
  46. }
  47. }
  48. int def_unpack(struct userrec *u, struct user_entry *e)
  49. {
  50. char *tmp = NULL;
  51. tmp = e->u.list->extra;
  52. e->u.list->extra = NULL;
  53. list_type_kill(e->u.list);
  54. e->u.string = tmp;
  55. return 1;
  56. }
  57. int def_pack(struct userrec *u, struct user_entry *e)
  58. {
  59. char *tmp = NULL;
  60. tmp = e->u.string;
  61. e->u.list = calloc(1, sizeof(struct list_type));
  62. e->u.list->next = NULL;
  63. e->u.list->extra = tmp;
  64. return 1;
  65. }
  66. int def_kill(struct user_entry *e)
  67. {
  68. free(e->u.string);
  69. free(e);
  70. return 1;
  71. }
  72. int def_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
  73. {
  74. if (lfprintf(f, "--%s %s\n", e->type->name, e->u.string) == EOF)
  75. return 0;
  76. return 1;
  77. }
  78. void *def_get(struct userrec *u, struct user_entry *e)
  79. {
  80. return e->u.string;
  81. }
  82. int def_set(struct userrec *u, struct user_entry *e, void *buf)
  83. {
  84. char *string = (char *) buf;
  85. if (string && !string[0])
  86. string = NULL;
  87. if (!string && !e->u.string)
  88. return 1;
  89. if (string) {
  90. int l = strlen (string);
  91. char *i;
  92. if (l > 160)
  93. l = 160;
  94. e->u.string = realloc (e->u.string, l + 1);
  95. strncpyz (e->u.string, string, l + 1);
  96. for (i = e->u.string; *i; i++)
  97. /* Allow bold, inverse, underline, color text here...
  98. * But never add cr or lf!! --rtc
  99. */
  100. if ((unsigned int) *i < 32 && !strchr ("\002\003\026\037", *i))
  101. *i = '?';
  102. } else { /* string == NULL && e->u.string != NULL */
  103. free(e->u.string);
  104. e->u.string = NULL;
  105. }
  106. if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED))) {
  107. shareout(NULL, "c %s %s %s\n", e->type->name, u->handle, e->u.string ? e->u.string : "");
  108. }
  109. return 1;
  110. }
  111. int def_gotshare(struct userrec *u, struct user_entry *e, char *data, int idx)
  112. {
  113. #ifdef HUB
  114. putlog(LOG_CMDS, "@", "%s: change %s %s", dcc[idx].nick, e->type->name, u->handle);
  115. #endif
  116. return e->type->set(u, e, data);
  117. }
  118. void def_display(int idx, struct user_entry *e, struct userrec *u)
  119. {
  120. dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
  121. }
  122. int def_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
  123. {
  124. return set_user(e->type, new, e->u.string);
  125. }
  126. static void comment_display(int idx, struct user_entry *e, struct userrec *u)
  127. {
  128. if (dcc[idx].user && (dcc[idx].user->flags & USER_MASTER))
  129. dprintf(idx, " COMMENT: %s\n", e->u.string);
  130. }
  131. struct user_entry_type USERENTRY_COMMENT =
  132. {
  133. 0, /* always 0 ;) */
  134. def_gotshare,
  135. def_dupuser,
  136. def_unpack,
  137. def_pack,
  138. def_write_userfile,
  139. def_kill,
  140. def_get,
  141. def_set,
  142. comment_display,
  143. "COMMENT"
  144. };
  145. struct user_entry_type USERENTRY_INFO =
  146. {
  147. 0, /* always 0 ;) */
  148. def_gotshare,
  149. def_dupuser,
  150. def_unpack,
  151. def_pack,
  152. def_write_userfile,
  153. def_kill,
  154. def_get,
  155. def_set,
  156. def_display,
  157. "INFO"
  158. };
  159. void added_display(int idx, struct user_entry *e, struct userrec *u)
  160. {
  161. /* format: unixtime handle */
  162. if (dcc[idx].user && (dcc[idx].user->flags & USER_OWNER)) {
  163. char tmp[30] = "", tmp2[70] = "", *hnd = NULL;
  164. time_t tm;
  165. strncpyz(tmp, e->u.string, sizeof(tmp));
  166. hnd = strchr(tmp, ' ');
  167. if (hnd)
  168. *hnd++ = 0;
  169. tm = atoi(tmp);
  170. #ifdef S_UTCTIME
  171. egg_strftime(tmp2, sizeof(tmp2), STR("%a, %d %b %Y %H:%M:%S %Z"), gmtime(&tm));
  172. #else /* !S_UTCTIME */
  173. egg_strftime(tmp2, sizeof(tmp2), STR("%a, %d %b %Y %H:%M:%S %Z"), localtime(&tm));
  174. #endif /* S_UTCTIME */
  175. if (hnd)
  176. dprintf(idx, STR(" -- Added %s by %s\n"), tmp2, hnd);
  177. else
  178. dprintf(idx, STR(" -- Added %s\n"), tmp2);
  179. }
  180. }
  181. struct user_entry_type USERENTRY_ADDED = {
  182. 0, /* always 0 ;) */
  183. def_gotshare,
  184. def_dupuser,
  185. def_unpack,
  186. def_pack,
  187. def_write_userfile,
  188. def_kill,
  189. def_get,
  190. def_set,
  191. added_display,
  192. "ADDED"
  193. };
  194. int config_set(struct userrec *u, struct user_entry *e, void *buf)
  195. {
  196. struct xtra_key *curr = NULL, *old = NULL, *new = buf;
  197. for (curr = e->u.extra; curr; curr = curr->next) {
  198. if (curr->key && !egg_strcasecmp(curr->key, new->key)) {
  199. old = curr;
  200. break;
  201. }
  202. }
  203. if (!old && (!new->data || !new->data[0])) {
  204. /* delete non-existant entry */
  205. free(new->key);
  206. if (new->data)
  207. free(new->data);
  208. free(new);
  209. return 1;
  210. }
  211. /* we will possibly free new below, so let's send the information
  212. * to the botnet now */
  213. if (!noshare && !cfg_noshare)
  214. shareout(NULL, STR("c CONFIG %s %s %s\n"), u->handle, new->key, new->data ? new->data : "");
  215. if ((old && old != new) || !new->data || !new->data[0]) {
  216. list_delete((struct list_type **) (&e->u.extra), (struct list_type *) old);
  217. free(old->key);
  218. free(old->data);
  219. free(old);
  220. }
  221. if (old != new && new->data) {
  222. if (new->data[0]) {
  223. list_insert((&e->u.extra), new);
  224. } else {
  225. if (new->data)
  226. free(new->data);
  227. free(new->key);
  228. free(new);
  229. }
  230. }
  231. return 1;
  232. }
  233. int config_unpack(struct userrec *u, struct user_entry *e)
  234. {
  235. struct list_type *curr = NULL, *head = NULL;
  236. struct xtra_key *t = NULL;
  237. char *key = NULL, *data = NULL;
  238. head = curr = e->u.list;
  239. e->u.extra = NULL;
  240. while (curr) {
  241. t = calloc(1, sizeof(struct xtra_key));
  242. data = curr->extra;
  243. key = newsplit(&data);
  244. if (data[0]) {
  245. t->key = strdup(key);
  246. t->data = strdup(data);
  247. list_insert((&e->u.extra), t);
  248. }
  249. curr = curr->next;
  250. }
  251. list_type_kill(head);
  252. return 1;
  253. }
  254. int config_pack(struct userrec *u, struct user_entry *e)
  255. {
  256. struct list_type *t = NULL;
  257. struct xtra_key *curr = NULL, *next = NULL;
  258. curr = e->u.extra;
  259. e->u.list = NULL;
  260. while (curr) {
  261. t = calloc(1, sizeof(struct list_type));
  262. t->extra = calloc(1, strlen(curr->key) + strlen(curr->data) + 4);
  263. sprintf(t->extra, STR("%s %s"), curr->key, curr->data);
  264. list_insert((&e->u.list), t);
  265. next = curr->next;
  266. free(curr->key);
  267. free(curr->data);
  268. free(curr);
  269. curr = next;
  270. }
  271. return 1;
  272. }
  273. void config_display(int idx, struct user_entry *e, struct userrec *u)
  274. {
  275. #ifdef HUB
  276. struct xtra_key *xk = NULL;
  277. struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
  278. get_user_flagrec(dcc[idx].user, &fr, NULL);
  279. /* scan thru xtra field, searching for matches */
  280. for (xk = e->u.extra; xk; xk = xk->next) {
  281. /* ok, it's a valid xtra field entry */
  282. if (glob_owner(fr))
  283. dprintf(idx, STR(" %s: %s\n"), xk->key, xk->data);
  284. }
  285. #endif /* HUB */
  286. }
  287. int config_gotshare(struct userrec *u, struct user_entry *e, char *buf, int idx)
  288. {
  289. char *arg = NULL;
  290. struct xtra_key *xk = NULL;
  291. int l;
  292. arg = newsplit(&buf);
  293. if (!arg[0])
  294. return 1;
  295. if (!strcmp(u->handle, conf.bot->nick)) {
  296. struct cfg_entry *cfgent = NULL;
  297. int i;
  298. cfg_noshare = 1;
  299. for (i = 0; !cfgent && (i < cfg_count); i++)
  300. if (!strcmp(arg, cfg[i]->name) && (cfg[i]->flags & CFGF_LOCAL))
  301. cfgent = cfg[i];
  302. if (cfgent) {
  303. set_cfg_str(conf.bot->nick, cfgent->name, (buf && buf[0]) ? buf : NULL);
  304. }
  305. cfg_noshare = 0;
  306. return 1;
  307. }
  308. xk = calloc(1, sizeof(struct xtra_key));
  309. l = strlen(arg);
  310. if (l > 1500)
  311. l = 1500;
  312. xk->key = calloc(1, l + 1);
  313. strncpy(xk->key, arg, l + 1);
  314. if (buf && buf[0]) {
  315. int k = strlen(buf);
  316. if (k > 1500 - l)
  317. k = 1500 - l;
  318. xk->data = calloc(1, k + 1);
  319. strncpy(xk->data, buf, k + 1);
  320. }
  321. config_set(u, e, xk);
  322. return 1;
  323. }
  324. int config_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
  325. {
  326. struct xtra_key *x1 = NULL, *x2 = NULL;
  327. for (x1 = e->u.extra; x1; x1 = x1->next) {
  328. x2 = calloc(1, sizeof(struct xtra_key));
  329. x2->key = strdup(x1->key);
  330. x2->data = strdup(x1->data);
  331. set_user(&USERENTRY_CONFIG, new, x2);
  332. }
  333. return 1;
  334. }
  335. int config_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
  336. {
  337. struct xtra_key *x = NULL;
  338. for (x = e->u.extra; x; x = x->next)
  339. lfprintf(f, STR("--CONFIG %s %s\n"), x->key, x->data);
  340. return 1;
  341. }
  342. int config_kill(struct user_entry *e)
  343. {
  344. struct xtra_key *x = NULL, *y = NULL;
  345. for (x = e->u.extra; x; x = y) {
  346. y = x->next;
  347. free(x->key);
  348. free(x->data);
  349. free(x);
  350. }
  351. free(e);
  352. return 1;
  353. }
  354. struct user_entry_type USERENTRY_CONFIG = {
  355. 0,
  356. config_gotshare,
  357. config_dupuser,
  358. config_unpack,
  359. config_pack,
  360. config_write_userfile,
  361. config_kill,
  362. def_get,
  363. config_set,
  364. config_display,
  365. "CONFIG"
  366. };
  367. void stats_add(struct userrec *u, int login, int op)
  368. {
  369. char *s = NULL, s2[50] = "";
  370. int sl, so;
  371. if (!u)
  372. return;
  373. s = get_user(&USERENTRY_STATS, u);
  374. if (s) {
  375. strncpyz(s2, s, sizeof(s2));
  376. } else
  377. strcpy(s2, STR("0 0"));
  378. s = strchr(s2, ' ');
  379. if (s) {
  380. s++;
  381. so = atoi(s);
  382. } else
  383. so = 0;
  384. sl = atoi(s2);
  385. if (login)
  386. sl++;
  387. if (op)
  388. so++;
  389. sprintf(s2, STR("%i %i"), sl, so);
  390. set_user(&USERENTRY_STATS, u, s2);
  391. }
  392. void stats_display(int idx, struct user_entry *e, struct userrec *u)
  393. {
  394. /* format: logincount opcount */
  395. if (dcc[idx].user && (dcc[idx].user->flags & USER_OWNER)) {
  396. char *p;
  397. p = strchr(e->u.string, ' ');
  398. if (p)
  399. dprintf(idx, STR(" -- %i logins, %i ops\n"), atoi(e->u.string), atoi(p));
  400. }
  401. }
  402. struct user_entry_type USERENTRY_STATS = {
  403. 0, /* always 0 ;) */
  404. def_gotshare,
  405. def_dupuser,
  406. def_unpack,
  407. def_pack,
  408. def_write_userfile,
  409. def_kill,
  410. def_get,
  411. def_set,
  412. stats_display,
  413. "STATS"
  414. };
  415. void update_mod(char *handle, char *nick, char *cmd, char *par)
  416. {
  417. char tmp[100] = "";
  418. egg_snprintf(tmp, sizeof tmp, "%lu, %s (%s %s)", now, nick, cmd, (par && par[0]) ? par : "");
  419. set_user(&USERENTRY_MODIFIED, get_user_by_handle(userlist, handle), tmp);
  420. }
  421. void modified_display(int idx, struct user_entry *e, struct userrec *u)
  422. {
  423. if (e && dcc[idx].user && (dcc[idx].user->flags & USER_MASTER)) {
  424. char tmp[1024] = "", tmp2[1024] = "", *hnd = NULL;
  425. time_t tm;
  426. strncpyz(tmp, e->u.string, sizeof(tmp));
  427. hnd = strchr(tmp, ' ');
  428. if (hnd)
  429. *hnd++ = 0;
  430. tm = atoi(tmp);
  431. #ifdef S_UTCTIME
  432. egg_strftime(tmp2, sizeof(tmp2), STR("%a, %d %b %Y %H:%M:%S %Z"), gmtime(&tm));
  433. #else /* !S_UTCTIME */
  434. egg_strftime(tmp2, sizeof(tmp2), STR("%a, %d %b %Y %H:%M:%S %Z"), localtime(&tm));
  435. #endif /* S_UTCTIME */
  436. if (hnd)
  437. dprintf(idx, " -- Modified %s by %s\n", tmp2, hnd);
  438. else
  439. dprintf(idx, " -- Modified %s\n", tmp2);
  440. }
  441. }
  442. struct user_entry_type USERENTRY_MODIFIED =
  443. {
  444. 0,
  445. def_gotshare,
  446. def_dupuser,
  447. def_unpack,
  448. def_pack,
  449. def_write_userfile,
  450. def_kill,
  451. def_get,
  452. def_set,
  453. modified_display,
  454. "MODIFIED"
  455. };
  456. int pass_set(struct userrec *u, struct user_entry *e, void *buf)
  457. {
  458. char new[32] = "";
  459. register char *pass = buf;
  460. if (e->u.extra)
  461. free(e->u.extra);
  462. if (!pass || !pass[0] || (pass[0] == '-'))
  463. e->u.extra = NULL;
  464. else {
  465. unsigned char *p = (unsigned char *) pass;
  466. if (strlen(pass) > 15)
  467. pass[15] = 0;
  468. while (*p) {
  469. if ((*p <= 32) || (*p == 127))
  470. *p = '?';
  471. p++;
  472. }
  473. if ((u->flags & USER_BOT) || (pass[0] == '+'))
  474. strcpy(new, pass);
  475. else
  476. encrypt_pass(pass, new);
  477. e->u.extra = strdup(new);
  478. }
  479. if (!noshare && !(u->flags & (USER_BOT | USER_UNSHARED)))
  480. shareout(NULL, "c PASS %s %s\n", u->handle, pass ? pass : "");
  481. return 1;
  482. }
  483. struct user_entry_type USERENTRY_PASS =
  484. {
  485. 0,
  486. def_gotshare,
  487. 0,
  488. def_unpack,
  489. def_pack,
  490. def_write_userfile,
  491. def_kill,
  492. def_get,
  493. pass_set,
  494. 0,
  495. "PASS"
  496. };
  497. void secpass_display(int idx, struct user_entry *e, struct userrec *u)
  498. {
  499. struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
  500. get_user_flagrec(dcc[idx].user, &fr, NULL);
  501. if (!strcmp(u->handle, dcc[idx].nick) || glob_admin(fr)) {
  502. #ifdef HUB
  503. dprintf(idx, " %s: %s\n", e->type->name, e->u.string);
  504. #else
  505. dprintf(idx, " %s: Hidden on leaf bots.", e->type->name);
  506. if (dcc[idx].u.chat->su_nick)
  507. dprintf(idx, " Nice try, %s.", dcc[idx].u.chat->su_nick);
  508. dprintf(idx, "\n");
  509. #endif /* HUB */
  510. }
  511. }
  512. struct user_entry_type USERENTRY_SECPASS =
  513. {
  514. 0,
  515. def_gotshare,
  516. def_dupuser,
  517. def_unpack,
  518. def_pack,
  519. def_write_userfile,
  520. def_kill,
  521. def_get,
  522. def_set,
  523. secpass_display,
  524. "SECPASS"
  525. };
  526. static int laston_unpack(struct userrec *u, struct user_entry *e)
  527. {
  528. char *par = NULL, *arg = NULL;
  529. struct laston_info *li = NULL;
  530. par = e->u.list->extra;
  531. arg = newsplit (&par);
  532. if (!par[0])
  533. par = "???";
  534. li = calloc(1, sizeof(struct laston_info));
  535. li->laston = atoi(arg);
  536. li->lastonplace = strdup(par);
  537. list_type_kill(e->u.list);
  538. e->u.extra = li;
  539. return 1;
  540. }
  541. static int laston_pack(struct userrec *u, struct user_entry *e)
  542. {
  543. char work[1024] = "";
  544. struct laston_info *li = NULL;
  545. int l;
  546. li = (struct laston_info *) e->u.extra;
  547. l = sprintf(work, "%lu %s", li->laston, li->lastonplace);
  548. e->u.list = calloc(1, sizeof(struct list_type));
  549. e->u.list->next = NULL;
  550. e->u.list->extra = calloc(1, l + 1);
  551. strcpy(e->u.list->extra, work);
  552. free(li->lastonplace);
  553. free(li);
  554. return 1;
  555. }
  556. static int laston_write_userfile(FILE * f, struct userrec *u, struct user_entry *e)
  557. {
  558. struct laston_info *li = (struct laston_info *) e->u.extra;
  559. if (lfprintf(f, "--LASTON %lu %s\n", li->laston,
  560. li->lastonplace ? li->lastonplace : "") == EOF)
  561. return 0;
  562. return 1;
  563. }
  564. static int laston_kill(struct user_entry *e)
  565. {
  566. if (((struct laston_info *) (e->u.extra))->lastonplace)
  567. free(((struct laston_info *) (e->u.extra))->lastonplace);
  568. free(e->u.extra);
  569. free(e);
  570. return 1;
  571. }
  572. static int laston_set(struct userrec *u, struct user_entry *e, void *buf)
  573. {
  574. struct laston_info *li = (struct laston_info *) e->u.extra;
  575. if (li != buf) {
  576. if (li) {
  577. free(li->lastonplace);
  578. free(li);
  579. }
  580. li = e->u.extra = buf;
  581. }
  582. /* donut share laston info */
  583. return 1;
  584. }
  585. static int laston_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
  586. {
  587. struct laston_info *li = e->u.extra, *li2 = NULL;
  588. if (li) {
  589. li2 = calloc(1, sizeof(struct laston_info));
  590. li2->laston = li->laston;
  591. li2->lastonplace = strdup(li->lastonplace);
  592. return set_user(&USERENTRY_LASTON, new, li2);
  593. }
  594. return 0;
  595. }
  596. struct user_entry_type USERENTRY_LASTON =
  597. {
  598. 0, /* always 0 ;) */
  599. 0,
  600. laston_dupuser,
  601. laston_unpack,
  602. laston_pack,
  603. laston_write_userfile,
  604. laston_kill,
  605. def_get,
  606. laston_set,
  607. 0,
  608. "LASTON"
  609. };
  610. static int botaddr_unpack(struct userrec *u, struct user_entry *e)
  611. {
  612. char p[1024] = "", *q1 = NULL, *q2 = NULL;
  613. struct bot_addr *bi = NULL;
  614. bi = calloc(1, sizeof(struct bot_addr));
  615. /* address:port/port:hublevel:uplink */
  616. Context;
  617. Assert(e);
  618. Assert(e->name);
  619. strcpy(p, e->u.list->extra);
  620. q1 = strchr(p, ':');
  621. if (q1)
  622. *q1++ = 0;
  623. bi->address = strdup(p);
  624. if (q1) {
  625. q2 = strchr(q1, ':');
  626. if (q2)
  627. *q2++ = 0;
  628. bi->telnet_port = atoi(q1);
  629. q1 = strchr(q1, '/');
  630. if (q1) {
  631. q1++;
  632. bi->relay_port = atoi(q1);
  633. }
  634. if (q2) {
  635. q1 = strchr(q2, ':');
  636. if (q1) {
  637. *q1++ = 0;
  638. bi->uplink = strdup(q1);
  639. }
  640. bi->hublevel = atoi(q2);
  641. }
  642. }
  643. if (!bi->telnet_port)
  644. bi->telnet_port = 3333;
  645. if (!bi->relay_port)
  646. bi->relay_port = bi->telnet_port;
  647. if (!bi->uplink) {
  648. bi->uplink = calloc(1, 1);
  649. }
  650. list_type_kill(e->u.list);
  651. e->u.extra = bi;
  652. return 1;
  653. }
  654. static int botaddr_pack(struct userrec *u, struct user_entry *e)
  655. {
  656. char work[1024] = "";
  657. struct bot_addr *bi = NULL;
  658. int l;
  659. Assert(e);
  660. Assert(!e->name);
  661. bi = (struct bot_addr *) e->u.extra;
  662. l = simple_sprintf(work, STR("%s:%u/%u:%u:%s"), bi->address, bi->telnet_port, bi->relay_port, bi->hublevel, bi->uplink);
  663. e->u.list = calloc(1, sizeof(struct list_type));
  664. e->u.list->next = NULL;
  665. e->u.list->extra = calloc(1, l + 1);
  666. strcpy(e->u.list->extra, work);
  667. free(bi->address);
  668. free(bi->uplink);
  669. free(bi);
  670. return 1;
  671. }
  672. static int botaddr_kill(struct user_entry *e)
  673. {
  674. free(((struct bot_addr *) (e->u.extra))->address);
  675. free(((struct bot_addr *) (e->u.extra))->uplink);
  676. free(e->u.extra);
  677. free(e);
  678. return 1;
  679. }
  680. static int botaddr_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
  681. {
  682. register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
  683. if (lfprintf(f, "--%s %s:%u/%u:%u:%s\n", e->type->name, bi->address,
  684. bi->telnet_port, bi->relay_port, bi->hublevel, bi->uplink) == EOF)
  685. return 0;
  686. return 1;
  687. }
  688. static int botaddr_set(struct userrec *u, struct user_entry *e, void *buf)
  689. {
  690. register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
  691. Context;
  692. if (!bi && !buf)
  693. return 1;
  694. if (bi != buf) {
  695. if (bi) {
  696. Assert(bi->address);
  697. free(bi->address);
  698. Assert(bi->uplink);
  699. free(bi->uplink);
  700. free(bi);
  701. }
  702. ContextNote("(sharebug) occurred in botaddr_set");
  703. bi = e->u.extra = buf;
  704. }
  705. Assert(u);
  706. if (bi && !noshare && !(u->flags & USER_UNSHARED)) {
  707. shareout(NULL, STR("c BOTADDR %s %s %d %d %d %s\n"),u->handle, (bi->address && bi->address[0]) ? bi->address : STR("127.0.0.1"), bi->telnet_port, bi->relay_port, bi->hublevel, bi->uplink);
  708. }
  709. return 1;
  710. }
  711. static void botaddr_display(int idx, struct user_entry *e, struct userrec *u)
  712. {
  713. #ifdef HUB
  714. struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
  715. get_user_flagrec(dcc[idx].user, &fr, NULL);
  716. if (glob_admin(fr)) {
  717. register struct bot_addr *bi = (struct bot_addr *) e->u.extra;
  718. if (bi->address && bi->hublevel && bi->hublevel != 0)
  719. dprintf(idx, STR(" ADDRESS: %.70s:%d\n"), bi->address, bi->telnet_port);
  720. if (bi->hublevel && bi->hublevel != 0)
  721. dprintf(idx, STR(" HUBLEVEL: %d\n"), bi->hublevel);
  722. if (bi->uplink && bi->uplink[0])
  723. dprintf(idx, STR(" UPLINK: %s\n"), bi->uplink);
  724. }
  725. #endif /* HUB */
  726. }
  727. static int botaddr_gotshare(struct userrec *u, struct user_entry *e, char *buf, int idx)
  728. {
  729. struct bot_addr *bi = NULL;
  730. char *arg = NULL;
  731. bi = calloc(1, sizeof(struct bot_addr));
  732. arg = newsplit(&buf);
  733. bi->address = strdup(arg);
  734. arg = newsplit(&buf);
  735. bi->telnet_port = atoi(arg);
  736. arg = newsplit(&buf);
  737. bi->relay_port = atoi(arg);
  738. arg = newsplit(&buf);
  739. bi->hublevel = atoi(arg);
  740. bi->uplink = strdup(buf);
  741. if (!bi->telnet_port)
  742. bi->telnet_port = 3333;
  743. if (!bi->relay_port)
  744. bi->relay_port = bi->telnet_port;
  745. return botaddr_set(u, e, bi);
  746. }
  747. static int botaddr_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
  748. {
  749. if (old->flags & USER_BOT) {
  750. struct bot_addr *bi = e->u.extra;
  751. if (bi) {
  752. struct bot_addr *bi2 = NULL;
  753. bi2 = calloc(1, sizeof(struct bot_addr));
  754. bi2->telnet_port = bi->telnet_port;
  755. bi2->relay_port = bi->relay_port;
  756. bi2->hublevel = bi->hublevel;
  757. bi2->address = strdup(bi->address);
  758. bi2->uplink = strdup(bi->uplink);
  759. return set_user(&USERENTRY_BOTADDR, new, bi2);
  760. }
  761. }
  762. return 0;
  763. }
  764. struct user_entry_type USERENTRY_BOTADDR =
  765. {
  766. 0, /* always 0 ;) */
  767. botaddr_gotshare,
  768. botaddr_dupuser,
  769. botaddr_unpack,
  770. botaddr_pack,
  771. botaddr_write_userfile,
  772. botaddr_kill,
  773. def_get,
  774. botaddr_set,
  775. botaddr_display,
  776. "BOTADDR"
  777. };
  778. static int hosts_dupuser(struct userrec *new, struct userrec *old, struct user_entry *e)
  779. {
  780. struct list_type *h = NULL;
  781. for (h = e->u.extra; h; h = h->next)
  782. set_user(&USERENTRY_HOSTS, new, h->extra);
  783. return 1;
  784. }
  785. static int hosts_null(struct userrec *u, struct user_entry *e)
  786. {
  787. return 1;
  788. }
  789. static int hosts_write_userfile(FILE *f, struct userrec *u, struct user_entry *e)
  790. {
  791. struct list_type *h = NULL;
  792. for (h = e->u.extra; h; h = h->next)
  793. if (lfprintf(f, "--HOSTS %s\n", h->extra) == EOF)
  794. return 0;
  795. return 1;
  796. }
  797. static int hosts_kill(struct user_entry *e)
  798. {
  799. list_type_kill(e->u.list);
  800. free(e);
  801. return 1;
  802. }
  803. static void hosts_display(int idx, struct user_entry *e, struct userrec *u)
  804. {
  805. #ifdef LEAF
  806. /* if this is a su, dont show hosts
  807. * otherwise, let users see their own hosts */
  808. if (!strcmp(u->handle,dcc[idx].nick) && !dcc[idx].u.chat->su_nick) {
  809. #endif /* LEAF */
  810. char s[1024] = "";
  811. struct list_type *q = NULL;
  812. strcpy(s, " HOSTS: ");
  813. for (q = e->u.list; q; q = q->next) {
  814. if (s[0] && !s[9])
  815. strcat(s, q->extra);
  816. else if (!s[0])
  817. sprintf(s, " %s", q->extra);
  818. else {
  819. if (strlen(s) + strlen(q->extra) + 2 > 65) {
  820. dprintf(idx, "%s\n", s);
  821. sprintf(s, " %s", q->extra);
  822. } else {
  823. strcat(s, ", ");
  824. strcat(s, q->extra);
  825. }
  826. }
  827. }
  828. if (s[0])
  829. dprintf(idx, "%s\n", s);
  830. #ifdef LEAF
  831. } else {
  832. dprintf(idx, " HOSTS: Hidden on leaf bots.");
  833. if (dcc[idx].u.chat->su_nick)
  834. dprintf(idx, " Nice try, %s.", dcc[idx].u.chat->su_nick);
  835. dprintf(idx, "\n");
  836. }
  837. #endif /* LEAF */
  838. }
  839. static int hosts_set(struct userrec *u, struct user_entry *e, void *buf)
  840. {
  841. if (!buf || !egg_strcasecmp(buf, "none")) {
  842. /* When the bot crashes, it's in this part, not in the 'else' part */
  843. list_type_kill(e->u.list);
  844. e->u.list = NULL;
  845. } else {
  846. char *host = buf, *p = strchr(host, ',');
  847. struct list_type **t;
  848. /* Can't have ,'s in hostmasks */
  849. while (p) {
  850. *p = '?';
  851. p = strchr(host, ',');
  852. }
  853. /* fred1: check for redundant hostmasks with
  854. * controversial "superpenis" algorithm ;) */
  855. /* I'm surprised Raistlin hasn't gotten involved in this controversy */
  856. t = &(e->u.list);
  857. while (*t) {
  858. if (wild_match(host, (*t)->extra)) {
  859. struct list_type *u;
  860. u = *t;
  861. *t = (*t)->next;
  862. if (u->extra)
  863. free(u->extra);
  864. free(u);
  865. } else
  866. t = &((*t)->next);
  867. }
  868. *t = calloc(1, sizeof(struct list_type));
  869. (*t)->next = NULL;
  870. (*t)->extra = strdup(host);
  871. }
  872. return 1;
  873. }
  874. static int hosts_gotshare(struct userrec *u, struct user_entry *e, char *buf, int idx)
  875. {
  876. /* doh, try to be too clever and it bites your butt */
  877. return 0;
  878. }
  879. struct user_entry_type USERENTRY_HOSTS =
  880. {
  881. 0,
  882. hosts_gotshare,
  883. hosts_dupuser,
  884. hosts_null,
  885. hosts_null,
  886. hosts_write_userfile,
  887. hosts_kill,
  888. def_get,
  889. hosts_set,
  890. hosts_display,
  891. "HOSTS"
  892. };
  893. int list_append(struct list_type **h, struct list_type *i)
  894. {
  895. for (; *h; h = &((*h)->next));
  896. *h = i;
  897. return 1;
  898. }
  899. int list_delete(struct list_type **h, struct list_type *i)
  900. {
  901. for (; *h; h = &((*h)->next))
  902. if (*h == i) {
  903. *h = i->next;
  904. return 1;
  905. }
  906. return 0;
  907. }
  908. int list_contains(struct list_type *h, struct list_type *i)
  909. {
  910. for (; h; h = h->next)
  911. if (h == i) {
  912. return 1;
  913. }
  914. return 0;
  915. }
  916. int add_entry_type(struct user_entry_type *type)
  917. {
  918. struct userrec *u = NULL;
  919. list_insert(&entry_type_list, type);
  920. for (u = userlist; u; u = u->next) {
  921. struct user_entry *e = find_user_entry(type, u);
  922. if (e && e->name) {
  923. e->type = type;
  924. e->type->unpack(u, e);
  925. free(e->name);
  926. e->name = NULL;
  927. }
  928. }
  929. return 1;
  930. }
  931. int del_entry_type(struct user_entry_type *type)
  932. {
  933. struct userrec *u = NULL;
  934. for (u = userlist; u; u = u->next) {
  935. struct user_entry *e = find_user_entry(type, u);
  936. if (e && !e->name) {
  937. e->type->pack(u, e);
  938. e->name = strdup(e->type->name);
  939. e->type = NULL;
  940. }
  941. }
  942. return list_delete((struct list_type **) &entry_type_list, (struct list_type *) type);
  943. }
  944. struct user_entry_type *find_entry_type(char *name)
  945. {
  946. struct user_entry_type *p = NULL;
  947. for (p = entry_type_list; p; p = p->next) {
  948. if (!egg_strcasecmp(name, p->name))
  949. return p;
  950. }
  951. return NULL;
  952. }
  953. struct user_entry *find_user_entry(struct user_entry_type *et, struct userrec *u)
  954. {
  955. struct user_entry **e = NULL, *t = NULL;
  956. for (e = &(u->entries); *e; e = &((*e)->next)) {
  957. if (((*e)->type == et) ||
  958. ((*e)->name && !egg_strcasecmp((*e)->name, et->name))) {
  959. t = *e;
  960. *e = t->next;
  961. t->next = u->entries;
  962. u->entries = t;
  963. return t;
  964. }
  965. }
  966. return NULL;
  967. }
  968. void *get_user(struct user_entry_type *et, struct userrec *u)
  969. {
  970. struct user_entry *e = NULL;
  971. if (u && (e = find_user_entry(et, u)))
  972. return et->get(u, e);
  973. return 0;
  974. }
  975. int set_user(struct user_entry_type *et, struct userrec *u, void *d)
  976. {
  977. struct user_entry *e = NULL;
  978. int r;
  979. if (!u || !et)
  980. return 0;
  981. if (!(e = find_user_entry(et, u))) {
  982. e = calloc(1, sizeof(struct user_entry));
  983. e->type = et;
  984. e->name = NULL;
  985. e->u.list = NULL;
  986. list_insert((&(u->entries)), e);
  987. }
  988. r = et->set(u, e, d);
  989. if (!e->u.list) {
  990. list_delete((struct list_type **) &(u->entries), (struct list_type *) e);
  991. free(e);
  992. }
  993. return r;
  994. }