Recent
:: This post is secret Bystroushaak
38 mins ago
:: RIFAS
3 hrs ago
:: buy clomid onli
4 hrs ago
:: RIFAS
4 hrs ago
:: anonymous
5 hrs ago
:: anonymous
5 hrs ago
:: anonymous
5 hrs ago
:: This post is secret DarckALexXP
5 hrs ago
:: DarckALexXP
5 hrs ago
:: s3v3n
7 hrs ago
:: anonymous
7 hrs ago
:: s3v3n
7 hrs ago
:: s3v3n
7 hrs ago
:: This post is secret KOLOU
13 hrs ago
:: This post is secret Chris
21 hrs ago
rss 2.0 feed

Make New Post
Posts: 19124

Syntax:       Wrapping:  

   #15378 Posted by sturm 2009-07-03 06:23:39
Formated by GeSHi
  1. /* main.c */
  2.  
  3. /*
  4.  * This code is public domain as declared by Sturm S. Mabie.
  5.  */
  6.  
  7.  
  8. #include <unistd.h>
  9. #include <errno.h>
  10. #include <sys/stat.h>
  11. #include <sys/types.h>
  12. #include <sys/socket.h>
  13. #include <sys/select.h>
  14. #include <netinet/in.h>
  15. #include <netdb.h>
  16. #include <fcntl.h>
  17. #include <arpa/inet.h>
  18. #include <getopt.h>
  19. #include <err.h>
  20. #include <db4.1/db_185.h>
  21. #include <limits.h>
  22.  
  23. #include <stdio.h>
  24. #include <stdlib.h>
  25. #include <string.h>
  26.  
  27. /*
  28.  * Apparantly, HOST_NAME_MAX isn't defined on some systems
  29.  */
  30. #ifndef HOST_NAME_MAX
  31. #define HOST_NAME_MAX 256
  32. #endif
  33.  
  34. /*
  35.  * Currently, all commands are <10 characters
  36.  */
  37. #define CMD_SIZ 10
  38.  
  39. #define NICK_SIZ 64
  40. #define MSG_SIZ 1024
  41. #define NMAIL 64
  42. #define MAIL_SIZ 512
  43. #define NAME_SIZ 128
  44. #define EMAIL_SIZ 64
  45. #define DROP_SIZ 128
  46. /*
  47.  * Because using write() correctly is a bitch
  48.  */
  49. ssize_t writeall(int, const void *, size_t);
  50.  
  51. void usage();
  52.  
  53. int handler(const char *, int);
  54. int handler_im(const char *, int);
  55. int handler_ison(const char *, int);
  56. int handler_isreg(const char *, int);
  57. int handler_mail(const char *, int);
  58. int handler_pass(const char *, int);
  59. int handler_pickup(const char *, int);
  60. int handler_pong(const char *, int);
  61. int handler_quit(const char *, int);
  62. int handler_register(const char *, int);
  63. int handler_servinfo(const char *, int);
  64. int handler_to(const char *, int);
  65. int handler_whois(const char *, int);
  66.  
  67. int activedb_add(int, char *);
  68. int activedb_del(int);
  69. char *activedb_getnick(int);
  70. int activedb_getfd(char *);
  71. /* int regdb_add(char *, struct scmp_user *); */
  72.  
  73. /*
  74.  * Each registered user of the system gets a scmp_user structure
  75.  */
  76. struct scmp_user {
  77. char nick[NICK_SIZ]; /* nick name or user name*/
  78. char email[EMAIL_SIZ]; /* email address for the account */
  79. char name[NAME_SIZ]; /* real name */
  80. char mail[MAIL_SIZ][NMAIL]; /* the queued mail */
  81. char drop[NICK_SIZ][DROP_SIZ]; /* a list of names that are dropped */
  82. };
  83.  
  84. /*
  85.  * This is an in memory only db that maps the current open fds to nicks. The
  86.  * dbfdtonick db converts fds to nicks while the dbnicktofd db converts,
  87.  * obviously, nicks to fds. These dbs should be in parallel, in that, they
  88.  * should contain the same information, just with the key/values reversed.
  89.  */
  90. struct {
  91. DB *dbfdtonick;
  92. DB *dbnicktofd;
  93. } activedb;
  94.  
  95. /*
  96.  * When the command is encountered, a binary search is used to find it in
  97.  * icmdtab
  98.  */
  99. struct input_cmd {
  100. const char *cmd;
  101. int (*fp)(const char *, int);
  102. } icmdtab[] = {
  103. { "IM" , handler_im },
  104. { "ISON" , handler_ison },
  105. { "ISREG" , handler_isreg },
  106. { "MAIL" , handler_mail },
  107. { "PASS" , handler_pass },
  108. { "PICKUP" , handler_pickup },
  109. { "PONG" , handler_pong },
  110. { "QUIT" , handler_quit },
  111. { "REGISTER" , handler_register },
  112. { "SERVINFO" , handler_servinfo },
  113. { "TO" , handler_to },
  114. { "WHOIS" , handler_whois }
  115. };
  116.  
  117. const char servinfo_msg[] = "INFO scmpd version 0.1\n";
  118. DB *regdb;
  119. int fdhwm;
  120. fd_set set, rset;
  121.  
  122. int
  123. main(int argc, char *argv[])
  124. {
  125. struct addrinfo hint, *infop;
  126. struct sockaddr_in *sa;
  127. int skfd, cskfd, fd, c;
  128. int fflg;
  129. char buf[MSG_SIZ], host[HOST_NAME_MAX], port[9], dbpath[PATH_MAX];
  130. ssize_t nr;
  131.  
  132. fflg = 0;
  133. (void)gethostname(host, sizeof(host));
  134. (void)strcpy(port, "7777");
  135. (void)strcpy(dbpath, "/var/lib/scmpd.db");
  136. while ((c = getopt(argc, argv, "fd:i:p:")) != -1) {
  137. switch (c) {
  138. case 'd':
  139. (void)strncpy(dbpath, optarg, sizeof(dbpath));
  140. break;
  141. case 'f':
  142. fflg = 1;
  143. break;
  144. case 'i':
  145. (void)strncpy(host, optarg, sizeof(host));
  146. break;
  147. case 'p':
  148. (void)strncpy(port, optarg, sizeof(port));
  149. break;
  150. default:
  151. usage();
  152. break;
  153. }
  154. }
  155. argc -= optind;
  156. argv += optind;
  157.  
  158. if (!fflg) {
  159. if (daemon(0, 0) == -1)
  160. err(1, "daemon()");
  161. }
  162.  
  163. fdhwm = 0;
  164. infop = NULL;
  165. (void)memset(&hint, 0, sizeof(hint));
  166. hint.ai_family = AF_INET;
  167. hint.ai_socktype = SOCK_STREAM;
  168. hint.ai_flags = AI_PASSIVE;
  169.  
  170. if (getaddrinfo(host, port, &hint, &infop) != 0)
  171. err(1, "getaddrinfo()");
  172. sa = (struct sockaddr_in *)infop->ai_addr;
  173. if ((skfd = socket(AF_INET, SOCK_STREAM, 0)) == -1)
  174. err(1, "socket()");
  175. if (bind(skfd, (struct sockaddr *)sa, sizeof(*sa)) == -1)
  176. err(1, NULL);
  177. if (listen(skfd, SOMAXCONN) == -1)
  178. err(1, "listen()");
  179.  
  180. /* initialize dbs */
  181. if ((activedb.dbfdtonick = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == NULL)
  182. err(1, "dbopen()");
  183. if ((activedb.dbnicktofd = dbopen(NULL, O_RDWR, 0, DB_HASH, NULL)) == NULL)
  184. err(1, "dbopen()");
  185. if ((regdb = dbopen(dbpath, O_RDWR | O_CREAT,
  186. S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH,
  187. DB_HASH, NULL)) == NULL)
  188. err(1, "dbopen()");
  189.  
  190. if (skfd > fdhwm)
  191. fdhwm = skfd;
  192.  
  193. FD_ZERO(&set);
  194. FD_SET(skfd, &set);
  195. loop:
  196. rset = set;
  197. if (select(fdhwm + 1, &rset, NULL, NULL, NULL) == -1)
  198. err(1, "select()");
  199.  
  200. for (fd = 0; fd <= fdhwm; fd++) {
  201. if (FD_ISSET(fd, &rset)) {
  202. if (fd == skfd) {
  203. if ((cskfd = accept(skfd, NULL, 0)) == -1)
  204. err(1, "accept()");
  205. FD_SET(cskfd, &set);
  206. if (cskfd > fdhwm)
  207. fdhwm = cskfd;
  208. } else {
  209. if ((nr = read(fd, buf, sizeof(buf))) == -1)
  210. err(1, "read()");
  211. if (nr == 0)
  212. (void)activedb_del(fd);
  213. else {
  214. buf[nr] = '\0';
  215. (void)handler(buf, fd);
  216. }
  217. }
  218. }
  219. }
  220. goto loop;
  221.  
  222. freeaddrinfo(infop);
  223. (void)activedb.dbfdtonick->close(activedb.dbfdtonick);
  224. (void)activedb.dbnicktofd->close(activedb.dbnicktofd);
  225. (void)close(skfd);
  226. (void)close(cskfd);
  227.  
  228. return 0;
  229. }
  230.  
  231. void
  232. usage()
  233. {
  234. (void)fprintf(stderr,
  235. "usage: scmpd [-f] [-d database] [-i address] [-p port] \n");
  236. exit(1);
  237. }
  238.  
  239.  
  240. int
  241. handler(const char *s, int fd)
  242. {
  243. char buf[CMD_SIZ];
  244. int in, c, j;
  245. int l, h, m, cmp;
  246.  
  247. in = j = l = 0;
  248. h = sizeof(icmdtab) / sizeof(*icmdtab) - 1;
  249.  
  250. for (c = 0; s[c] != '\0'; c++) {
  251. if (j > CMD_SIZ)
  252. return -1;
  253. if (isspace(s[c])) {
  254. if (in)
  255. break;
  256. } else {
  257. if (!in)
  258. in = 1;
  259. buf[j++] = s[c];
  260. }
  261. }
  262. buf[j] = '\0';
  263. while (l <= h) {
  264. m = (l + h) / 2;
  265. cmp = strcmp(buf, icmdtab[m].cmd);
  266. if (cmp < 0)
  267. h = m - 1;
  268. else if (cmp > 0)
  269. l = m + 1;
  270. else
  271. break;
  272. }
  273. if (l > h)
  274. return -1;
  275.  
  276. (void)icmdtab[m].fp(s + c + 1, fd);
  277.  
  278. return 0;
  279. }
  280.  
  281. int
  282. handler_im(const char *s, int fd)
  283. {
  284. char buf[NICK_SIZ];
  285. char sbuf[MSG_SIZ];
  286. int in, j, c;
  287. ssize_t nw;
  288.  
  289. in = j = 0;
  290. for (c = 0; s[c] != '\0'; c++) {
  291. if (j > NICK_SIZ)
  292. return -1;
  293. if (isspace(s[c])) {
  294. if (in)
  295. break;
  296. } else {
  297. if (!in)
  298. in = 1;
  299. buf[j++] = s[c];
  300. }
  301. }
  302. buf[j] = '\0';
  303.  
  304. if (activedb_getfd(buf) != -1) {
  305. char tmp[] = "DENIED This user name is already in use\n";
  306.  
  307. if ((nw = writeall(fd, tmp, sizeof(tmp) - 1)) == -1 || nw == 0)
  308. return -1;
  309. return 0;
  310. }
  311. (void)activedb_add(fd, buf);
  312. (void)snprintf(sbuf, MSG_SIZ, "HELLO %s\n", buf);
  313. if ((nw = writeall(fd, sbuf, strlen(sbuf))) == -1 || nw == 0)
  314. return -1;
  315. return 0;
  316. }
  317.  
  318. int
  319. handler_ison(const char *s, int fd)
  320. {
  321. char buf[NICK_SIZ];
  322. int c, j, in;
  323. ssize_t nw;
  324.  
  325. j = in = 0;
  326. for (c = 0; s[c] != '\0'; c++) {
  327. if (j > NICK_SIZ)
  328. return -1;
  329. if (isspace(s[c])) {
  330. if (in)
  331. break;
  332. } else {
  333. if (!in)
  334. in = 1;
  335. buf[j++] = s[c];
  336. }
  337. }
  338. buf[j] = '\0';
  339.  
  340. if (activedb_getfd(buf) == -1) {
  341. if ((nw = writeall(fd, "NO\n", 3)) == -1 || nw == 0)
  342. return -1;
  343. } else {
  344. if ((nw = writeall(fd, "YES\n", 4)) == -1 || nw == 0)
  345. return -1;
  346. }
  347. return 0;
  348. }
  349.  
  350. int
  351. handler_isreg(const char *s, int fd)
  352. {
  353. }
  354.  
  355. int
  356. handler_mail(const char *s, int fd)
  357. {
  358. }
  359.  
  360. int
  361. handler_pass(const char *s, int fd)
  362. {
  363.  
  364. }
  365.  
  366. int
  367. handler_pickup(const char *s, int fd)
  368. {
  369. }
  370.  
  371. int
  372. handler_pong(const char *s, int fd)
  373. {
  374. }
  375.  
  376. int
  377. handler_quit(const char *s, int fd)
  378. {
  379. ssize_t nw;
  380.  
  381. if ((nw = writeall(fd, "BYE\n", 4)) == -1 || nw == 0)
  382. return -1;
  383. return activedb_del(fd);
  384. }
  385.  
  386. int
  387. handler_register(const char *s, int fd)
  388. {
  389. }
  390.  
  391. /* args not used */
  392. int
  393. handler_servinfo(const char *s, int fd)
  394. {
  395. ssize_t nw;
  396.  
  397. if ((nw = writeall(fd, servinfo_msg, sizeof(servinfo_msg) - 1)) == -1
  398. || nw == 0)
  399. return -1;
  400. return 0;
  401. }
  402.  
  403. int
  404. handler_to(const char *s, int fd)
  405. {
  406. char buf[NICK_SIZ];
  407. char sbuf[MSG_SIZ];
  408. char *name;
  409. int c, j, in, rfd;
  410. ssize_t nw;
  411.  
  412. j = in = 0;
  413. for (c = 0; s[c] != '\0'; c++) {
  414. if (j > NICK_SIZ)
  415. return -1;
  416. if (isspace(s[c])) {
  417. if (in)
  418. break;
  419. } else {
  420. if (!in)
  421. in = 1;
  422. buf[j++] = s[c];
  423. }
  424. }
  425. buf[j] = '\0';
  426. if ((name = activedb_getnick(fd)) == NULL)
  427. return -1;
  428. (void)snprintf(sbuf, MSG_SIZ, "FROM %s %s", name, s + c + 1);
  429. if ((rfd = activedb_getfd(buf)) == -1)
  430. return -1;
  431. if ((nw = writeall(rfd, sbuf, strlen(sbuf))) == -1 || nw == 0)
  432. return -1;
  433. if ((nw = writeall(fd, "SENT\n", 5)) == -1 || nw == 0)
  434. return -1;
  435. free(name);
  436. return 0;
  437. }
  438.  
  439. int
  440. handler_whois(const char *s, int fd)
  441. {
  442. }
  443.  
  444. ssize_t
  445. writeall(int fd, const void *buf, size_t size)
  446. {
  447. ssize_t nw, tmp;
  448.  
  449. nw = 0;
  450. do {
  451. if ((tmp = write(fd, buf + nw, size - nw)) == -1)
  452. return -1;
  453. else if (tmp == 0)
  454. return nw;
  455. } while ((nw += tmp) < size);
  456. return nw;
  457. }
  458.  
  459. int
  460. activedb_add(int fd, char *s)
  461. {
  462. DBT dbtfd, dbts;
  463.  
  464. dbtfd.data = &fd;
  465. dbtfd.size = sizeof(int);
  466. dbts.data = s;
  467. dbts.size = strlen(s) + 1;
  468. if (activedb.dbfdtonick->put(activedb.dbfdtonick, &dbtfd, &dbts, 0) == -1)
  469. err(1, "DB->put()");
  470. if (activedb.dbnicktofd->put(activedb.dbnicktofd, &dbts, &dbtfd, 0) == -1)
  471. err(1, "DB->put()");
  472. return 0;
  473. }
  474.  
  475.  
  476. /*
  477.  * Caller must free()
  478.  */
  479. char *
  480. activedb_getnick(int fd)
  481. {
  482. DBT ret, dbtfd;
  483. char *sret;
  484.  
  485. dbtfd.data = &fd;
  486. dbtfd.size = sizeof(int);
  487. if (activedb.dbfdtonick->get(activedb.dbfdtonick, &dbtfd, &ret, 0) == 1)
  488. return NULL;
  489. if ((sret = strdup(ret.data)) == NULL)
  490. err(1, "strdup()");
  491. return sret;
  492. }
  493.  
  494. int
  495. activedb_getfd(char *s)
  496. {
  497. DBT ret, dbts;
  498.  
  499. dbts.data = s;
  500. dbts.size = strlen(s) + 1;
  501. if (activedb.dbnicktofd->get(activedb.dbnicktofd, &dbts, &ret, 0) == 1)
  502. return -1;
  503. return *((int *)ret.data);
  504. }
  505.  
  506. int
  507. activedb_del(int fd)
  508. {
  509. DBT dbtfd, dbts;
  510. char *s;
  511.  
  512. if ((s = activedb_getnick(fd)) == NULL)
  513. return -1;
  514. dbtfd.data = &fd;
  515. dbtfd.size = sizeof(int);
  516. dbts.data = s;
  517. dbts.size = strlen(s) + 1;
  518. if (activedb.dbnicktofd->del(activedb.dbnicktofd, &dbts, 0) == -1)
  519. return -1;
  520. if (activedb.dbfdtonick->del(activedb.dbfdtonick, &dbtfd, 0) == -1)
  521. return -1;
  522. FD_CLR(fd, &set);
  523. if (fd == fdhwm)
  524. fdhwm--;
  525. if (close(fd) == -1)
  526. err(1, "close()");
  527. free(s);
  528. return 0;
  529. }
  530.  
Parsed in 0.243325 seconds
::  Inline view Inline view ::  Email this post Email  ::  Print Print   

:: Download   Download Text File15378.txt   Download Gziped text File15378.txt.gz   Download HTML File15378.html   Download PDF File15378.pdf
:: Print into    Print into HTML FileHTML document   Print into PDF FilePDF document

:: Make Diff

:: Erase Post

* Code:

To highlight particular lines, prefix each line with @@


Description:


Secret key (for later deletion)
Syntax:     


comments (0)


Copyright © 2006 Openpastebin