sending recv() data to a file



I am creating a server which recv()s the data from the client and send()s
it to a file. The basic design idea is to have a log-server which writes a
file after receiving log information from the clients.

WANTED:

It should work like syslog in Linux:

1.) It will read data from client and creates a new file say "mylog.log"

2.) It will check if a file of same name "mylog.log" already exists and if
its size if less than say 100 KB.

(a) If the size of file is less than 100KB then server will append the
data to that file.

(b)If the size of the file is equal to 100KB then server will create a
new file with same name "mylog.log" after moving the old file to name
like "mylog.log.0" or "mylog.log.5" etc.

(c) if the size of file is less than 100 KB and writing data to file
makes it larger than 100 KB, then server should create a new file.

3.) if the total number of files increase by 10, then server should delete
the oldest file which will be "mylog.log.10"


PROBLEM:
All I know is how to open/create/append to the file( fopen() ) but how to
give same name to each file with a numeric ending and how to determine the
size of the file before reading/writing is beyond my understanding. I have
written the code till recv(), using poll() for multiplexing to save CPU
usage but at the file thing I am dead :( . any help


/* CLS server to handle client logs */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <poll.h>

#define SERVER_IP "127.0.0.1"
#define LOG_NAME "cls.log"


enum { ARRSIZE = 1001, BACKLOG = 10, FILESIZE = 100, LOGNUM_MAX = 10 };


int main( int argc, char** argv )
{
int sockfd, acceptfd;
int MYPORT, CONN_MAX;
struct sockaddr_in servaddr, cliaddr;
int recv_bytes, clilen;
char buff[ARRSIZE];

/* Log file preparaion */
int log_cnt;


log_cnt = 0;


if( argc != 3 )
{
perror("USAGE: ./file NUMBER-OF-CLIENTS PORT");
exit( EXIT_FAILURE );
}
else
{
CONN_MAX = atoi( argv[1] );
MYPORT = atoi( argv[2] );
}

memset( &servaddr, '\0', sizeof(struct sockaddr_in) );
memset( &cliaddr, '\0', sizeof(struct sockaddr_in) );


/* poll() preparation */
struct pollfd clients[CONN_MAX];
int nready, curr_index, max_index;
int i, j; /* variables used for indexing */

/* initialize socket internet structures */
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(MYPORT);
if( inet_pton(AF_INET, SERVER_IP, &servaddr.sin_addr) < 0 )
{
perror("INET_PTON() error");
exit( EXIT_FAILURE );
}

if( (sockfd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
{
perror("SOCKET() error");
exit( EXIT_FAILURE );
}

printf("SOCKET() done\n");
if( bind(sockfd, (struct sockaddr*)&servaddr, sizeof(struct sockaddr)) < 0 )
{
perror("BIND() error");
exit( EXIT_FAILURE );
}

printf("BIND() done\n");
if( listen(sockfd, BACKLOG) < 0 )
{
perror("LISTEN() error");
exit( EXIT_FAILURE );
}

printf("LISTEN() done\n");
/*poll() initalization */
clients[0].fd = sockfd;
clients[0].events = POLLIN;
curr_index = 0;
max_index = 0;

printf("Entering POLL()'s infinite LOOP\n");

for( ; ; )
{
if( (nready = poll(clients, max_index + 1, -1)) <= 0 )
{
perror("POLL() error");
exit(EXIT_FAILURE);
}

printf("POLL() done\n");
if( clients[0].revents & POLLIN )
{
/* check if we are exceeding the maximum connections */
if( curr_index > CONN_MAX )
{
perror("too many connections");
continue;
}

clilen = sizeof( struct sockaddr_in );
if( (acceptfd = accept(sockfd, (struct sockaddr*)&cliaddr, &clilen)) < 0 )
{
perror("ACCEPT() error");
exit( EXIT_FAILURE );
}

printf("ACCEPTED\n");
for( i=1; i < CONN_MAX; ++i )
{
if( clients[i].fd < 0 )
{
clients[i].fd = acceptfd;
/* FD added, so we don't need to do anything else */
break;
}
}

if( curr_index > max_index )
{
max_index = curr_index;
}

if( --nready <= 0 )
{
continue;
}

} /* finished with checking the readable FDs */


/* check the readbale FDs for data */
for( j = 0; j < max_index; ++j )
{
if( clients[j].fd < 0 )
{
continue;
}

if( clients[j].fd & (POLLIN | POLLERR) )
{
if( (recv_bytes = recv(clients[j].fd, buff, ARRSIZE, 0)) <= 0 )
{
perror("CLIENT_SIDE problem");
close( clients[i].fd );
clients[j].fd = -1;
}
else
{
/* save that data to a text-file

1.) check if we are exceeding the number of files:
(a) if we are exceeding, remove the oldest text-file and create a new file.
(b) else go to step 2
2.) check if we are exceeding the size of the file being written to:
(a) if yes, create a new file
(b) else, append the data to the latest file.
*/

}

if( --nready <= 0 )
{
break; /* no more redable FDs, so break out of this reading data loop */
}
}
} /* for loop for reading data */
} /* for( ; ; ) loop */


return 0;
}


--
www.lispmachine.wordpress.com
my email is @ the above blog
check the "About Myself" page

.



Relevant Pages

  • RE: SSPI Kerberos for delegation
    ... you have to check on 'trust this machine for delegation' in the server computer's ADUC property page. ... Doing this will tell the client kerberos package that it should get a forwardable ticket and that it should forward it ... int n = ib.cbBuffer; ... // wserr() displays winsock errors and aborts. ...
    (comp.protocols.kerberos)
  • [NT] Dark Age of Camelot Man-In-The-Middle
    ... use of RSA public key cryptography and an RC4 based symmetric algorithm. ... Seeing the imminent release of code for cracking the game client (which ... At the beginning of each TCP session, the server sends a 1536 bit RSA ... void bytes_out(unsigned char *data, int len) ...
    (Securiteam)
  • Re: Problem with SslStream when using Windows Vista
    ... The code for the server & client follow. ... private int _port = 0; ... // SslStream using the client's network stream. ...
    (microsoft.public.dotnet.framework)
  • [UNIX] Multiple up-imapproxy DoS Vulnerabilities
    ... The following security advisory is sent to the securiteam mailing list, and can be found at the SecuriTeam web site: http://www.securiteam.com ... connections open after client has logged out, ... allows attacker to cause the server to crash by sending them when they ... extern void HandleRequest(int); ...
    (Securiteam)
  • echo client using threads
    ... pollwhile client is written using threads. ... server recvs some characters from a client and then echoes the ... int main ... exit(EXIT_FAILURE); ...
    (comp.unix.programmer)