⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket_server.cpp

📁 用于使用moden进行传真的源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/* Copyright (C) 2003 Chris VineThis program is distributed under the General Public Licence, version 2.For particulars of this and relevant disclaimers see the fileCOPYING distributed with the source files.*/#include <cstdlib>#include <fstream>#include <vector>#include <algorithm>#include <cstring>#include <sys/stat.h>#include <sys/types.h>#include <signal.h>#include <sys/socket.h>#include <arpa/inet.h>#include <unistd.h>#include <netdb.h>#include <errno.h>#ifdef HAVE_PTHREAD_SIGMASK #include <pthread.h>#endif#include <glibmm/convert.h>#include "socket_server.h"#ifdef ENABLE_NLS#include <libintl.h>#endif#define SAVED_FAX_FILENAME  ".efax-gtk_queued_server_files"#define BUFFER_LENGTH 1024Socket_server::Socket_server(void): server_running(false), closing_socket(false),				    serve_sock_fd(-1), count (0),                                    homedir(prog_config.homedir),				    filenames_s(new(FilenamesList)) {  // we have included std::string homedir member so that we can access it in the  // socket server thread created by Socket_server::start() without having to  // introduce locking of accesses to prog_config.homedir by the main GUI thread  // it is fine to initialise it in the initialisation list of this constructor  // as prog_config.homedir is only set once, on the first call to configure_prog()  // (that is, when configure_prog() is passed false as its argument)  fax_to_send.second = 0;  stdout_notify.connect(sigc::mem_fun(*this, &Socket_server::write_stdout_dispatcher_slot));  // make sure that we have the $HOME/efax-gtk-server directory  // (we do not need to lock homedir_mutex as the socket server thread cannot  // be running at this point)  std::string dir_name(homedir);  dir_name += "/efax-gtk-server";  mkdir(dir_name.c_str(), S_IRUSR | S_IWUSR | S_IXUSR);  // now populate the queued faxes from server list    read_queued_faxes();}void Socket_server::start(const std::string& port_, bool other_sock_client_address_) {  if (!server_running) {    port = port_;    other_sock_client_address = other_sock_client_address_;    server_running = true;    // now block off the signals for which we have set handlers so that the socket server    // thread does not receive the signals, otherwise we will have memory synchronisation    // issues in multi-processor systems - we will unblock in the initial (GUI) thread    // as soon as the socket server thread has been launched    sigset_t sig_mask;    sigemptyset(&sig_mask);    sigaddset(&sig_mask, SIGCHLD);    sigaddset(&sig_mask, SIGQUIT);    sigaddset(&sig_mask, SIGTERM);    sigaddset(&sig_mask, SIGINT);    sigaddset(&sig_mask, SIGHUP);#ifdef HAVE_PTHREAD_SIGMASK     pthread_sigmask(SIG_BLOCK, &sig_mask, 0);#else    sigprocmask(SIG_BLOCK, &sig_mask, 0);#endif    try {      Glib::Thread::create(sigc::mem_fun(*this, &Socket_server::socket_thread), false);    }    catch (Glib::ThreadError&) {      write_error("Cannot start new socket thread, fax socket will not run\n");      server_running = false;    }    // now unblock the signals so that the initial (GUI) thread can receive them#ifdef HAVE_PTHREAD_SIGMASK     pthread_sigmask(SIG_UNBLOCK, &sig_mask, 0);#else    sigprocmask(SIG_UNBLOCK, &sig_mask, 0);#endif  }}void Socket_server::socket_thread(void) {  { // mutex critical section    Glib::Mutex::Lock lock(socket_mutex);    if ((serve_sock_fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {      write_error("Cannot create socket for socket server\n");      server_running = false;      return;    }    sockaddr_in serve_address;    serve_address.sin_family = AF_INET;    if (other_sock_client_address) serve_address.sin_addr.s_addr = htonl(INADDR_ANY);    else {      long localhost_address = inet_addr("127.0.0.1");      if (localhost_address > -1) serve_address.sin_addr.s_addr = localhost_address;      else {	write_error("Cannot create network address for localhost\n");	close(serve_sock_fd);	serve_sock_fd = -1;	server_running = false;	return;      }    }    serve_address.sin_port = htons(std::atoi(port.c_str()));        if ((bind(serve_sock_fd, (sockaddr*)&serve_address, sizeof(serve_address))) < 0) {      write_error("Cannot bind to socket for socket server\n");      close(serve_sock_fd);      serve_sock_fd = -1;      server_running = false;      return;    }    if ((listen(serve_sock_fd, 5)) < 0) {      write_error("Cannot listen on socket of socket server\n");      close(serve_sock_fd);      serve_sock_fd = -1;      server_running = false;      return;    }  } // end of mutex critical section  std::string message(gettext("Socket running on port "));  message += port;  message += '\n';  write_stdout_from_thread(message.c_str());  // now wait for clients to connect, and continue  while (accept_on_client());  write_stdout_from_thread("Closing the socket\n");  server_running = false;  close_sem.post();}bool Socket_server::accept_on_client(void) {  bool return_val = false;  sockaddr_in connect_address;  socklen_t client_len = sizeof(connect_address);  int connect_sock_fd = accept(serve_sock_fd, (sockaddr*)&connect_address, &client_len);  // go into mutex critical section here  Glib::Mutex::Lock lock(socket_mutex);  if (connect_sock_fd >= 0      && is_valid_peer(connect_address)) {    std::string filename;    {      Glib::Mutex::Lock lock(homedir_mutex);      filename = homedir;    }    filename += "/efax-gtk-server/efax-gtk-server-XXXXXX";    std::string::size_type size = filename.size() + 1;    char* tempfile = new char[size];    std::memcpy(tempfile, filename.c_str(), size); // this will include the terminating '\0' in the copy    int file_fd = mkstemp(tempfile);    if (file_fd < 0) {            write_error("Can't open temporary file for socket server\n"		  "This fax will not be processed.  Is the disk full?\n");      close(connect_sock_fd);      stop();      return_val = false;    }    else read_socket(file_fd, connect_sock_fd, tempfile);    delete[] tempfile;    close(connect_sock_fd);    close(file_fd);    return_val = true;  }  else if (connect_sock_fd >= 0) {    // if we have got here then the peer is invalid - reject it by    // closing connect_sock_fd    write_error("Invalid host tried to connect to the socket server\n");    close(connect_sock_fd);    return_val = true;  }  else if (closing_socket) closing_socket = false; // stop() has been called  else{    // if we have got here, connect_sock_fd is in error condition (otherwise it    // would have been picked up in the previous else_if blocks) - report the    // problem    write_error("There is a problem with receiving a connection on the socket server\n");    return_val = true;  }  return return_val;}void Socket_server::read_socket(int file_fd, int connect_sock_fd, const char* file) {  char buffer[BUFFER_LENGTH];  ssize_t read_result;  ssize_t write_result;  while ((read_result = read(connect_sock_fd, buffer, BUFFER_LENGTH)) > 0	 || read_result == -1 && errno == EINTR) {    if (read_result > 0) {      do {	write_result = write(file_fd, buffer, read_result);      } while (write_result == -1 && errno == EINTR);    }  }  if (!read_result) {                                   // normal close by client      write_stdout_from_thread(gettext("Print job received on socket\n"));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -