ServerMain.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  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. Server server;
  50. void interruptHandler(int signal)
  51. {
  52. serverRemove(&server);
  53. exit(EXIT_SUCCESS);
  54. }
  55. void ensureBufferSize(char** data, int* size, int minSize)
  56. {
  57. if(minSize >= *size)
  58. {
  59. int newSize = *size;
  60. while(newSize <= minSize)
  61. {
  62. newSize *= 2;
  63. }
  64. printf("Resize from %d to %d\n", *size, newSize);
  65. char* newData = malloc(sizeof(char) * newSize);
  66. memcpy(newData, *data, *size);
  67. *size = newSize;
  68. free(*data);
  69. *data = newData;
  70. }
  71. }
  72. void packageSendFailAnswer(int clientSocket)
  73. {
  74. Stream out;
  75. streamInit(&out, 16);
  76. streamWriteInt(&out, 0);
  77. streamWriteChars(&out, "ERR\n");
  78. serverSend(clientSocket, &out);
  79. streamRemove(&out);
  80. }
  81. int createDirectory(char* path)
  82. {
  83. DIR* dir = opendir(path);
  84. if(dir == NULL)
  85. {
  86. if(mkdir(path, S_ISUID | S_ISGID | S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) == -1)
  87. {
  88. perror("create dir fail");
  89. return -1;
  90. }
  91. dir = opendir(path);
  92. if(dir == NULL)
  93. {
  94. perror("open dir fail");
  95. return -1;
  96. }
  97. }
  98. if(closedir(dir))
  99. {
  100. perror("close dir fail");
  101. return -1;
  102. }
  103. if(chdir(path) == -1)
  104. {
  105. perror("change dir fail");
  106. return -1;
  107. }
  108. return 0;
  109. }
  110. void storeMail(char* sender, char* receiver, char* subject, char* message)
  111. {
  112. printf("sender: %s\n", sender);
  113. printf("receiver: %s\n", receiver);
  114. printf("subject: %s\n", subject);
  115. printf("message: %s\n", message);
  116. if(createDirectory(receiver) == -1)
  117. {
  118. return;
  119. }
  120. int id = getMailCounter();
  121. if(createDirectory(sender) == -1)
  122. {
  123. return;
  124. }
  125. char buffer[12];
  126. snprintf(buffer, 12, "%d", id);
  127. if(createDirectory(buffer) == -1)
  128. {
  129. return;
  130. }
  131. if(creat(subject, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) == -1)
  132. {
  133. return;
  134. }
  135. FILE* file = fopen(subject, "w");
  136. if(file == NULL)
  137. {
  138. perror("cant open file");
  139. return;
  140. }
  141. if(fputs(message, file) == EOF)
  142. {
  143. perror("cant write to file");
  144. return;
  145. }
  146. if(fflush(file) == EOF)
  147. {
  148. perror("cant flush the file");
  149. return;
  150. }
  151. if(fclose(file) == EOF)
  152. {
  153. perror("cant close");
  154. return;
  155. }
  156. }
  157. int packageSend(int client, int clientSocket, Stream* in)
  158. {
  159. char c;
  160. int i;
  161. const char* error = "invalid SEND package\n";
  162. // sender
  163. i = 0;
  164. char sender[9];
  165. while(1)
  166. {
  167. if(streamGetChar(in, &c) != -1)
  168. {
  169. if(c == '\n')
  170. {
  171. sender[i] = '\0';
  172. break;
  173. }
  174. else
  175. {
  176. if(i == 8)
  177. {
  178. printf("%s", error);
  179. packageSendFailAnswer(clientSocket);
  180. return 0;
  181. }
  182. sender[i] = c;
  183. i++;
  184. }
  185. }
  186. else
  187. {
  188. printf("%s", error);
  189. packageSendFailAnswer(clientSocket);
  190. return 0;
  191. }
  192. }
  193. if(strlen(sender) == 0)
  194. {
  195. printf("%s", error);
  196. packageSendFailAnswer(clientSocket);
  197. return 0;
  198. }
  199. // receiver
  200. i = 0;
  201. char receiver[9];
  202. while(1)
  203. {
  204. if(streamGetChar(in, &c) != -1)
  205. {
  206. if(c == '\n')
  207. {
  208. receiver[i] = '\0';
  209. break;
  210. }
  211. else
  212. {
  213. if(i == 8)
  214. {
  215. printf("%s", error);
  216. packageSendFailAnswer(clientSocket);
  217. return 0;
  218. }
  219. receiver[i] = c;
  220. i++;
  221. }
  222. }
  223. else
  224. {
  225. printf("%s", error);
  226. packageSendFailAnswer(clientSocket);
  227. return 0;
  228. }
  229. }
  230. if(strlen(receiver) == 0)
  231. {
  232. printf("%s", error);
  233. packageSendFailAnswer(clientSocket);
  234. return 0;
  235. }
  236. // subject
  237. i = 0;
  238. char subject[81];
  239. while(1)
  240. {
  241. if(streamGetChar(in, &c) != -1)
  242. {
  243. if(c == '\n')
  244. {
  245. subject[i] = '\0';
  246. break;
  247. }
  248. else
  249. {
  250. if(i == 80)
  251. {
  252. printf("%s", error);
  253. packageSendFailAnswer(clientSocket);
  254. return 0;
  255. }
  256. subject[i] = c;
  257. i++;
  258. }
  259. }
  260. else
  261. {
  262. printf("%s", error);
  263. packageSendFailAnswer(clientSocket);
  264. return 0;
  265. }
  266. }
  267. if(strlen(subject) == 0)
  268. {
  269. printf("%s", error);
  270. packageSendFailAnswer(clientSocket);
  271. return 0;
  272. }
  273. // message
  274. i = 0;
  275. int buffer = 16;
  276. char* message = malloc(sizeof(char) * buffer);
  277. while(1)
  278. {
  279. if(streamGetChar(in, &c) != -1)
  280. {
  281. if(c == '\n')
  282. {
  283. char n1;
  284. if(streamGetChar(in, &n1) == -1)
  285. {
  286. printf("%s", error);
  287. packageSendFailAnswer(clientSocket);
  288. free(message);
  289. return 0;
  290. }
  291. char n2;
  292. if(streamGetChar(in, &n2) == -1)
  293. {
  294. printf("%s", error);
  295. packageSendFailAnswer(clientSocket);
  296. free(message);
  297. return 0;
  298. }
  299. if(n1 == '.' && n2 == '\n')
  300. {
  301. ensureBufferSize(&message, &buffer, i);
  302. message[i] = '\0';
  303. break;
  304. }
  305. else
  306. {
  307. ensureBufferSize(&message, &buffer, i + 2);
  308. message[i] = c;
  309. i++;
  310. message[i] = n1;
  311. i++;
  312. message[i] = n2;
  313. i++;
  314. continue;
  315. }
  316. }
  317. ensureBufferSize(&message, &buffer, i);
  318. message[i] = c;
  319. i++;
  320. }
  321. else
  322. {
  323. printf("%s", error);
  324. packageSendFailAnswer(clientSocket);
  325. free(message);
  326. return 0;
  327. }
  328. }
  329. char workingPath[256];
  330. if(getcwd(workingPath, 256) != NULL)
  331. {
  332. storeMail(sender, receiver, subject, message);
  333. assert(chdir(workingPath) == 0);
  334. }
  335. free(message);
  336. Stream out;
  337. streamInit(&out, 16);
  338. streamWriteInt(&out, 0);
  339. streamWriteChars(&out, "OK\n");
  340. serverSend(clientSocket, &out);
  341. streamRemove(&out);
  342. return 0;
  343. }
  344. void sendMailList(char* user, Stream* out)
  345. {
  346. DIR* dir = opendir(user);
  347. if(dir == NULL)
  348. {
  349. streamWriteInt(out, 0);
  350. return;
  351. }
  352. assert(chdir(user) == 0);
  353. int counterPos = streamGetPosition(out);
  354. streamWriteInt(out, 0);
  355. int counter = 0;
  356. struct dirent* pDir = readdir(dir);
  357. while(pDir != NULL)
  358. {
  359. if(strcmp(pDir->d_name, ".") != 0 && strcmp(pDir->d_name, "..") != 0)
  360. {
  361. DIR* innerdir = opendir(pDir->d_name);
  362. if(innerdir != NULL)
  363. {
  364. assert(chdir(pDir->d_name) == 0);
  365. struct dirent* idDir = readdir(innerdir);
  366. while(idDir != NULL)
  367. {
  368. if(strcmp(idDir->d_name, ".") != 0 && strcmp(idDir->d_name, "..") != 0)
  369. {
  370. counter++;
  371. DIR* innerIdDir = opendir(idDir->d_name);
  372. if(innerIdDir != NULL)
  373. {
  374. struct dirent* mails = readdir(innerIdDir);
  375. while(mails != NULL)
  376. {
  377. if(strcmp(mails->d_name, ".") != 0 && strcmp(mails->d_name, "..") != 0)
  378. {
  379. streamWriteChars(out, idDir->d_name);
  380. streamWriteChars(out, " - ");
  381. streamWriteChars(out, mails->d_name);
  382. streamWriteChar(out, '\n');
  383. }
  384. mails = readdir(innerIdDir);
  385. }
  386. closedir(innerIdDir);
  387. }
  388. }
  389. idDir = readdir(innerdir);
  390. }
  391. assert(chdir("../") == 0);
  392. closedir(innerdir);
  393. }
  394. }
  395. pDir = readdir(dir);
  396. }
  397. int current = streamGetPosition(out);
  398. streamSetPosition(out, counterPos);
  399. streamWriteInt(out, counter);
  400. streamSetPosition(out, current);
  401. closedir(dir);
  402. }
  403. int packageList(int client, int clientSocket, Stream* in)
  404. {
  405. char c;
  406. int i;
  407. const char* error = "invalid LIST package\n";
  408. // user
  409. i = 0;
  410. char user[9];
  411. while(1)
  412. {
  413. if(streamGetChar(in, &c) != -1)
  414. {
  415. if(c == '\n')
  416. {
  417. user[i] = '\0';
  418. break;
  419. }
  420. else
  421. {
  422. if(i == 8)
  423. {
  424. printf("%s", error);
  425. packageSendFailAnswer(clientSocket);
  426. return 0;
  427. }
  428. user[i] = c;
  429. i++;
  430. }
  431. }
  432. else
  433. {
  434. printf("%s", error);
  435. packageSendFailAnswer(clientSocket);
  436. return 0;
  437. }
  438. }
  439. if(strlen(user) == 0)
  440. {
  441. printf("%s", error);
  442. packageSendFailAnswer(clientSocket);
  443. return 0;
  444. }
  445. Stream out;
  446. streamInit(&out, 16);
  447. streamWriteInt(&out, 1);
  448. char workingPath[256];
  449. if(getcwd(workingPath, 256) != NULL)
  450. {
  451. sendMailList(user, &out);
  452. assert(chdir(workingPath) == 0);
  453. }
  454. serverSend(clientSocket, &out);
  455. streamRemove(&out);
  456. return 0;
  457. }
  458. int packageRead(int client, int clientSocket, Stream* in)
  459. {
  460. char c;
  461. int i;
  462. const char* error = "invalid READ package\n";
  463. // user
  464. i = 0;
  465. char user[9];
  466. while(1)
  467. {
  468. if(streamGetChar(in, &c) != -1)
  469. {
  470. if(c == '\n')
  471. {
  472. user[i] = '\0';
  473. break;
  474. }
  475. else
  476. {
  477. if(i == 8)
  478. {
  479. printf("%s", error);
  480. packageSendFailAnswer(clientSocket);
  481. return 0;
  482. }
  483. user[i] = c;
  484. i++;
  485. }
  486. }
  487. else
  488. {
  489. printf("%s", error);
  490. packageSendFailAnswer(clientSocket);
  491. return 0;
  492. }
  493. }
  494. if(strlen(user) == 0)
  495. {
  496. printf("%s", error);
  497. packageSendFailAnswer(clientSocket);
  498. return 0;
  499. }
  500. int number;
  501. if(streamGetInt(in, &number) == -1)
  502. {
  503. printf("%s", error);
  504. packageSendFailAnswer(clientSocket);
  505. return 0;
  506. }
  507. if(streamGetChar(in, &c) == -1)
  508. {
  509. printf("%s", error);
  510. packageSendFailAnswer(clientSocket);
  511. return 0;
  512. }
  513. else if(c != '\n')
  514. {
  515. printf("%s", error);
  516. packageSendFailAnswer(clientSocket);
  517. return 0;
  518. }
  519. printf("user: %s\n", user);
  520. printf("number: %d\n", number);
  521. Stream out;
  522. streamInit(&out, 16);
  523. streamWriteInt(&out, 0);
  524. streamWriteChars(&out, "OK\n");
  525. serverSend(clientSocket, &out);
  526. streamRemove(&out);
  527. return 0;
  528. }
  529. int packageDelete(int client, int clientSocket, Stream* in)
  530. {
  531. char c;
  532. int i;
  533. const char* error = "invalid DELETE package\n";
  534. // user
  535. i = 0;
  536. char user[9];
  537. while(1)
  538. {
  539. if(streamGetChar(in, &c) != -1)
  540. {
  541. if(c == '\n')
  542. {
  543. user[i] = '\0';
  544. break;
  545. }
  546. else
  547. {
  548. if(i == 8)
  549. {
  550. printf("%s", error);
  551. packageSendFailAnswer(clientSocket);
  552. return 0;
  553. }
  554. user[i] = c;
  555. i++;
  556. }
  557. }
  558. else
  559. {
  560. printf("%s", error);
  561. packageSendFailAnswer(clientSocket);
  562. return 0;
  563. }
  564. }
  565. if(strlen(user) == 0)
  566. {
  567. printf("%s", error);
  568. packageSendFailAnswer(clientSocket);
  569. return 0;
  570. }
  571. int number;
  572. if(streamGetInt(in, &number) == -1)
  573. {
  574. printf("%s", error);
  575. packageSendFailAnswer(clientSocket);
  576. return 0;
  577. }
  578. if(streamGetChar(in, &c) == -1)
  579. {
  580. printf("%s", error);
  581. packageSendFailAnswer(clientSocket);
  582. return 0;
  583. }
  584. else if(c != '\n')
  585. {
  586. printf("%s", error);
  587. packageSendFailAnswer(clientSocket);
  588. return 0;
  589. }
  590. printf("user: %s\n", user);
  591. printf("number: %d\n", number);
  592. Stream out;
  593. streamInit(&out, 16);
  594. streamWriteInt(&out, 0);
  595. streamWriteChars(&out, "OK\n");
  596. serverSend(clientSocket, &out);
  597. streamRemove(&out);
  598. return 0;
  599. }
  600. int packageQuit(int client, int clientSocket, Stream* in)
  601. {
  602. printf("%d wants to disconnect ...\n", client);
  603. return 1;
  604. }
  605. int main(int argc, char** argv)
  606. {
  607. if(argc < 2)
  608. {
  609. printf("Usage: %s directory\n", argv[0]);
  610. return EXIT_FAILURE;
  611. }
  612. serverInitDefaults(&server);
  613. signal(SIGINT, interruptHandler);
  614. signal(SIGKILL, interruptHandler);
  615. if(serverInit(&server, 3, 6543, argv[1]) == -1)
  616. {
  617. return EXIT_FAILURE;
  618. }
  619. serverRegisterHandler(&server, packageSend);
  620. serverRegisterHandler(&server, packageList);
  621. serverRegisterHandler(&server, packageRead);
  622. serverRegisterHandler(&server, packageDelete);
  623. serverRegisterHandler(&server, packageQuit);
  624. serverWaitForConnection(&server);
  625. serverRemove(&server);
  626. return EXIT_SUCCESS;
  627. }