(file) Return to server.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus_unsupported / utils / memo

  1 karl  1.1 /*
  2           **==============================================================================
  3           **
  4           ** Copyright (c) 2003, 2004, 2005 Michael E. Brasher
  5           ** 
  6           ** Permission is hereby granted, free of charge, to any person obtaining a
  7           ** copy of this software and associated documentation files (the "Software"),
  8           ** to deal in the Software without restriction, including without limitation
  9           ** the rights to use, copy, modify, merge, publish, distribute, sublicense,
 10           ** and/or sell copies of the Software, and to permit persons to whom the
 11           ** Software is furnished to do so, subject to the following conditions:
 12           ** 
 13           ** The above copyright notice and this permission notice shall be included in
 14           ** all copies or substantial portions of the Software.
 15           ** 
 16           ** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 17           ** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 18           ** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 19           ** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 20           ** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 21           ** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 22 karl  1.1 ** SOFTWARE.
 23           **
 24           **==============================================================================
 25           */
 26           
 27           #include <cstdio>
 28           #include <cstdlib>
 29           #include <cstring>
 30           #include <cctype>
 31           #include <unistd.h>
 32           #include <fcntl.h>
 33           #include <netinet/in.h>
 34           #include <pthread.h>
 35           #include <cassert>
 36           #include "memo.h"
 37           
 38           unsigned short SERVER_PORT = 8888;
 39           
 40           static int _close_on_exec(int sock)
 41           {
 42               return ::fcntl(sock, F_SETFD, ::fcntl(sock, F_GETFD) | FD_CLOEXEC);
 43 karl  1.1 }
 44           
 45           static void _handle_client_request(int sock)
 46           {
 47               unsigned char request;
 48           
 49               int n = read(sock, &request, sizeof(request));
 50           
 51               if (n == -1)
 52               {
 53           	fprintf(stderr, "MEMO: error reading socket: %d\n", sock);
 54           	return;
 55               }
 56           
 57               switch (tolower(request))
 58               {
 59           	case 't':
 60           	{
 61           	    size_t size = memo_total_bytes();
 62           	    char buffer[64];
 63           	    sprintf(buffer, "%d bytes\n", (int)size);
 64 karl  1.1 	    write(sock, buffer, strlen(buffer) + 1);
 65           	    break;
 66           	}
 67           
 68           	case 'c':
 69           	{
 70           	    memo_check();
 71           	    break;
 72           	}
 73           
 74           	default:
 75           	{
 76           	    const char buffer[] = "Illegal request\n";
 77           	    write(sock, buffer, strlen(buffer) + 1);
 78           	}
 79               }
 80           
 81               close(sock);
 82           }
 83           
 84           void _create_port_file(unsigned port)
 85 karl  1.1 {
 86               char path[64];
 87               sprintf(path, "/tmp/memo.port");
 88           
 89               FILE* os = fopen(path, "wb");
 90           
 91               if (!os)
 92               {
 93           	fprintf(stderr, "MEMO: failed to create port file: %s\n", path);
 94           	assert(0);
 95               }
 96           
 97               fprintf(os, "%u\n", port);
 98               fflush(os);
 99               fclose(os);
100           }
101           
102           void run_server()
103           {
104               // printf("MEMO: server started\n");
105           
106 karl  1.1     //// Initialize server address:
107           
108               sockaddr_in server_addr;
109               bzero(&server_addr, sizeof(sockaddr_in));
110               server_addr.sin_family = AF_INET;
111               server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
112               server_addr.sin_port = 0;
113           
114               //// Figure out which port was used:
115           
116               // htons(SERVER_PORT);
117           
118               //// Create socket:
119           
120               int listen_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
121           
122               _close_on_exec(listen_sock);
123               int opt = 1;
124               setsockopt(listen_sock, SOL_SOCKET, SO_REUSEADDR, (char*)&opt, sizeof opt);
125           
126               bind(listen_sock, (sockaddr*)(&server_addr), sizeof server_addr);
127 karl  1.1 
128               sockaddr_in tmp_addr;
129               socklen_t tmp_len = sizeof(tmp_addr);
130               getsockname(listen_sock, (sockaddr*)&tmp_addr, &tmp_len);
131               _create_port_file(ntohs(tmp_addr.sin_port));
132               
133               listen(listen_sock, 5);
134           
135               //// Accept and handle connections:
136           
137               for (;;)
138               {
139           	sockaddr_in addr;
140           	socklen_t length = sizeof addr;
141           	int sock = accept(listen_sock, (sockaddr*)&addr, &length);
142           
143           	if (sock == -1)
144           	    continue;
145           
146           	_close_on_exec(sock);
147           	_handle_client_request(sock);
148 karl  1.1 	close(sock);
149               }
150           }

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2