/new_server_clnt/open.c

https://github.com/blackav/ejudge · C · 85 lines · 57 code · 15 blank · 13 comment · 7 complexity · 58bc0e0f9804787b39d7d54c224ff03d MD5 · raw file

  1. /* -*- mode: c -*- */
  2. /* Copyright (C) 2006-2016 Alexander Chernov <cher@ejudge.ru> */
  3. /*
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. */
  14. #include "new_server_clnt/new_server_clnt_priv.h"
  15. #include "ejudge/new_server_proto.h"
  16. #include "ejudge/errlog.h"
  17. #include "ejudge/sock_op.h"
  18. #include "ejudge/xalloc.h"
  19. #include "ejudge/osdeps.h"
  20. #include <signal.h>
  21. #include <unistd.h>
  22. #include <sys/types.h>
  23. #include <sys/socket.h>
  24. #include <sys/un.h>
  25. int
  26. new_server_clnt_open(const unsigned char *socketpath, new_server_conn_t *p_conn)
  27. {
  28. int fd = -1;
  29. int max_path_buf;
  30. struct sockaddr_un addr;
  31. int code = -1;
  32. new_server_conn_t new_conn = 0;
  33. signal(SIGPIPE, SIG_IGN);
  34. if (!socketpath) return -NEW_SRV_ERR_BAD_SOCKET_NAME;
  35. max_path_buf = sizeof(struct sockaddr_un) -
  36. XOFFSET(struct sockaddr_un, sun_path);
  37. if (strlen(socketpath) >= max_path_buf) {
  38. err("new_server_clnt_open: socket path length is too long (%zu)",
  39. strlen(socketpath));
  40. return -NEW_SRV_ERR_BAD_SOCKET_NAME;
  41. }
  42. if ((fd = socket(PF_UNIX, SOCK_STREAM, 0)) < 0) {
  43. err("new_server_clnt_open: socket() failed: %s", os_ErrorMsg());
  44. code = -NEW_SRV_ERR_SYSTEM_ERROR;
  45. goto failure;
  46. }
  47. if (sock_op_enable_creds(fd) < 0) {
  48. code = -NEW_SRV_ERR_SYSTEM_ERROR;
  49. goto failure;
  50. }
  51. memset(&addr, 0, sizeof(addr));
  52. addr.sun_family = AF_UNIX;
  53. strncpy(addr.sun_path, socketpath, max_path_buf - 1);
  54. if (connect(fd, (struct sockaddr*) &addr, sizeof(addr)) < 0) {
  55. err("new_server_clnt_open: connect() failed: %s", os_ErrorMsg());
  56. code = -NEW_SRV_ERR_CONNECT_FAILED;
  57. goto failure;
  58. }
  59. if (sock_op_put_creds(fd) < 0) {
  60. code = -NEW_SRV_ERR_WRITE_ERROR;
  61. goto failure;
  62. }
  63. XCALLOC(new_conn, 1);
  64. new_conn->fd = fd;
  65. *p_conn = new_conn;
  66. return 0;
  67. failure:
  68. if (fd >= 0) close(fd);
  69. return code;
  70. }