Why is this custom network-service crashing (written in C)? - c

I wrote this program which listens on a given port and then, once a connection is received, outputs a single line of text and disconnects. It runs for days, processing thousands of queries, but then (inevitably) crashes and I have to go restart it. Wondering if anyone sees anything wrong with it, or (alternatively) if anyone can suggest a way to make it more robust.
int main(int argc, char *argv[])
{
srand(time(0));
int sockfd, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1)
{
unsigned char write_val;
unsigned char y[BYTES];
int i, j;
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
fill_buffer(y); // fills buffer y with a 128-bit string; not included here
for (i=BYTES-1; i >= 0; i--)
{
const void* ZERO = (void *)"0";
const void* ONE = (void *)"1";
for (j=7; j >= 0; j--)
write(newsockfd, (y[i] >> j) & 1 ? ONE : ZERO, 1);
}
write(newsockfd, "\n", 1);
close(newsockfd);
}
close(sockfd);
return 0;
}

anyone sees anything wrong with it
While this code could be made more efficient (by writing all the bytes in one single pass for example), there's no obvious flaw there.
That makes the unpublished part of your code a decent candidate for the problem:
fill_buffer(y); // fills buffer y with a 128-bit string; not included here
If you read more bytes than y[]'s size then you will crash.
or (alternatively) if anyone can suggest a way to make it more robust
Try enlarging the size of this y[] buffer (doubling it can't hurt).
And make sure that fill_buffer() can't read more than BYTES characters.
Publish this missing code in case of doubt.
You could also compile your code with debug symbols and dump a backtrace (with symbols) in a file from your signal handler. This way, if your program crashes, you will know where and why.

The code looks good with some comments.
One somewhat important comment:
portno should be declared as unsigned short. This works OK with an Intel-like (little endian) processor but it won't be portable to a processor with different endianness.
Anyway it was not the reason for your process crashing.
Obviously the crash occurs while executing within the 'while', and by looking at the code, if it crashes for a buffer overflow, the only possibility is within fill_buffer.
If you show the definition of BYTES and fill_buffer it will be easier to help you.
Now, if it is not a buffer overflow, there is the possibility that it aborts in the write if the client closed the connection before the server writes into the socket. In that case the process will receive a signal SIGPIPE and it will abort if the code does not handle that signal.
You can also ignore SIGPIPE with:
signal(SIGPIPE, SIG_IGN);
Other possibility is if you are doing something weird with write_val and you're not showing that code.
I hope this helps.

Related

Sending a file content to a server: Socket

My code reads from a file line by line and sends it to a server.
client.c
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
FILE* pFile;
char* line = NULL;
//char buffer[256];
char* buffer;
int len;
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
pFile = fopen ("myfile.txt","r");
if (pFile==NULL)
{
printf("Error reading temp file\n");
exit (1);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
//loop
while (!feof(pFile)) {
//printf("Please enter the message: ");
line = readLine(pFile, line);
len=strlen(line);
buffer= (char*) malloc((len+1)*sizeof(char));
bzero(buffer,len);
memcpy(buffer,line,len+1);
// fgets(buffer,len,pFile);
printf("%s\n", buffer);
n = write(sockfd,buffer,strlen(buffer)+1);
if (n < 0)
error("ERROR writing to socket");
free(buffer);
free(line);
}
buffer= (char*) malloc(2048*sizeof(char));
bzero(buffer,2048);
n = read(sockfd,buffer,2048);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
free(buffer);
fclose (pFile);
close(sockfd);
return 0;
}
And
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(const char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[2048];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
else
printf("Socket connected\n");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
printf("Data Receieved by client: \n");
bzero(buffer,2048);
n=read(newsockfd,buffer,2048);
if (n < 0) error("ERROR reading from socket");
printf("%s\n",buffer);
n = write(newsockfd,"Server received the message",18);
if (n < 0)
error("ERROR writing to socket");
close(newsockfd);
close(sockfd);
return 0;
}
The problem is that the server reveives a few lines and misses a few. Not able to figure out what is wrong. Can some one help?
Client Side
[gaurav1.k#DELL-BUILD03 Socket]$ gcc -Wall client.c -o client.exe
[gaurav1.k#DELL-BUILD03 Socket]$ ./client.exe localhost 8000
I am line number One,am I?
Here comes line number Two.
Will you welcome, Line number Three? And I am your Friend.
I am here, It is me - Line number Four.
Hello All, I am line number Five, am I? Yes I am.
It is over, because I am line number six.
Server received th
[gaurav1.k#DELL-BUILD03 Socket]$
Server Side:
[gaurav1.k#DELL-BUILD03 Socket]$ gcc -Wall server.c -o server.exe
[gaurav1.k#DELL-BUILD03 Socket]$ ./server.exe 8000
Socket connected
Data Receieved by client:
I am line number One,am I?
[gaurav1.k#DELL-BUILD03 Socket]$
The content of file to be read is:
I am line number One,am I?
Here comes line number Two.
Will you welcome, Line number Three? And I am your Friend.
I am here, It is me - Line number Four.
Hello All, I am line number Five, am I? Yes I am.
It is over, because I am line number six.
For a scenario like this you usually want to implement a kind of communication protocol.
Most importantly, the server needs to know how many bytes it has to read to receive the whole content. So usually, you transfer the message size as the first part of your message (header). Then the server knows how many bytes to receive after that to consume the actual payload data.
The problem is multiple write at the client side, but only one read at the server side. How?
For every line the client will write into the socket, that is multiple write(you are using write in a loop), but in server you are having one read, that is single read(no loop's, so it will read only the first line).
For first line, you are reading at server side. But for second line the client is writing, but your server have no read statement(first read is already executed). Due to this you wont receive the full message
A simple solution is write the whole file content at a time, not line by line and read it.
Try the below change also-
n = write(newsockfd,"Server received the message",50); // Increase the size
It looks like the problem is that you don't check the result of the read and write functions, which can fail in partial success states, indicating the number of bytes they've successfully transferred. In general, you need to wrap these functions in a loop that repeats until the entire buffer has been read/written.
On top of the failure to properly account for the returns from system calls, as described by other posters, there is:
bzero(buffer,2048);
n=read(newsockfd,buffer,2048)
..
printf("%s\n",buffer);
If the read() returns 2048 bytes, the printf can UB as it tries to find a non-existent null after the end of the buffer. Either allocate/clear 2049 of read 2047, and even that will only work well for transferring plain ASCII text files, (ie files with no embedded nulls).

C http server stops after unpredictable time

I am writing a custom HTTP server in C for my OpenWrt router. It makes use of the uclibc library. I am only using one static buffer which I am very careful not to overflow, and no multi-threading is involved. It doesn't contain any complex data structures, and what it does is that:
it listen() s on the socket
reads the request after accept() ing
gets an html page by sending an http request to a predefined remote server (not a proxy)
sends the result through the accepted connection, and closes both.
The program would just stop running after some time, (it can be on receiving the first request, or after working under heavy strain for more that 2 hours). I am getting no error messages through the console, or anything, the program just stops. I have watched it and, as expected it doesn't consume more and more memory as it runs...
Is it possible that the kernel stops it if it thinks its abusing the CPU? How do I overcome that?
Are there some quirks to watch for in socket programming in C that are known to cause such crashes?
Can the stability issues be caused by using the Barrier Bracker (bleeding edge) branch of OpenWrt? Although the router itself never stops working...
Where do I start to look for the source of the problem?
Ok, first, I would like to thank everybody for helping. After writing a lot of netcat testers, I have pinpointed the problem. The program would crash - end without a single error message, if the connection is closed by the client before the last write or read occurs.
The write or read would raise a SIGPIPE signal which by default crashed the program if not handled manually... More info here: How to prevent SIGPIPE or prevent the server from ending?
This seems to be similar to what your trying to do,
as shown on http://www.cs.rpi.edu/~moorthy/Courses/os98/Pgms/socket.html
Is this socket setup the same/similar to what your performing in your code?
/* A simple server in the internet domain using TCP
The port number is passed as an argument */
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
void error(char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
return 0;
}

Implementing poll() on a TCP server's read/write

I need this server to be able to listen for and establish new connections with clients while simultaneously writing to existing connections.. ie. Asynchronous non-blocking i/o. I've been told to use poll() but after spending an inordinate amount of time simply trying to grasp socket programming, I'm still unsure how implement the poll() function.
int sockfd;
int main(int argc, char *argv[])
{
int newsockfd, portno;
socklen_t clilen;
char buffer[256];
struct sockaddr_in serv_addr, cli_addr;
int n;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
while(1){
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
// READ READ READ READ READ READ READ READ READ READ READ READ READ READ READ READ
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
// WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE WRITE
n = write(newsockfd,"I got your message",18);
if (n < 0) error("ERROR writing to socket");
close(newsockfd);
}
return 0;
}
My understanding is that I need to build something like this:
// Set up array of file descriptors for polling
struct pollfd ufds[2];
ufds[0].fd = sockfd;
ufds[0].events = POLLIN;
ufds[1].fd = newsockfd;
ufds[1].events = POLLOUT;
and use poll(ufds,2,2000); inside the loop to check whether sockfd or newsockfd have any activity, in which case I use the appropriate read or write.. If anybody could give me some guidance I'd be very appreciative.
The kernel will fill in the events that occurred in the revents field of your struct pollfd array.
From the manual page:
The field revents is an output parameter, filled by the kernel with the events that actually occurred. The bits returned in revents can include any of those specified in events, or one of the values POLLERR, POLLHUP, or POLLNVAL. (These three bits are meaningless in the events field, and will be set in the revents field whenever the corresponding condition is true.)
If you want event notifications for accepted connections, then you need to either reserve space in advance or resize the struct pollfd array for every connection.
You'll need some way to differentiate the listening socket. You could store it in index zero of your array.
int i, n;
n = poll(ufds, num_fds_in_array, timeout_value);
/* errors or timeout? */
if (n < 1)
;
for (i = 0; i < num_fds_in_array; i++) {
/* were there any events for this socket? */
if (!ufds[i].revents)
continue;
/* is it our listening socket? */
if (!i) {
if (ufds[0].revents & POLLIN)
/* call accept() and add the new socket to ufds */
else
/* error */
continue;
}
/* is there incoming data on the socket? */
if (ufds[i].revents & POLLIN)
/* call recv() on the socket and decide what to do from there */
}
The POLLOUT flag is used to signal when the sending data on the socket will not block the caller.
For non-blocking I/O, I'd use a more powerful API since it requires more bookkeeping to do reliably. See the next paragraph.
Unfortunately, there's no room for auxiliary per-connection data to store state when using poll. There are alternatives available depending on your platform, e. g. epoll for Linux, kqueue for *BSD, and a handful of options for Windows. If you want to use poll with context data, you'd have to use a data structure that can be searched using the file descriptor or array index.
Why don't u use libevent? It totally asynchronous and non-blocking.
http://libevent.org/

Problems with C code for buffer overflow

I'm writing a small tcp echo server for testing buffer overruns on Linux. I have two slightly different versions of the server code. When an over sized buffer is sent the the first it overflows as expected in the read function causing a Segmentation Fault. For the second version of the code I added a While (1) loop around the accept, read, and write functions so that the server will not exit under normal use, however when the same buffer is sent to the second server there is no overflow and the server does not crash at all. I'm having trouble figuring out why, the code is identical short of the while loop. Any help would be very appreciated. :)
SERVER 1
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char recv[512];
bzero(recv,512);
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) exit(1);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) exit(1);
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) exit(1);
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) exit(1);
int n = read(newsockfd,recv,1024);
if (n < 0) exit(1);
write(newsockfd,recv,n);
close(newsockfd);
return 0;
}
SERVER 2
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main(int argc, char *argv[])
{
int sockfd, newsockfd, portno, clilen;
char recv[512];
bzero(recv,512);
struct sockaddr_in serv_addr, cli_addr;
if (argc < 2) exit(1);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0) exit(1);
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) exit(1);
listen(sockfd,5);
clilen = sizeof(cli_addr);
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0) continue;
int n = read(newsockfd,recv,1024);
if (n < 0) continue;
write(newsockfd,recv,n);
close(newsockfd);
}
return 0;
}
Buffer overflows cause the stack to be overwritten, in particular the return address from a function. The actual overflow itself isn't what causes the segmentation fault, it's that when you later on return from the function that had the overflow, the return address has been corrupted. (Other possible segfaults from a buffer overflow include accessing memory from overwritten pointers, or using function pointers that have been overwritten, etc).
In your example, the while loop is preventing you from ever reaching the return statement, so while your buffer is being overflowed and your return address clobbered, that return address is never used, so the segfault doesn't occur.
If you want to verify that the overflow is occurring, I would recommend either watching in a debugger, or printing out the values inside the serv_addr and cli_addr structures, which I would expect would be clobbered by your overflow.
Also if you want to see the segfault from overflow, move the recv call and its destination buffer into a separate function, then call that function from inside the while(1) loop. The segfault should occur when the function with recv in it returns.
You cannot predict what your program will do when there is a buffer overflow. The behavior depends on what happens to be after the buffer and exactly what's in the overly-long input. Those things may depend on unrelated parts of your program (what addresses things are compiled at), and possibly even things like load addresses that change from run to run.

How you pass path from client to server?

Hello i am trying to make a TCP client/server that i want these things.
The client will give the filename or the path of filename of a file.
The server will find that file and give these details:
permissions,size,owner,group of owner,date modified/created,number of words,id and priority of user and send these to client of -1 if something goes wrong.The client will print that details.I have done a lot of this things but i have a huge problem so i cant continue,my problem is that server cant recognize path of file but i tried with naming the file and communication its OK.What i am doing wrong?
Thank you in advance
CLIENT
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
void error(char *msg)
{
perror(msg);
exit(0);
}
int main(int argc, char *argv[])
{
int sockfd, portno, n;
struct sockaddr_in serv_addr;
struct hostent *server;
char buffer[1024];
if (argc < 3) {
fprintf(stderr,"usage %s hostname port\n", argv[0]);
exit(0);
}
portno = atoi(argv[2]);
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
server = gethostbyname(argv[1]);
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
printf("Please enter the filename or path of filename: ");
bzero(buffer,1024);
fgets(buffer,1024,stdin);
n = write(sockfd,buffer,strlen(buffer));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,1024);
n = read(sockfd,buffer,1024);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return 0;
SERVER
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/resource.h>
#include <sys/time.h>
void error(char *msg)
{
perror(msg);
exit(1);
}
int main(int argc, char *argv[])
{
FILE *fp;
int sockfd, newsockfd, portno, clilen,i;
char buffer[1024],filename[1024];
char * pPath;
struct sockaddr_in serv_addr, cli_addr;
int n;
int which = PRIO_PROCESS;
id_t pid;
int ret;
if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
if (bind(sockfd, (struct sockaddr *) &serv_addr,
sizeof(serv_addr)) < 0)
error("ERROR on binding");
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd,
(struct sockaddr *) &cli_addr,
&clilen);
if (newsockfd < 0)
error("ERROR on accept");
bzero(buffer,1024);
n = read(newsockfd,buffer,1024);
if (n < 0) error("ERROR reading from socket");
printf("Here is the message: %s\n",buffer);
system("ls -al 1.txt > ls.txt");
system("wc -w 1.txt > wc.txt");
/* pPath = getenv ("PATH");
if (pPath!=NULL)
printf ("The current path is: %s\n",pPath);
system("touch path.txt");
fp=fopen("path.txt","w");
if (fp==NULL) exit(1);
fprintf(fp,pPath);
fclose(fp); */
pid = getpid();
ret = getpriority(which, pid);
printf("priority %d user id %d ret %d",which,pid,ret);
system("paste ls.txt wc.txt user.txt > info.txt");
fp=fopen("info.txt","r");
if (fp==NULL) exit(1);
for(int i=0;i<1000;i++){
fscanf(fp,"%c",&buffer[i]);
}
fclose(fp);
n = write(newsockfd,buffer,1024);
if (n < 0) error("ERROR writing to socket");
return 0;
}
}`
Thank you for the fast reply.To be specific,professor didn't ask us to make this txt files i created but i created cause i couldn't find a solution and i couldn't write everything to buffer.It should be like this:
buffer i coming with path from client
find path-file from buffer(this is where i have problem)
ls -al write to buffer(i wrote it to .txt)
wc write to buffer(i wrote it to .txt)
path write to buffer(haven't done this yet)
user info write to buffer(haven't done this yet)
buffer send to client
client prints buffer with all these info
I tried sprintf but i didn't understand exactly how you use it,but this commands looks better than mine thanks:).No is passed through buffer if i understand well.
You're probably going to need to pass the path into your system calls. Allocate a buffer (keep in mind that you should be doing checks on your buffers for security, but I understand this is probably homework) and use sprintf (http://www.cplusplus.com/reference/clibrary/cstdio/sprintf/):
char lsbuf[1024];
sprintf(lsbuf,"ls -al %s > ls.txt",buffer);
system(lsbuf);
The proper way to do things (and the way your instructor most likely intends you to do them) would be to do the work of ls, wc, etc within the code. Calling system like this leaves you open to a whole new class of security holes.
Does the path passed to the server contain a trailing '\n'? If so you should remove it (for example by placing \0 character)
In your current code, nothing is really done with the input by the clients, and the behaviour does not match your description of it.
What is this supposed to do?:
for(int i=0;i<1000;i++){
fscanf(fp,"%c",&buffer[i]);
}
fclose(fp);
This will look for each character in the input (seeing as you use 1000 here, and the buffer can be 1024 characters, you are missing the last 24 characters) and return how many times it occurs in "info.txt". Note that you will also do a search for the NUL character ('\0'). Besides these carelessnesses it doesn't really do anything.
I assume you just want to find the string in the file, and work with the line number? You need a different method of searching strings. There are some clever and less clever algorithms for that. One of the more 'brute' algorithms is:
Search for the first character
Keep some flag as 'true' as long as all next characters match the expected character
If some character violates the match, go to the next search of the first character
Note that there are more efficient algorithms than this.
I did not scrutinize your network setup, assuming it works. It would be a good idea to either split the code up into several paragraphs using some more whitespace, or put the network setup into a different function.
First, use of bzero should be avoided since that function is deprecated. Use memset instead.
The function fgets, reads until a newline or the End-of-File is reached. Since a newline is a valid character, it is added to the string and a null character is appended.
If you type in "mytext" and then enter, the buffer will have "mytext\n\0".
Based on the current code, you are not even using the buffer from the client so it obvious it isn't working (not that it will due to the fgets() behavior due to an appended newline).
Sorry for replying like this but i didn't have an account,i am new to this(i didn't have problem with my projects for 4 years:P).I insert
char lsbuf[1024];
sprintf(lsbuf,"ls -al %s > ls.txt",buffer);
system(lsbuf);
and is working like a charm almost...It accepts the path and do ls but doesn't save the ls to ls.txt(creates empty file) and doesn't send it to buffer.Also i tried replaced memset and is working!!

Resources