Why do I get segmentation fault using fopen? - c

I'm writing a client-server model in C which works using fifos. I send a file name plus a name for a unique fifo for the client to recieve the data from the client and the server opens the file and writes the first line of it on the fifo. The thing is that even if the file exists i get a segmentation fault when opening it. Seems like the fopen() function works but I still get the error. If the file doesn't exist it just sends an empty string.
Here is client.c :
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define BUFSIZE 512
struct sent {
char name[BUFSIZE];
char fifo[BUFSIZE];
};
int main()
{
char name[BUFSIZE];
char recieved[BUFSIZE];
int client_server_fifo;
char cs_fifo[BUFSIZE] = "cs_fifo";
int server_client_fifo;
char sc_fifo[BUFSIZE];
sprintf(sc_fifo, "sc_fifo_%d", getpid());
struct sent *sent;
mkfifo(sc_fifo, 0777);
while(1) {
printf("Write the name of the file: ");
scanf("%s", name);
printf("1111\n");
client_server_fifo = open(cs_fifo, O_WRONLY);
printf("2222\n");
printf("%s", name);
printf("%s", cs_fifo);
sent->name = name;
sent->fifo = cs_fifo;
printf("%s", name);
printf("%s", cs_fifo);
write(client_server_fifo, sent, sizeof(*sent));
server_client_fifo = open(sc_fifo, O_RDONLY);
if (read(server_client_fifo, recieved, sizeof(recieved)) == -1) {
printf("An error ocurred.\n");
} else {
printf("First line of the file: \n%s\n", recieved);
close(client_server_fifo);
close(server_client_fifo);
}
memset(recieved, 0, sizeof(recieved));
}
return 0;
}
And here's server.c :
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#define BUFSIZE 512
struct sent {
char name[BUFSIZE];
char fifo[BUFSIZE];
};
int main()
{
int client_server_fifo;
char cs_fifo[BUFSIZE] = "cs_fifo";
int server_client_fifo;
char sc_fifo[BUFSIZE];
struct sent *sent;
char name[BUFSIZE];
char line[BUFSIZE];
FILE *file;
printf("Server running...\n");
mkfifo(cs_fifo, 0777);
while (1)
{
client_server_fifo = open(cs_fifo, O_RDONLY);
read(client_server_fifo, sent, sizeof(*sent));
strcpy(name, sent->name);
strcpy(sc_fifo, sent->fifo);
if((file = fopen(name, "r")) != NULL) {
printf("%s\n", name);
fgets(line, BUFSIZE, file);
printf("%s\n", name);
}
server_client_fifo = open(sc_fifo, O_WRONLY);
write(server_client_fifo, line, strlen(line));
memset(name, 0, sizeof(name));
memset(line, 0, sizeof(line));
close(client_server_fifo);
}
return 0;
}
Why does this happen?

The program has undefined behavior because in gthis statement
sprintf(sc_fifo, "sc_fifo_%d", getpid());
you are trying to change a string literal pointed to by the pointer sc_fifo.
char *cs_fifo = "cs_fifo";
When you declare a pointer to a string literal always declare them with the qualifier const. In this case you will get ban error at compilation time if you will tray to change a string literal.
Also you are using uninitialized pointer sent
struct sent *sent;
in this statement
read(client_server_fifo, sent, sizeof(*sent));
There are other errors. For example arrays do not have the assignment operator. So these statements in client.c
sent->name = name;
sent->fifo = cs_fifo;
are incorrect.

Related

how to print name of newly created file(s) within a directory in C?

This code scans for newly created files within a directory, however where "%s" should contain the name of the new file(s) this does not occur.
I can imagine there are unnecessary pieces of code written here, however being quite unfamiliar with C I'm simply happy it compiles at this point (and actually recognizes new files) !
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <sys/inotify.h>
int main (int argc, char *argv[])
{
char target[FILENAME_MAX];
int result;
int fd;
int wd; /* watch descriptor */
const int event_size = sizeof(struct inotify_event);
const int buf_len = 1024 * (event_size + FILENAME_MAX);
fd = inotify_init();
if (fd < 0) {
perror("inotify_init");
}
wd = inotify_add_watch(fd, "/home/joe/Documents", IN_CREATE);
while (1) {
char buff[buf_len];
int no_of_events, count = 0;
no_of_events = read (fd, buff, buf_len);
while (count < no_of_events) {
struct inotify_event *event = (struct inotify_event *)&buff[count];
if (event->len) {
if (event->mask & IN_CREATE)
if(!(event->mask & IN_ISDIR)) {
printf("The file %s has been created\n", target);
fflush(stdout);
}
}
count += event_size + event->len;
}
}
return 0;
}
You're printing out target when you get an event, however target is never modified.
The name of the created file is stored in event->name. That's what you want to print.
printf("The file %s has been created\n", event->name);

Getting segmentation fault in C on Ubuntu when trying to run function from .so library

I am using libwireshark.so, libwsutil.so and libwiretap.so in order to make program which decodes packets like Wireshark in C on Ubuntu Linux.
I am try to run function named epan_init() from libwireshark.so but I get the following run-time error:
Enter file name: 1.pcap
Enter print type(0-XML, 1-TEXT): 1
Init function start
Segmentaion fault (core dumped)
Process returned 139 (0x8B) execution time : 2.882 s
Press ENTER to continue.
SOURCE CODE:
#define HAVE_STDARG_H 1
#define WS_MSVC_NORETURN
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
#include <string.h>
#include <wireshark/epan/epan.h>
#include <wireshark/epan/print.h>
#include <wireshark/epan/timestamp.h>
#include <wireshark/epan/prefs.h>
#include <wireshark/epan/column.h>
#include <wireshark/epan/epan-int.h>
#include <wireshark/wsutil/privileges.h>
#include <wireshark/epan/epan_dissect.h>
#include <wireshark/epan/proto.h>
#include <wireshark/epan/ftypes/ftypes.h>
#include <wireshark/epan/asm_utils.h>
///Prototypes
void getString(char *msg, char **input);
int init(char *filename);
///Print type of packets
typedef enum {PRINT_XML, PRINT_TEXT} print_type_t;
capture_file cfile;
int main()
{
///Variables
int err;
char *filename = NULL;
print_type_t print_type = PRINT_XML;
getString("Enter file name: ", &filename);
printf("Enter print type(0-XML, 1-TEXT): ");
scanf("%d",&print_type);
err = init(filename);
if(err)
{
printf("Main function(): Error init");
return 1;
}
printf("\n\n\n%s\n\n\n",cfile.filename);
//printf("Hello World");
return 0;
}
///Get input from user
void getString(char *msg, char **input)
{
char buffer[100];
printf("%s", msg);
fgets(buffer, sizeof(buffer), stdin);
*input = calloc(sizeof(char), strlen(buffer) + 1);
strncpy(*input, buffer, strlen(buffer));
}
///
int init(char *filename)
{
printf("Init function start\n");
int err = 0;
gchar *err_info = NULL;
e_prefs *prefs_p;
/// Called when the program starts, to enable security features and save whatever credential information we’ll need later.
init_process_policies();
printf("Init proccesss politices done");
/// Init the whole epan module. Must be called only once in a program. Returns TRUE on success, FALSE on failure.
epan_init(register_all_protocols, register_all_protocol_handoffs, NULL, NULL);
//printf("epan init done");
cap_file_init(&cfile);
cfile.filename = filename;
return 0;
}
void cap_file_init(capture_file *cf)
{
/* Initialize the capture file struct */
memset(cf, 0, sizeof(capture_file));
cf->snap = WTAP_MAX_PACKET_SIZE;
}

Named piped error

Sorry for the poor title, i didnt' know how to explain this simply.
I have 2 programs : a server and a client.
Server make a named pipe and waits to read something. Client connects and send a message to the pipe. Server checks a part of the message to get the "type" of the message (in this case, type is "HELO") reading char 4 to 8 of the sent string. If i send "HELO", server prints "Type : HELO" as expected.
But if i send a message with something else, it doesn't print "No match" as expected : it just does nothing.
Here is the code :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#define BUF_SIZE 256
char * getType(char * message){
char* type = malloc(sizeof(char)*5);
memcpy(type,&message[4],4);
type[4] = '\0';
return type;
}
int main(int argc, char* argv[]){
mkfifo("tchatserv", 0666);
int fd = open("tchatserv", O_RDONLY);
char buf[BUF_SIZE];
int val;
while(1){
val = read(fd, buf , BUF_SIZE );
if(val >0){
char * type = getType(buf);
if(strcmp("HELO",type) == 0){
printf("Type: %s\n", type);
}
else{
printf("no match");
}
}
}
}
Here is client :
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include <fcntl.h>
char * makeInt(int val){
char* res = malloc(sizeof(char)*5);
char l [5] = "";
sprintf(l,"%d",val);
if(val < 10){
strcat(res,"000");
strcat(res,l);
}
else if(val < 100){
strcat(res,"00");
strcat(res,l);
}
else if(val < 1000){
strcat(res,"0");
strcat(res,l);
}
else if( val < 10000){
strcat(res,l);
}
return res;
}
char * makeString(char * ch, int final){
int t = strlen(ch);
if(final == 1){
t = t+4;
}
char * chaine = makeInt(t);
strcat(chaine,ch);
return chaine;
}
void connection(){
printf("Pseudo:\n");
char * pseudo = malloc(sizeof(char)*30);
pseudo[0] = '\0';
scanf("%s", pseudo);
printf("Tube:\n");
char * tube = malloc(sizeof(char)*30);
tube[0] = '\0';
scanf("%s", tube);
char * message = malloc(sizeof(char)*100);
char * type = "HELO";
message[0] = '\0';
strcat(message,type);
pseudo = makeString(pseudo,0);
strcat(message,pseudo);
tube = makeString(tube,0);
strcat(message,tube);
message = makeString(message,1);
printf("%s",message);
int fd = open("tchatserv", O_WRONLY);
write(fd,message,256);
}
int main(int argc, char* argv[]){
connection();
return 0;
}
EDIT: When i try to send something else than HELO it doesn't print "no match" but then i send HELO and it prints : "no match Type: HELO", like if the first "no match" got stuck in the pipe instead of getting printed immediately, i don't understand why.
When i try to send something else than HELO it doesn't print "no match" but then i send HELO and it prints : "no match Type: HELO", like if the first "no match" got stuck in the pipe instead of getting printed immediately, i don't understand why.
The no match indeed got stuck in a way, though not in the pipe, but rather in the server's buffer of the standard output stream, which is presumably line buffered, i. e., characters are transmitted (printed) when a new-line is encountered. To cure this, just change the printf("no match") to printf("no match\n") or puts("no match").

File sent over TCP is created with type: application/octet-stream

I'm trying to transfer a file from a server to a client using TCP protocol.
I manage to send the whole syze of the file, but when the client creates the file, it cant be open. In this case, im sending an jpg file.
heres the code for server.c:
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#define PORT 59000
int main(int argc,char *argv[]) {
int port, fd, newfd, n, nw, addrlen;
int port_was_given = 0;
char buffer[128], *ptr, *topic, *data;
size_t result;
struct hostent *h;
struct sockaddr_in addr;
FILE *send;
if((fd=socket(AF_INET,SOCK_STREAM,0))==-1)exit(1); //error
memset((void*)&addr,(int)'\0',sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_addr.s_addr=htonl(INADDR_ANY);
if (argc == 3) {
port = atoi(argv[2]);
port_was_given = 1;
}
if(port_was_given == 1)
addr.sin_port=htons((u_short)port);
else
addr.sin_port=htons((u_short)PORT);
if(bind(fd,(struct sockaddr*)&addr,sizeof(addr))==-1)exit(1); //error
if(listen(fd,5)==-1)exit(1); //error
while(1) {
addrlen=sizeof(addr);
if((newfd=accept(fd,(struct sockaddr*)&addr,&addrlen))==-1)exit(1); //erro
h=gethostbyaddr((char*)&addr.sin_addr,sizeof(struct in_addr),AF_INET);
while((n=read(newfd,buffer,128))!=0) {
if(n==-1)exit(1);
topic = strtok(buffer," ");
topic = strtok(NULL," ");
if (strcmp(topic, "Nacional\n")==0) {
send = fopen("flag","r");
fseek(send, 0L, SEEK_END); //vai ate ao fim do ficheiro
int sz = ftell(send); //size of file
fseek(send,0L,SEEK_SET);
//rewind(send);
data = (char*)malloc(sizeof(char)*sz);
result = fread(data,1,sz,send);
//fseek(send,0L,SEEK_SET);
fclose(send);
char ptr2[300] = "REP ok ";
char *ptrInt; //for s -> int
sprintf(ptrInt, "%d", sz);
strcat(ptr2, ptrInt);
strcat(ptr2, " ");
strcat(ptr2, data);
strcat(ptr2, "\n");
while(n>0) {
nw=write(newfd,ptr2,n); //write n bytes on each cycle
}
}
}
close(newfd);
}
close(fd);
exit(0);
}
Ok so the logic is: client requests a type of content, in this case the content is "Nacional", so the server has to send the "flag.jpg" to the client.
The answer of the server has the following type:
REP status size data
In which status can be "ok" or "nok". If "nok" then the file is not sent.
size is the size of the data.
data is data of the file itself.
Now the client.c:
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <arpa/inet.h>
#define PORT 58000
#define NG 10
int main (int argc,char *argv[])
{
/** ... variables declarations and other stuff ... */
fdtcp=socket(AF_INET,SOCK_STREAM,0);
if (fdtcp==-1) exit(1); // Erro
inet_aton(ip, &address);
if (strcmp(lsname, "localhost")==0)
newHost = gethostbyname("localhost");
else
newHost = gethostbyaddr((const void *)&address,sizeof ip,AF_INET);
newPort = atoi(newport);
memset((void*)&addrtcp,(int)'\0',sizeof(addrtcp));
addrtcp.sin_family=AF_INET;
addrtcp.sin_addr.s_addr=((struct in_addr *)(newHost->h_addr_list[0]))->s_addr;
addrtcp.sin_port=htons((u_short)newPort);
k = connect(fdtcp,(struct sockaddr*)&addrtcp,sizeof(addrtcp));
if (k==-1) exit(1); // Erro
// REQ Tn (Conteudo Solicitado)
ptr = strcat(reqdata, tn);
ptr = strcat(reqdata, "\n");
// Envia-se o Comando REQ
nreqleft = 25;
while(nreqleft>0) {
kwrite=write(fdtcp,ptr,nreqleft);
if (kwrite<=0) exit(1); // Erro
nreqleft -= kwrite;
ptr += kwrite;
}
// Recebe-se o Comando REP
nreqleft = 128;
ptr = &buffertcp[0];
kread=read(fdtcp,ptr,nreqleft);
if (kread==-1) exit(1); // Erro
cmd = strtok(buffertcp, " "); // REP
cmd = strtok(NULL, " "); // Status
if(strcmp(cmd,"ok")) {
printf("ERR\n");
exit(1); // Erro
}
cmd = strtok(NULL, " "); // Size
size = atoi(cmd);
// Recebem-se os Dados do Conteúdo Desejado
nreqleft = size;
char data[size];
ptr = &data[0];
while(nreqleft>0) {
kread=read(fdtcp,ptr,nreqleft);
if (kread==-1) exit(1); // Erro
nreqleft -= kread;
ptr += kread;
}
file = fopen("file","w");
fwrite(data, 1, size, file);
fclose(file);
close(fdtcp);
// --------------------------------------------------- //
exit(0);
}
The "other stuff" part is just variables declarations and a UDP connection with another server which has nothing to do with this part, so I'm 100% sure it won't affect this part. In fact, on client.c, if I place an printf of the message received from the server, it will show "REP ok 31800 ?????" which ??? I assume would be the data of the file.
The problem is that the "file" created can't be open. Help?
One problem is that 31800 is much larger than 300, and so when you append the data to your ptr2 array in the server, you have buffer overrun. You can correct that by not sending the data with a separate write() call after sending your "header" in ptr2. Your write() loop looks like it will loop forever, but I am guessing you are not showing all of your code.
In the receiver, I don't see any attempt to parse the header to separate the header from the data. Since you read in up to 128 bytes, that read may have received both the header and some data of the file, and you make no attempt to detect and save that part of the file.
When debugging file transfer applications, I would start with textual files so that you can visually see the resulting file, and run a simple diff on the file you saved with the actual file to see if there are differences.

Open function in POSIX C not working

I'm trying to get my open function to work with this program, it is reading the input correctly, as I can see if I printf the file name after I type it in, but my open function must be wrong, I can't seem to figure out what is wrong with it and it keeps returning -1 and exiting. I am trying to just open a file called tester.txt and I'm using a virtual machine running ubuntu. Any help is appreciated,thanks everyone.
#include <stdio.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>
int main(){
int bytes_read = 1;
int nbytes = 32;
char buffer[32];
char s[] = "name";
printf("Welcome to File Copy by %s!\n", s);
char *inputFile = NULL;
puts("Enter the name of the source file: ");
bytes_read = getline(&inputFile, &nbytes, stdin);
//if fail exit
int inputOpen = open("inputFile", O_RDONLY);
//if fail exit
if (inputOpen == -1){
printf("file not found.\n");
return -1;
}
return 0;
}
No matter what is entered as the name of the file, you try to open a file called "inputFile". You need to add code to extract the filename from the line entered.
This would be one way:
char *eol;
bytes_read = getline(&inputFile, &nbytes, stdin);
eol = strchr(inputFile, '\n');
if (eol != NULL) // remove end of line
*eol = 0;
int inputOpen = open(inputFile, O_RDONLY);

Resources