ServerMain.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <signal.h>
  5. #include <string.h>
  6. #include <dirent.h>
  7. #include <sys/stat.h>
  8. #include <sys/types.h>
  9. #include <fcntl.h>
  10. #include <dirent.h>
  11. #include <assert.h>
  12. #include "Server.h"
  13. int getMailCounter()
  14. {
  15. FILE* test = fopen("mailcounter", "r+");
  16. if(test == NULL)
  17. {
  18. if(creat("mailcounter", S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
  19. {
  20. return 0;
  21. }
  22. test = fopen("mailcounter", "r+");
  23. if(test == NULL)
  24. {
  25. return 0;
  26. }
  27. }
  28. int counter;
  29. if(fread(&counter, sizeof(int), 1, test) == 0)
  30. {
  31. counter = -1;
  32. }
  33. counter++;
  34. rewind(test);
  35. if(fwrite(&counter, sizeof(int), 1, test) == 0)
  36. {
  37. return 0;
  38. }
  39. if(fflush(test) == EOF)
  40. {
  41. return 0;
  42. }
  43. if(fclose(test) == EOF)
  44. {
  45. return 0;
  46. }
  47. return counter;
  48. }
  49. int isSpecialFolder(char* folder)
  50. {
  51. return strcmp(folder, ".") == 0 || strcmp(folder, "..") == 0;
  52. }
  53. Server server;
  54. void interruptHandler(int signal)
  55. {
  56. serverRemove(&server);
  57. exit(EXIT_SUCCESS);
  58. }
  59. void ensureBufferSize(char** data, int* size, int minSize)
  60. {
  61. if(minSize >= *size)
  62. {
  63. int newSize = *size;
  64. while(newSize <= minSize)
  65. {
  66. newSize *= 2;
  67. }
  68. //printf("Resize from %d to %d\n", *size, newSize);
  69. char* newData = malloc(sizeof(char) * newSize);
  70. memcpy(newData, *data, *size);
  71. *size = newSize;
  72. free(*data);
  73. *data = newData;
  74. }
  75. }
  76. void packageSendFailAnswer(int clientSocket)
  77. {
  78. Stream out;
  79. streamInit(&out, 16);
  80. streamWriteInt(&out, 0);
  81. streamWriteChars(&out, "ERR\n");
  82. serverSend(clientSocket, &out);
  83. streamRemove(&out);
  84. }
  85. void packageSendOkAnswer(int clientSocket)
  86. {
  87. Stream out;
  88. streamInit(&out, 16);
  89. streamWriteInt(&out, 0);
  90. streamWriteChars(&out, "OK\n");
  91. serverSend(clientSocket, &out);
  92. streamRemove(&out);
  93. }
  94. int createDirectory(char* path)
  95. {
  96. DIR* dir = opendir(path);
  97. if(dir == NULL)
  98. {
  99. if(mkdir(path, S_ISUID | S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
  100. {
  101. perror("create dir fail");
  102. return -1;
  103. }
  104. dir = opendir(path);
  105. if(dir == NULL)
  106. {
  107. perror("open dir fail");
  108. return -1;
  109. }
  110. }
  111. if(closedir(dir))
  112. {
  113. perror("close dir fail");
  114. return -1;
  115. }
  116. if(chdir(path) == -1)
  117. {
  118. perror("change dir fail");
  119. return -1;
  120. }
  121. return 0;
  122. }
  123. void storeMail(char* sender, char* receiver, char* subject, char* message)
  124. {
  125. /*printf("sender: %s\n", sender);
  126. printf("receiver: %s\n", receiver);
  127. printf("subject: %s\n", subject);
  128. printf("message: %s\n", message);*/
  129. if(createDirectory(receiver) == -1)
  130. {
  131. return;
  132. }
  133. int id = getMailCounter();
  134. if(createDirectory(sender) == -1)
  135. {
  136. return;
  137. }
  138. char buffer[12];
  139. snprintf(buffer, 12, "%d", id);
  140. if(createDirectory(buffer) == -1)
  141. {
  142. return;
  143. }
  144. if(creat(subject, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
  145. {
  146. return;
  147. }
  148. FILE* file = fopen(subject, "w");
  149. if(file == NULL)
  150. {
  151. perror("cant open file");
  152. return;
  153. }
  154. if(fputs(message, file) == EOF)
  155. {
  156. perror("cant write to file");
  157. return;
  158. }
  159. if(fflush(file) == EOF)
  160. {
  161. perror("cant flush the file");
  162. return;
  163. }
  164. if(fclose(file) == EOF)
  165. {
  166. perror("cant close");
  167. return;
  168. }
  169. }
  170. int packageSend(int client, int clientSocket, Stream* in)
  171. {
  172. char c;
  173. int i;
  174. const char* error = "invalid SEND package\n";
  175. // sender
  176. i = 0;
  177. char sender[9];
  178. while(1)
  179. {
  180. if(streamGetChar(in, &c) != -1)
  181. {
  182. if(c == '\n')
  183. {
  184. sender[i] = '\0';
  185. break;
  186. }
  187. else
  188. {
  189. if(i == 8)
  190. {
  191. printf("%s", error);
  192. packageSendFailAnswer(clientSocket);
  193. return 0;
  194. }
  195. sender[i] = c;
  196. i++;
  197. }
  198. }
  199. else
  200. {
  201. printf("%s", error);
  202. packageSendFailAnswer(clientSocket);
  203. return 0;
  204. }
  205. }
  206. if(strlen(sender) == 0)
  207. {
  208. printf("%s", error);
  209. packageSendFailAnswer(clientSocket);
  210. return 0;
  211. }
  212. // receiver
  213. i = 0;
  214. char receiver[9];
  215. while(1)
  216. {
  217. if(streamGetChar(in, &c) != -1)
  218. {
  219. if(c == '\n')
  220. {
  221. receiver[i] = '\0';
  222. break;
  223. }
  224. else
  225. {
  226. if(i == 8)
  227. {
  228. printf("%s", error);
  229. packageSendFailAnswer(clientSocket);
  230. return 0;
  231. }
  232. receiver[i] = c;
  233. i++;
  234. }
  235. }
  236. else
  237. {
  238. printf("%s", error);
  239. packageSendFailAnswer(clientSocket);
  240. return 0;
  241. }
  242. }
  243. if(strlen(receiver) == 0)
  244. {
  245. printf("%s", error);
  246. packageSendFailAnswer(clientSocket);
  247. return 0;
  248. }
  249. // subject
  250. i = 0;
  251. char subject[81];
  252. while(1)
  253. {
  254. if(streamGetChar(in, &c) != -1)
  255. {
  256. if(c == '\n')
  257. {
  258. subject[i] = '\0';
  259. break;
  260. }
  261. else
  262. {
  263. if(i == 80)
  264. {
  265. printf("%s", error);
  266. packageSendFailAnswer(clientSocket);
  267. return 0;
  268. }
  269. subject[i] = c;
  270. i++;
  271. }
  272. }
  273. else
  274. {
  275. printf("%s", error);
  276. packageSendFailAnswer(clientSocket);
  277. return 0;
  278. }
  279. }
  280. if(strlen(subject) == 0)
  281. {
  282. printf("%s", error);
  283. packageSendFailAnswer(clientSocket);
  284. return 0;
  285. }
  286. // message
  287. i = 0;
  288. int buffer = 16;
  289. char* message = malloc(sizeof(char) * buffer);
  290. while(1)
  291. {
  292. if(streamGetChar(in, &c) != -1)
  293. {
  294. if(c == '\n')
  295. {
  296. char n1;
  297. if(streamGetChar(in, &n1) == -1)
  298. {
  299. printf("%s", error);
  300. packageSendFailAnswer(clientSocket);
  301. free(message);
  302. return 0;
  303. }
  304. char n2;
  305. if(streamGetChar(in, &n2) == -1)
  306. {
  307. printf("%s", error);
  308. packageSendFailAnswer(clientSocket);
  309. free(message);
  310. return 0;
  311. }
  312. if(n1 == '.' && n2 == '\n')
  313. {
  314. ensureBufferSize(&message, &buffer, i);
  315. message[i] = '\0';
  316. break;
  317. }
  318. else
  319. {
  320. ensureBufferSize(&message, &buffer, i + 2);
  321. message[i] = c;
  322. i++;
  323. message[i] = n1;
  324. i++;
  325. message[i] = n2;
  326. i++;
  327. continue;
  328. }
  329. }
  330. ensureBufferSize(&message, &buffer, i);
  331. message[i] = c;
  332. i++;
  333. }
  334. else
  335. {
  336. printf("%s", error);
  337. packageSendFailAnswer(clientSocket);
  338. free(message);
  339. return 0;
  340. }
  341. }
  342. char workingPath[256];
  343. if(getcwd(workingPath, 256) != NULL)
  344. {
  345. storeMail(sender, receiver, subject, message);
  346. assert(chdir(workingPath) == 0);
  347. }
  348. free(message);
  349. packageSendOkAnswer(clientSocket);
  350. return 0;
  351. }
  352. void sendMailList(char* user, Stream* out)
  353. {
  354. DIR* dir = opendir(user);
  355. if(dir == NULL)
  356. {
  357. streamWriteInt(out, 0);
  358. return;
  359. }
  360. assert(chdir(user) == 0);
  361. int counterPos = streamGetPosition(out);
  362. streamWriteInt(out, 0);
  363. int counter = 0;
  364. struct dirent* pDir = readdir(dir);
  365. while(pDir != NULL)
  366. {
  367. if(strcmp(pDir->d_name, ".") != 0 && strcmp(pDir->d_name, "..") != 0)
  368. {
  369. DIR* innerdir = opendir(pDir->d_name);
  370. if(innerdir != NULL)
  371. {
  372. assert(chdir(pDir->d_name) == 0);
  373. struct dirent* idDir = readdir(innerdir);
  374. while(idDir != NULL)
  375. {
  376. if(strcmp(idDir->d_name, ".") != 0 && strcmp(idDir->d_name, "..") != 0)
  377. {
  378. counter++;
  379. DIR* innerIdDir = opendir(idDir->d_name);
  380. if(innerIdDir != NULL)
  381. {
  382. struct dirent* mails = readdir(innerIdDir);
  383. while(mails != NULL)
  384. {
  385. if(strcmp(mails->d_name, ".") != 0 && strcmp(mails->d_name, "..") != 0)
  386. {
  387. streamWriteChars(out, idDir->d_name);
  388. streamWriteChars(out, " - ");
  389. streamWriteChars(out, mails->d_name);
  390. streamWriteChar(out, '\n');
  391. }
  392. mails = readdir(innerIdDir);
  393. }
  394. closedir(innerIdDir);
  395. }
  396. }
  397. idDir = readdir(innerdir);
  398. }
  399. assert(chdir("../") == 0);
  400. closedir(innerdir);
  401. }
  402. }
  403. pDir = readdir(dir);
  404. }
  405. int current = streamGetPosition(out);
  406. streamSetPosition(out, counterPos);
  407. streamWriteInt(out, counter);
  408. streamSetPosition(out, current);
  409. closedir(dir);
  410. }
  411. int packageList(int client, int clientSocket, Stream* in)
  412. {
  413. char c;
  414. int i;
  415. const char* error = "invalid LIST package\n";
  416. // user
  417. i = 0;
  418. char user[9];
  419. while(1)
  420. {
  421. if(streamGetChar(in, &c) != -1)
  422. {
  423. if(c == '\n')
  424. {
  425. user[i] = '\0';
  426. break;
  427. }
  428. else
  429. {
  430. if(i == 8)
  431. {
  432. printf("%s", error);
  433. packageSendFailAnswer(clientSocket);
  434. return 0;
  435. }
  436. user[i] = c;
  437. i++;
  438. }
  439. }
  440. else
  441. {
  442. printf("%s", error);
  443. packageSendFailAnswer(clientSocket);
  444. return 0;
  445. }
  446. }
  447. if(strlen(user) == 0)
  448. {
  449. printf("%s", error);
  450. packageSendFailAnswer(clientSocket);
  451. return 0;
  452. }
  453. Stream out;
  454. streamInit(&out, 16);
  455. streamWriteInt(&out, 1);
  456. char workingPath[256];
  457. if(getcwd(workingPath, 256) != NULL)
  458. {
  459. sendMailList(user, &out);
  460. assert(chdir(workingPath) == 0);
  461. }
  462. serverSend(clientSocket, &out);
  463. streamRemove(&out);
  464. return 0;
  465. }
  466. void readMail(char* user, int number, Stream* out)
  467. {
  468. DIR* dir = opendir(user);
  469. if(dir == NULL)
  470. {
  471. streamWriteChars(out, "ERR\n");
  472. return;
  473. }
  474. assert(chdir(user) == 0);
  475. char buffer[12];
  476. snprintf(buffer, 12, "%d", number);
  477. struct dirent* senders;
  478. senders = readdir(dir);
  479. while(senders != NULL)
  480. {
  481. if(strcmp(senders->d_name, ".") != 0 && strcmp(senders->d_name, "..") != 0)
  482. {
  483. if(chdir(senders->d_name) == 0)
  484. {
  485. DIR* innerDir = opendir(buffer);
  486. if(innerDir != NULL)
  487. {
  488. struct dirent* mail;
  489. mail = readdir(innerDir);
  490. while(mail != NULL && (strcmp(mail->d_name, ".") == 0 || strcmp(mail->d_name, "..") == 0))
  491. {
  492. mail = readdir(innerDir);
  493. }
  494. if(mail != NULL)
  495. {
  496. assert(chdir(buffer) == 0);
  497. FILE* file = fopen(mail->d_name, "r");
  498. if(file != NULL)
  499. {
  500. struct stat stats;
  501. if(stat(mail->d_name, &stats) == 0)
  502. {
  503. char* filebuffer = malloc(sizeof(char) * (stats.st_size + 1));
  504. if(fgets(filebuffer, stats.st_size + 1, file) != NULL)
  505. {
  506. streamWriteChars(out, "OK\n");
  507. streamWriteChars(out, filebuffer);
  508. streamWriteChar(out, '\n');
  509. }
  510. else
  511. {
  512. streamWriteChars(out, "ERR\n");
  513. }
  514. }
  515. else
  516. {
  517. streamWriteChars(out, "ERR\n");
  518. }
  519. if(fclose(file) == EOF)
  520. {
  521. perror("cannot close file");
  522. }
  523. }
  524. else
  525. {
  526. streamWriteChars(out, "ERR\n");
  527. }
  528. }
  529. else
  530. {
  531. streamWriteChars(out, "ERR\n");
  532. }
  533. if(closedir(innerDir) == -1)
  534. {
  535. perror("cannot close innerDir");
  536. }
  537. if(closedir(dir) == -1)
  538. {
  539. perror("cannot close dir");
  540. }
  541. return;
  542. }
  543. assert(chdir("../") == 0);
  544. }
  545. }
  546. senders = readdir(dir);
  547. }
  548. if(closedir(dir) == -1)
  549. {
  550. perror("cannot close dir");
  551. }
  552. streamWriteChars(out, "ERR\n");
  553. }
  554. int packageRead(int client, int clientSocket, Stream* in)
  555. {
  556. char c;
  557. int i;
  558. const char* error = "invalid READ package\n";
  559. // user
  560. i = 0;
  561. char user[9];
  562. while(1)
  563. {
  564. if(streamGetChar(in, &c) != -1)
  565. {
  566. if(c == '\n')
  567. {
  568. user[i] = '\0';
  569. break;
  570. }
  571. else
  572. {
  573. if(i == 8)
  574. {
  575. printf("%s", error);
  576. packageSendFailAnswer(clientSocket);
  577. return 0;
  578. }
  579. user[i] = c;
  580. i++;
  581. }
  582. }
  583. else
  584. {
  585. printf("%s", error);
  586. packageSendFailAnswer(clientSocket);
  587. return 0;
  588. }
  589. }
  590. if(strlen(user) == 0)
  591. {
  592. printf("%s", error);
  593. packageSendFailAnswer(clientSocket);
  594. return 0;
  595. }
  596. int number;
  597. if(streamGetInt(in, &number) == -1)
  598. {
  599. printf("%s", error);
  600. packageSendFailAnswer(clientSocket);
  601. return 0;
  602. }
  603. if(streamGetChar(in, &c) == -1)
  604. {
  605. printf("%s", error);
  606. packageSendFailAnswer(clientSocket);
  607. return 0;
  608. }
  609. else if(c != '\n')
  610. {
  611. printf("%s", error);
  612. packageSendFailAnswer(clientSocket);
  613. return 0;
  614. }
  615. Stream out;
  616. streamInit(&out, 16);
  617. streamWriteInt(&out, 2);
  618. char workingPath[256];
  619. if(getcwd(workingPath, 256) != NULL)
  620. {
  621. readMail(user, number, &out);
  622. assert(chdir(workingPath) == 0);
  623. }
  624. else
  625. {
  626. streamWriteChars(&out, "ERR\n");
  627. }
  628. serverSend(clientSocket, &out);
  629. streamRemove(&out);
  630. return 0;
  631. }
  632. int deleteMail(char* user, int number)
  633. {
  634. DIR* dir = opendir(user);
  635. if(dir == NULL)
  636. {
  637. return 0;
  638. }
  639. assert(chdir(user) == 0);
  640. char buffer[12];
  641. snprintf(buffer, 12, "%d", number);
  642. int rValue = 0;
  643. struct dirent* senders;
  644. senders = readdir(dir);
  645. while(senders != NULL)
  646. {
  647. if(strcmp(senders->d_name, ".") != 0 && strcmp(senders->d_name, "..") != 0)
  648. {
  649. if(chdir(senders->d_name) == 0)
  650. {
  651. DIR* innerDir = opendir(buffer);
  652. if(innerDir != NULL)
  653. {
  654. if(chdir(buffer) == -1)
  655. {
  656. perror("cannot change dir");
  657. if(closedir(innerDir) == -1)
  658. {
  659. perror("cannot close innerDir");
  660. }
  661. break;
  662. }
  663. rValue = 1;
  664. struct dirent* mail;
  665. mail = readdir(innerDir);
  666. while(mail != NULL)
  667. {
  668. if(!isSpecialFolder(mail->d_name) && remove(mail->d_name) == -1)
  669. {
  670. perror("cannot delete file");
  671. rValue = 0;
  672. }
  673. mail = readdir(innerDir);
  674. }
  675. if(closedir(innerDir) == -1)
  676. {
  677. perror("cannot close innerDir");
  678. rValue = 0;
  679. }
  680. if(chdir("../") == 0)
  681. {
  682. if(rmdir(buffer) == -1)
  683. {
  684. perror("cannot remove dir");
  685. rValue = 0;
  686. }
  687. }
  688. else
  689. {
  690. perror("cannot change dir");
  691. rValue = 0;
  692. }
  693. break;
  694. }
  695. if(chdir("../") == -1)
  696. {
  697. perror("cannot change dir");
  698. break;
  699. }
  700. }
  701. }
  702. senders = readdir(dir);
  703. }
  704. if(closedir(dir) == -1)
  705. {
  706. perror("cannot close dir");
  707. }
  708. return rValue;
  709. }
  710. int packageDelete(int client, int clientSocket, Stream* in)
  711. {
  712. char c;
  713. int i;
  714. const char* error = "invalid DELETE package\n";
  715. // user
  716. i = 0;
  717. char user[9];
  718. while(1)
  719. {
  720. if(streamGetChar(in, &c) != -1)
  721. {
  722. if(c == '\n')
  723. {
  724. user[i] = '\0';
  725. break;
  726. }
  727. else
  728. {
  729. if(i == 8)
  730. {
  731. printf("%s", error);
  732. packageSendFailAnswer(clientSocket);
  733. return 0;
  734. }
  735. user[i] = c;
  736. i++;
  737. }
  738. }
  739. else
  740. {
  741. printf("%s", error);
  742. packageSendFailAnswer(clientSocket);
  743. return 0;
  744. }
  745. }
  746. if(strlen(user) == 0)
  747. {
  748. printf("%s", error);
  749. packageSendFailAnswer(clientSocket);
  750. return 0;
  751. }
  752. int number;
  753. if(streamGetInt(in, &number) == -1)
  754. {
  755. printf("%s", error);
  756. packageSendFailAnswer(clientSocket);
  757. return 0;
  758. }
  759. if(streamGetChar(in, &c) == -1)
  760. {
  761. printf("%s", error);
  762. packageSendFailAnswer(clientSocket);
  763. return 0;
  764. }
  765. else if(c != '\n')
  766. {
  767. printf("%s", error);
  768. packageSendFailAnswer(clientSocket);
  769. return 0;
  770. }
  771. Stream out;
  772. streamInit(&out, 16);
  773. streamWriteInt(&out, 2);
  774. char workingPath[256];
  775. if(getcwd(workingPath, 256) != NULL)
  776. {
  777. if(deleteMail(user, number))
  778. {
  779. streamWriteChars(&out, "OK\n");
  780. }
  781. else
  782. {
  783. streamWriteChars(&out, "ERR\n");
  784. }
  785. assert(chdir(workingPath) == 0);
  786. }
  787. else
  788. {
  789. streamWriteChars(&out, "ERR\n");
  790. }
  791. serverSend(clientSocket, &out);
  792. streamRemove(&out);
  793. return 0;
  794. }
  795. int packageQuit(int client, int clientSocket, Stream* in)
  796. {
  797. printf("%d wants to disconnect ...\n", client);
  798. return 1;
  799. }
  800. int main(int argc, char** argv)
  801. {
  802. if(argc < 2)
  803. {
  804. printf("Usage: %s directory\n", argv[0]);
  805. return EXIT_FAILURE;
  806. }
  807. serverInitDefaults(&server);
  808. signal(SIGINT, interruptHandler);
  809. signal(SIGKILL, interruptHandler);
  810. if(serverInit(&server, 3, 6543, argv[1]) == -1)
  811. {
  812. return EXIT_FAILURE;
  813. }
  814. serverRegisterHandler(&server, packageSend);
  815. serverRegisterHandler(&server, packageList);
  816. serverRegisterHandler(&server, packageRead);
  817. serverRegisterHandler(&server, packageDelete);
  818. serverRegisterHandler(&server, packageQuit);
  819. serverWaitForConnection(&server);
  820. serverRemove(&server);
  821. return EXIT_SUCCESS;
  822. }