Why does fread() not work for files with html content? - html

I tried to read some files with the following code:
Main:
#define RESPONSE_MAX_LENGTH (1024 * 1024) // Should be 1MB
char file_content[RESPONSE_MAX_LEGNTH];
memset(&file_content, 0, RESPONSE_MAX_LEGNTH);
request_get_file("/User/...", file_content);
Function Declaration:
int request_get_file(char* requested_file_path, char* buf) {
int file_size = 0;
FILE* fp = NULL;
if ((fp = fopen(requested_file_path, "r+")) == NULL) {
return errno;
}
fseek(fp, 0L, SEEK_END);
file_size = (int)ftell(fp);
rewind(fp);
errno = 0;
if (fread(buf, 1, file_size, fp) == 0) {
if (!feof(fp)) {
if (ferror(fp)) {
printf("An error occured while reading the requested file. File size: %d\n", file_size);
perror("fread()");
return errno;
}
}
}
fclose(fp);
}
I am able to read .txt files, but when I open a html file, I get an error saying:
fread(): Bad address (Created with perror("fread"))
errno = 14
For some reason, this error only occurs for some specific documents.
Solution:
I just realized that the problem seems to be related to a specific file. After renaming my test.html to test.txt and trying to open this one, the error is still there. Could that have to do with the file content?
=> Yes, as the buffer I was writing the data was way too small.
How can I fix this issue?

The problem was that the buffer I was writing to was way too small to hold all the data read by fread().
My updated code:
Main:
char* buf = NULL;
request_get_file("/User/...", &buf);
Function Declaration:
int request_get_file(char* requested_file_path, char** buf) {
int file_size = 0;
FILE* fp = NULL;
if ((fp = fopen(requested_file_path, "r+")) == NULL) {
return errno;
}
fseek(fp, 0L, SEEK_END);
file_size = (int)ftell(fp);
rewind(fp);
errno = 0;
if ((*buf = calloc(file_size + 1, sizeof(char))) == NULL) {
perror("calloc()");
return errno;
}
if (fread(*buf, 1, file_size, fp) == 0) {
if (!feof(fp)) {
if (ferror(fp)) {
printf("An error occured while reading the requested file. File size: %d\n", file_size);
perror("fread()");
return errno;
}
}
}
fclose(fp);
}

Related

How to write multiple ssid's and passwords to the same json file ESP32

I am currently testing a piece of code using arduinojson6. My goal is to store multiple ssid's and passwords to the esp32 SPIFF.
The uneddited question contained a piece of code that would append to the file rather than reading doc, deleting /SSID.json, adding to doc serialization and saving the file again like I have now, is also not the solution.
the desired json file would be:
{"information":[{ "SSID":"variable blaat1", "PASS1":"variable Abc1", "NUMBER": "1" },{ "SSID":"variable blaat2", "PASS2":"variable Abc2", "NUMBER": "2" },{ "SSID":"variable blaat3", "PASS3":"variable Abc3", "NUMBER": "3" },{ "SSID":"variable blaat4", "PASS4":"variable Abc4", "NUMBER": "4" },{ "SSID":"variable blaat5", "PASS5":"variable Abc5", "NUMBER": "5" }]}
Instead, when more then 1 value is serialized and appended it will read like this:
{
"information": {},
"test": [
"mooiman\n",
"mooiweer\n"
],
"number": [
1,
2
]
}
Maybe some of you know how to serialize it properly.
The code I test with:
#include <Arduino.h>
#include <WiFi.h>
//#include <time.h>
//#include <ESP32Ping.h>
#include "FS.h"
#include "SPIFFS.h"
//#include <HTTPClient.h>
#include <ArduinoJson.h>
int numberofInputs = 1;
String ssid = "YourSSID";
String passwords = "YourPassword";
String readString;
char FileReadBuff[1024];
DynamicJsonDocument doc(1024);
void readFile(fs::FS &fs, const char * path){
if (SPIFFS.exists("/SSID.json") == false)
{
File file = SPIFFS.open("/SSID.json", FILE_WRITE);
if (!file) {
Serial.println("There was an error opening the file for writing");
return;
}
if (file.print("SSID")) {
Serial.println("File was written");
} else {
Serial.println("File write failed");
}
file.close();
}
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path);
if(!file || file.isDirectory()){
Serial.println("- failed to open file for reading");
return;
}
uint16_t i = 0;
Serial.println("reading");
while (file.available()) {
FileReadBuff[i] = file.read();
i++;
}
file.close();
}
void CleanFile(fs::FS &fs, const char * path, const char * message) {
for( int i = 0; i < sizeof(FileReadBuff); ++i ){
FileReadBuff[i] = (char)0;
}
File file = SPIFFS.open(path, FILE_WRITE);
if (fs.remove(path)) {
Serial.println("\r\n- file cleaned");
} else {
Serial.println("\r\n- Cleaning failed");
}
file.print(path);
}
void appendFile(fs::FS &fs, const char * path, const char * message){
if (SPIFFS.exists("/SSID.json") == false)
{
File file = SPIFFS.open("/SSID.json", FILE_WRITE);
if (!file) {
Serial.println("There was an error opening the file for writing");
return;
}
if (file.print("SSID")) {
Serial.println("File was written");
} else {
Serial.println("File write failed");
}
file.close();
}
Serial.printf("Appending to file: %s\r\n", path);
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("- failed to open file for appending");
return;
}
if(file.println(message)){
Serial.println("- message appended");
} else {
Serial.println("- append failed");
}
file.close();
}
void Deserialization(){
for( int i = 0; i < sizeof(FileReadBuff); ++i ){
FileReadBuff[i] = (char)0;
}
readFile(SPIFFS, "/SSID.json"); //read everything from ssid.json file
const char * JsonFF = FileReadBuff; // put everything in to const char
Serial.print("Json From File:"); Serial.println(JsonFF);
DeserializationError error = deserializeJson(doc, JsonFF);
if(error){
Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); // if not legit print error
}
if(!error){
String information = doc["information"];
Serial.println(information);
information = "";
}
}
void testjson(){
readString = "";
while(readString.length() < 1) {
while (Serial.available()) {
delay(10); //small delay to allow input buffer to fill
if (Serial.available() > 0) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
break;
} //breaks out of capture loop to print readstring
readString += c;
} //makes the string readString
}
if (readString.length() > 0) {
Serial.println(readString); //prints string to serial port out
if (readString.indexOf("READ") >= 0) {
Serial.println("reading file");
readFile(SPIFFS, "/SSID.json");
Serial.println(FileReadBuff);
for( int i = 0; i < sizeof(FileReadBuff); ++i ){
FileReadBuff[i] = (char)0;
}
}
if (readString.indexOf("DES") >= 0) { //DEZ deserialize will result in an error because json file is currently not valid
Serial.println("reading deserialized json");
Deserialization();
}
if (readString.indexOf("CLEAN") >= 0) { //CLEAN cleans the SSID.json file
Serial.println("reading deserialized json");
CleanFile(SPIFFS, "/SSID.json", "");
}
if (readString.indexOf("WRANDOM") >= 0){ //WRANDOM writes a random string to the SSID.json file
readString = "";
Serial.println("Going to write the following input:"); //waiting for user input
while(readString.length() < 1) {
while (Serial.available()) {
delay(10); //small delay to allow input buffer to fill
if (Serial.available() > 0) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
break;
} //breaks out of capture loop to print readstring
readString += c;
} //makes the string readString
}
if (readString.length() > 0) {
Serial.println(readString); //prints string to serial port out
`here is the part we're talking about`
CleanFile(SPIFFS, "/SSID.json", "");
JsonObject information = doc.createNestedObject("information");
String SerializedJson = "";
doc["test"].add(readString);
doc["number"].add(numberofInputs);
serializeJsonPretty(doc, SerializedJson);
appendFile(SPIFFS, "/SSID.json", SerializedJson.c_str());
SerializedJson = "";
numberofInputs ++;
return;
}
}
}
}
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
if (!SPIFFS.begin(true)) {
Serial.println("An Error has occurred while mounting SPIFFS");
return;
}
if (SPIFFS.exists("/SSID.json") == false)
{
File file = SPIFFS.open("/SSID.json", FILE_WRITE);
if (!file) {
Serial.println("There was an error opening the file for writing");
return;
}
if (file.print("SSID")) {
Serial.println("File was written");
} else {
Serial.println("File write failed");
}
file.close();
}
WiFi.mode(WIFI_MODE_STA);
WiFi.begin(ssid.c_str(), passwords.c_str());
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.print(".");
}
Serial.println("Connected");
}
void loop() {
// put your main code here, to run repeatedly:
readString = ""; //clears variable for new input
Serial.println("Ready for new input: ");
testjson();
}
So when you serial write WRANDOM you'll get promted to put in something.
When that is recieved it will store that in json.
Do that another time.
Next when you serial write READ it will show you the saved /SSID.json.
Thanks in advance.
Note that the DynamicJsonDocument startsof empty.
PS. I know littlefs is the new spiff but lets first try to make this work (or I need to make sepperate files for every ssid+password)
Here is a test sketch you can implement to your project.
I did not had the time to write more detailed sketch than this.
Let me know if you have any question about this
#include <Arduino.h>
#include "FS.h"
#include <LittleFS.h>
#include <ArduinoJson.h>
#define DOC_SIZE 5000
/*
Example JSON :
{
"information":[
{ "SSID":"variable blaat1", "PASS1":"variable Abc1", "NUMBER": "1" },
{ "SSID":"variable blaat2", "PASS2":"variable Abc2", "NUMBER": "2" },
{ "SSID":"variable blaat3", "PASS3":"variable Abc3", "NUMBER": "3" },
{ "SSID":"variable blaat4", "PASS4":"variable Abc4", "NUMBER": "4" },
{ "SSID":"variable blaat5", "PASS5":"variable Abc5", "NUMBER": "5" }
]
}
*/
/*
When you create a JSON array, you don't need to push the index of the object, since you can later
ask for the array size, therefor you know the indexes. Also you don't need to separate the passwords
like PASS1 or PASS2 since every cred is a separate object.
*/
void addCredentials( const char* SSID, const char* PW ){
// Create a static JSON document.
StaticJsonDocument fileDoc(DOC_SIZE);
// Open the file containing the credentials
File credFile = LittleFS.open(FILE_PATH,FILE_READ);
// Check if it opened.
if( !credFile ){ Serial.println("Failed to open file"); return; }
// Deserialize the file
DeserializationError error = deserializeJson(fileDoc, credFile );
// Check if the deserialization has any errors.
if( error ){ Serial.printf("Error on deserialization: %s\n", error.c_str() );
// Get the info array from the JSON.
JsonArray infoArr = fileDoc["information"].as<JsonArray>();
// Create a new object inside the array.
JsonObject newCred = infoArr.createNestedObject();
// Add credentials to the object.
newCred["SSID"] = SSID;
newCred["PASS"] = PW;
// Serialize everythig back to the file.
serializeJson(fileDoc, credFile);
// Close the file.
credFile.close();
}
// Open the file and put the pretty json into the serial directly.
void printFileContent(){
File credFile = LittleFS.open(FILE_PATH,FILE_READ);
if( !credFile ){ Serial.println("Failed to open file"); return; }
serializeJsonPretty(Serial, credFile);
credFile.close();
}
void clearFile(){
if( !LittleFS.exists(FILE_PATH) ){ Serial.println("Credentials file does not exists yet!"); return; }
File credFile = LittleFS.open(FILE_PATH,FILE_READ);
credFile.remove();
}
void getUserInput(){
if( !Serial.available() ){ return; }
// Get the credentials or whatever from the serial
// and call the **addCredentials( const char* SSID, const char* PW );** function.
}
void setup() {
Serial.begin(115200);
}
void loop() {
getUserInput();
}
I got it figured out with help from Dr.Random. It wasn't the full answer but it helped getting the json format and apend to that file correctly. The following code is a working example.
#include <Arduino.h>
#include <WiFi.h>
#include "FS.h"
#include "LittleFS.h"
#include <ArduinoJson.h>
#define FORMAT_LITTLEFS_IF_FAILED true
#define DOC_SIZE 5000
#define FILE_PATH "/SSID.json"
String ssid = "yourssid";
String passwords = "yourpass";
String readString;
char FileReadBuff[1024];
void readFile(fs::FS &fs, const char * path){
Serial.printf("Reading file: %s\r\n", path);
File file = fs.open(path);
if(!file || file.isDirectory()){
Serial.println("- failed to open file for reading");
return;
}
Serial.println("- read from file:");
while(file.available()){
Serial.write(file.read());
}
file.close();
}
void Showone(int wichone){
DynamicJsonDocument doc(DOC_SIZE);
File credFile = LittleFS.open(FILE_PATH, FILE_READ);// open file for reading
DeserializationError error = deserializeJson(doc, credFile);// deserialize json
if( !credFile ){ Serial.println("Failed to open file"); return; }// if file doesn't exist, return
const char* SSID = doc[wichone]["SSID"]; //
const char* PASS = doc[wichone]["PASS"]; //
Serial.print("SSID and PASS = "); Serial.print(SSID); Serial.print(PASS); Serial.print(" "); Serial.println(" ");
credFile.close();
}
void addCredentials(const char * input){
DynamicJsonDocument doc(DOC_SIZE);// create json doc
String Serialized; // create string to store serialized json
File credFile = LittleFS.open(FILE_PATH, FILE_READ);// open file for reading
if( !credFile ){ Serial.println("Failed to open file"); return; }// if file doesn't exist, return
DeserializationError error = deserializeJson(doc, credFile);// deserialize json
if( error ){ Serial.printf("Error on deserialization: %s\n", error.c_str() );} //error when spiff is empty or not formatted correctly
JsonArray inforArr = doc["information"].as<JsonArray>();// get array from json
JsonObject newCred = doc.createNestedObject();// create new object in json
newCred["SSID"] = input;
newCred["PASS"] = input;
serializeJsonPretty(doc, Serialized);
Serial.print("input = "); Serial.println(input);
Serial.print("Serialized: "); Serial.println(Serialized);
File credFile2 = LittleFS.open(FILE_PATH, FILE_WRITE);// open file for writing
credFile2.print(Serialized);
credFile2.close();
credFile.close();
Serialized = "";
}
void testjson(){
readString = "";
while(readString.length() < 1) {
while (Serial.available()) {
delay(10); //small delay to allow input buffer to fill
if (Serial.available() > 0) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
break;
} //breaks out of capture loop to print readstring
readString += c;
} //makes the string readString
}
if (readString.length() > 0) {
Serial.println(readString); //prints string to serial port out
if (readString.indexOf("READ") >= 0) {
Serial.println("reading file");
readFile(LittleFS, "/SSID.json");
Serial.println(FileReadBuff);
for( int i = 0; i < sizeof(FileReadBuff); ++i ){
FileReadBuff[i] = (char)0;
}
}
if (readString.indexOf("SHOW") >= 0) {
readString = "";
Serial.println("Showing the following input(number): "); //waiting for user input
while(readString.length() < 1) {
while (Serial.available()) {
delay(10); //small delay to allow input buffer to fill
if (Serial.available() > 0) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
break;
} //breaks out of capture loop to print readstring
readString += c;
} //makes the string readString
}
if (readString.length() > 0) {
Serial.println(readString); //prints string to serial port out
Showone(readString.toInt());
}
}
}
if (readString.indexOf("CLEAN") >= 0) { //CLEAN cleans the SSID.json file
Serial.println("reading deserialized json");
File credFile = LittleFS.open(FILE_PATH, FILE_WRITE);// open file for writing
credFile.print("");
credFile.close();
}
if (readString.indexOf("WRANDOM") >= 0){ //WRANDOM writes a random string to the SSID.json file
readString = "";
Serial.println("Going to write the following input:"); //waiting for user input
while(readString.length() < 1) {
while (Serial.available()) {
delay(10); //small delay to allow input buffer to fill
if (Serial.available() > 0) {
char c = Serial.read(); //gets one byte from serial buffer
if (c == ',') {
break;
} //breaks out of capture loop to print readstring
readString += c;
} //makes the string readString
}
if (readString.length() > 0) {
Serial.println(readString); //prints string to serial port out
addCredentials(readString.c_str());
}
}
}
}
}
}
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
if(!LittleFS.begin(FORMAT_LITTLEFS_IF_FAILED)){
Serial.println("LittleFS Mount Failed");
return;
}
//if /ssid.json doesn't exist, create it littlefs
if(!LittleFS.exists(FILE_PATH)){
Serial.println("File doesn't exist, creating it");
File credFile = LittleFS.open(FILE_PATH, FILE_WRITE);
if(!credFile){
Serial.println("Failed to create file");
return;
}
credFile.close();
}
WiFi.mode(WIFI_MODE_STA);
WiFi.begin(ssid.c_str(), passwords.c_str());
while (WiFi.status() != WL_CONNECTED) { //Check for the connection
delay(1000);
Serial.print(".");
}
Serial.println("Connected");
}
void loop() {
// put your main code here, to run repeatedly:
readString = ""; //clears variable for new input
Serial.println("Ready for new input: ");
testjson();
}
Any improvements are still desirable.

Understanding how to use CGI programming with C and HTML

I'm attempting to use a local server made in C with an HTML page run on this server that will be able to interact with a program i made to be able to run bash commands which works perfectly outside of the html page but needs to be able to receive input from the user via text box on the web page, display the command entered as well as the output on the html page. Right now when i click the submit button on the html page it goes to localhost:PORT/pexec.cgi but shows absolutely no display at all, just white space. What am i doing wrong and how can i get this to work so that it will correctly display output?
WCServer.c
#include <sys/socket.h> // socket definitions
#include <sys/types.h> // socket types
#include <arpa/inet.h> // inet (3) funtions
#include <unistd.h> // misc. UNIX functions
#include <signal.h> // signal handling
#include <stdlib.h> // standard library
#include <stdio.h> // input/output library
#include <string.h> // string library
#include <errno.h> // error number library
#include <fcntl.h> // for O_* constants
#include <sys/mman.h> // mmap library
#include <sys/types.h> // various type definitions
#include <sys/stat.h> // more constants
// global constants
#define PORT 3838 // port to connect on
#define LISTENQ 10 // number of connections
int list_s; // listening socket
// structure to hold the return code and the filepath to serve to client.
typedef struct {
int returncode;
char *filename;
} httpRequest;
// Structure to hold variables that will be placed in shared memory
typedef struct {
pthread_mutex_t mutexlock;
int totalbytes;
} sharedVariables;
// headers to send to clients
char *header200 = "HTTP/1.0 200 OK\nServer: CS241Serv v0.1\nContent-Type: text/html\n\n";
char *header400 = "HTTP/1.0 400 Bad Request\nServer: CS241Serv v0.1\nContent-Type: text/html\n\n";
char *header404 = "HTTP/1.0 404 Not Found\nServer: CS241Serv v0.1\nContent-Type: text/html\n\n";
// get a message from the socket until a blank line is recieved
char *getMessage(int fd) {
// A file stream
FILE *sstream;
// Try to open the socket to the file stream and handle any failures
if( (sstream = fdopen(fd, "r")) == NULL)
{
fprintf(stderr, "Error opening file descriptor in getMessage()\n");
exit(EXIT_FAILURE);
}
// Size variable for passing to getline
size_t size = 1;
char *block;
// Allocate some memory for block and check it went ok
if( (block = malloc(sizeof(char) * size)) == NULL )
{
fprintf(stderr, "Error allocating memory to block in getMessage\n");
exit(EXIT_FAILURE);
}
// Set block to null
*block = '\0';
// Allocate some memory for tmp and check it went ok
char *tmp;
if( (tmp = malloc(sizeof(char) * size)) == NULL )
{
fprintf(stderr, "Error allocating memory to tmp in getMessage\n");
exit(EXIT_FAILURE);
}
// Set tmp to null
*tmp = '\0';
// Int to keep track of what getline returns
int end;
// Int to help use resize block
int oldsize = 1;
// While getline is still getting data
while( (end = getline( &tmp, &size, sstream)) > 0)
{
// If the line its read is a caridge return and a new line were at the end of the header so break
if( strcmp(tmp, "\r\n") == 0)
{
break;
}
// Resize block
block = realloc(block, size+oldsize);
// Set the value of oldsize to the current size of block
oldsize += size;
// Append the latest line we got to block
strcat(block, tmp);
}
// Free tmp a we no longer need it
free(tmp);
// Return the header
return block;
}
// send a message to a socket file descripter
int sendMessage(int fd, char *msg) {
return write(fd, msg, strlen(msg));
}
// Extracts the filename needed from a GET request and adds public_html to the front of it
char * getFileName(char* msg)
{
// Variable to store the filename in
char * file;
// Allocate some memory for the filename and check it went OK
if( (file = malloc(sizeof(char) * strlen(msg))) == NULL)
{
fprintf(stderr, "Error allocating memory to file in getFileName()\n");
exit(EXIT_FAILURE);
}
// Get the filename from the header
sscanf(msg, "GET %s HTTP/1.1", file);
// Allocate some memory not in read only space to store "public_html"
char *base;
if( (base = malloc(sizeof(char) * (strlen(file) + 18))) == NULL)
{
fprintf(stderr, "Error allocating memory to base in getFileName()\n");
exit(EXIT_FAILURE);
}
char* ph = "public_html";
// Copy public_html to the non read only memory
strcpy(base, ph);
// Append the filename after public_html
strcat(base, file);
// Free file as we now have the file name in base
free(file);
// Return public_html/filetheywant.html
return base;
}
// parse a HTTP request and return an object with return code and filename
httpRequest parseRequest(char *msg){
httpRequest ret;
// A variable to store the name of the file they want
char* filename;
// Allocate some memory to filename and check it goes OK
if( (filename = malloc(sizeof(char) * strlen(msg))) == NULL)
{
fprintf(stderr, "Error allocating memory to filename in parseRequest()\n");
exit(EXIT_FAILURE);
}
// Find out what page they want
filename = getFileName(msg);
// Check if its a directory traversal attack
char *badstring = "..";
char *test = strstr(filename, badstring);
// Check if they asked for / and give them input.html
int test2 = strcmp(filename, "public_html/");
// Check if the page they want exists
FILE *exists = fopen(filename, "r" );
// If the badstring is found in the filename
if( test != NULL )
{
// Return a 400 header and 400.html
ret.returncode = 400;
ret.filename = "400.html";
}
// If they asked for / return input.html
else if(test2 == 0)
{
ret.returncode = 200;
ret.filename = "public_html/input.html";
}
// If they asked for a specific page and it exists because we opened it sucessfully return it
else if( exists != NULL )
{
ret.returncode = 200;
ret.filename = filename;
// Close the file stream
fclose(exists);
}
// If we get here the file they want doesn't exist so return a 404
else
{
ret.returncode = 404;
ret.filename = "404.html";
}
// Return the structure containing the details
return ret;
}
// print a file out to a socket file descriptor
int printFile(int fd, char *filename) {
/* Open the file filename and echo the contents from it to the file descriptor fd */
// Attempt to open the file
FILE *read;
if( (read = fopen(filename, "r")) == NULL)
{
fprintf(stderr, "Error opening file in printFile()\n");
exit(EXIT_FAILURE);
}
// Get the size of this file for printing out later on
int totalsize;
struct stat st;
stat(filename, &st);
totalsize = st.st_size;
// Variable for getline to write the size of the line its currently printing to
size_t size = 1;
// Get some space to store each line of the file in temporarily
char *temp;
if( (temp = malloc(sizeof(char) * size)) == NULL )
{
fprintf(stderr, "Error allocating memory to temp in printFile()\n");
exit(EXIT_FAILURE);
}
// Int to keep track of what getline returns
int end;
// While getline is still getting data
while( (end = getline( &temp, &size, read)) > 0)
{
sendMessage(fd, temp);
}
// Final new line
sendMessage(fd, "\n");
// Free temp as we no longer need it
free(temp);
// Return how big the file we sent out was
return totalsize;
}
// clean up listening socket on ctrl-c
void cleanup(int sig) {
printf("Cleaning up connections and exiting.\n");
// try to close the listening socket
if (close(list_s) < 0) {
fprintf(stderr, "Error calling close()\n");
exit(EXIT_FAILURE);
}
// Close the shared memory we used
shm_unlink("/sharedmem");
// exit with success
exit(EXIT_SUCCESS);
}
int printHeader(int fd, int returncode)
{
// Print the header based on the return code
switch (returncode)
{
case 200:
sendMessage(fd, header200);
return strlen(header200);
break;
case 400:
sendMessage(fd, header400);
return strlen(header400);
break;
case 404:
sendMessage(fd, header404);
return strlen(header404);
break;
}
}
// Increment the global count of data sent out
int recordTotalBytes(int bytes_sent, sharedVariables *mempointer)
{
// Lock the mutex
pthread_mutex_lock(&(*mempointer).mutexlock);
// Increment bytes_sent
(*mempointer).totalbytes += bytes_sent;
// Unlock the mutex
pthread_mutex_unlock(&(*mempointer).mutexlock);
// Return the new byte count
return (*mempointer).totalbytes;
}
int main(int argc, char *argv[]) {
int conn_s; // connection socket
short int port = PORT; // port number
struct sockaddr_in servaddr; // socket address structure
// set up signal handler for ctrl-c
(void) signal(SIGINT, cleanup);
// create the listening socket
if ((list_s = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) {
fprintf(stderr, "Error creating listening socket.\n");
exit(EXIT_FAILURE);
}
// set all bytes in socket address structure to zero, and fill in the relevant data members
memset(&servaddr, 0, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
servaddr.sin_port = htons(port);
// bind to the socket address
if (bind(list_s, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0 ) {
fprintf(stderr, "Error calling bind()\n");
exit(EXIT_FAILURE);
}
// Listen on socket list_s
if( (listen(list_s, 10)) == -1)
{
fprintf(stderr, "Error Listening\n");
exit(EXIT_FAILURE);
}
// Set up some shared memory to store our shared variables in
// Close the shared memory we use just to be safe
shm_unlink("/sharedmem");
int sharedmem;
// Open the memory
if( (sharedmem = shm_open("/sharedmem", O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) == -1)
{
fprintf(stderr, "Error opening sharedmem in main() errno is: %s ", strerror(errno));
exit(EXIT_FAILURE);
}
// Set the size of the shared memory to the size of my structure
ftruncate(sharedmem, sizeof(sharedVariables) );
// Map the shared memory into our address space
sharedVariables *mempointer;
// Set mempointer to point at the shared memory
mempointer = mmap(NULL, sizeof(sharedVariables), PROT_READ | PROT_WRITE, MAP_SHARED, sharedmem, 0);
// Check the memory allocation went OK
if( mempointer == MAP_FAILED )
{
fprintf(stderr, "Error setting shared memory for sharedVariables in recordTotalBytes() error is %d \n ", errno);
exit(EXIT_FAILURE);
}
// Initalise the mutex
pthread_mutex_init(&(*mempointer).mutexlock, NULL);
// Set total bytes sent to 0
(*mempointer).totalbytes = 0;
// Size of the address
int addr_size = sizeof(servaddr);
// Sizes of data were sending out
int headersize;
int pagesize;
int totaldata;
// Number of child processes we have spawned
int children = 0;
// Variable to store the ID of the process we get when we spawn
pid_t pid;
// Loop infinitly serving requests
while(1)
{
// If we haven't already spawned 10 children fork
if( children <= 10)
{
pid = fork();
children++;
}
// If the pid is -1 the fork failed so handle that
if( pid == -1)
{
fprintf(stderr,"can't fork, error %d\n" , errno);
exit (1);
}
// Have the child process deal with the connection
if ( pid == 0)
{
// Have the child loop infinetly dealing with a connection then getting the next one in the queue
while(1)
{
// Accept a connection
conn_s = accept(list_s, (struct sockaddr *)&servaddr, &addr_size);
// If something went wrong with accepting the connection deal with it
if(conn_s == -1)
{
fprintf(stderr,"Error accepting connection \n");
exit (1);
}
// Get the message from the file descriptor
char * header = getMessage(conn_s);
// Parse the request
httpRequest details = parseRequest(header);
// Free header now were done with it
free(header);
// Print out the correct header
headersize = printHeader(conn_s, details.returncode);
// Print out the file they wanted
pagesize = printFile(conn_s, details.filename);
// Increment our count of total datasent by all processes and get back the new total
totaldata = recordTotalBytes(headersize+pagesize, mempointer);
// Print out which process handled the request and how much data was sent
printf("Process %d served a request of %d bytes. Total bytes sent %d \n", getpid(), headersize+pagesize, totaldata);
// Close the connection now were done
close(conn_s);
}
}
}
return EXIT_SUCCESS;
}
Pexec.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
static char* args[512];
pid_t pid;
int command_pipe[2];
#define READ 0
#define WRITE 1
static int command(int input, int first, int last)
{
int pipettes[2];
pipe( pipettes );
pid = fork();
if (pid == 0) {
if (first == 1 && last == 0 && input == 0) {
// First command
dup2( pipettes[WRITE], STDOUT_FILENO );
} else if (first == 0 && last == 0 && input != 0) {
// Middle command
dup2(input, STDIN_FILENO);
dup2(pipettes[WRITE], STDOUT_FILENO);
} else {
// Last command
dup2( input, STDIN_FILENO );
}
if (execvp( args[0], args) == -1)
_exit(EXIT_FAILURE);
}
if (input != 0)
close(input);
close(pipettes[WRITE]);
if (last == 1)
close(pipettes[READ]);
return pipettes[READ];
}
static void cleanup(int n)
{
int i;
for (i = 0; i < n; ++i)
wait(NULL);
}
static int run(char* cmd, int input, int first, int last);
static char line[1024];
static int n = 0; /* number of calls to 'command' */
int main(int argc, char *argv[])
{
while (1) {
// for(int i = 1; i < argc; i++){
// strcat(line, argv[i]);
// strcat(line, " ");
// }
/* Read a command line */
//if (!fgets(line, 1024, stdin))
//return 0;
int InputLength = atoi(getenv("INPUT_LENGTH"));
fread(line, InputLength, 1, stdin);
int input = 0;
int first = 1;
char* cmd = line;
char* next = strchr(cmd, '#'); /* Find first '|' */
while (next != NULL) {
/* 'next' points to '|' */
*next = '\0';
input = run(cmd, input, first, 0);
cmd = next + 1;
next = strchr(cmd, '#'); /* Find next '|' */
first = 0;
}
input = run(cmd, input, first, 1);
cleanup(n);
n = 0;
}
return 0;
}
static void split(char* cmd);
static int run(char* cmd, int input, int first, int last)
{
split(cmd);
if (args[0] != NULL) {
if (strcmp(args[0], "exit") == 0)
exit(0);
n += 1;
return command(input, first, last);
}
return 0;
}
static char* skipwhite(char* s)
{
while (isspace(*s)) ++s;
return s;
}
static void split(char* cmd)
{
cmd = skipwhite(cmd);
char* next = strchr(cmd, ' ');
int i = 0;
while(next != NULL) {
next[0] = '\0';
args[i] = cmd;
++i;
cmd = skipwhite(next + 1);
next = strchr(cmd, ' ');
}
if (cmd[0] != '\0') {
args[i] = cmd;
next = strchr(cmd, '\n');
next[0] = '\0';
++i;
}
args[i] = NULL;
}
input.html
<!DOCTYPE html>
<html>
<style>
input[type=text], select {
width: 100%;
padding: 12px 20px;
margin: 8px 0;
display: inline-block;
border: 1px solid #ccc;
border-radius: 4px;
box-sizing: border-box;
}
input[type=submit] {
width: 100%;
background-color: #4CAF50;
color: white;
padding: 14px 20px;
margin: 8px 0;
border: none;
border-radius: 4px;
cursor: pointer;
}
input[type=submit]:hover {
background-color: #45a049;
}
div {
border-radius: 5px;
background-color: #f2f2f2;
padding: 20px;
}
</style>
<body>
<h3><center>The Html Page Title </center></h3>
<div>
<form method="POST" action="pexec.cgi">
<label for="cmmd">Command</label>
<input type="text" id="cmmd" name="firstname" placeholder="Enter your Command here and then hit Run! Below">
<label for="lname">Entered Command </label>
<input type="text" id="lname" name="lastname" placeholder="This is what you entered...">
<label for="lname">Standard Output </label>
<input type="text" id="lname" name="lastname" placeholder="Standard Output will be shown here...">
<label for="lname">Standard Error </label>
<input type="text" id="lname" name="lastname" placeholder="standard error will be shown here...">
<input type="submit" value="Run!">
</form>
</div>
</body>
</html>

C:HTTP webserver - the image "http://localhost.... cannot be displayed because it contains errors

It's my first time dabbling with socket programming and I stumbled upon this amazing code from https://dzone.com/articles/web-server-c.
WHAT WE NEED TO DO: implement a simple HTTP web server that uses the web browser(input from the user) as a client
Here it is:
/*
* WebServer.c
*
* Created on: Nov 3, 2012
* Author: pavithra
*
* A web server in C language using only the standard libraries.
* The port number is passed as an argument.
*
*/
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <fcntl.h>
#include <errno.h>
#include <sys/stat.h>
#include <sys/sendfile.h>
#define EOL "\r\n"
#define EOL_SIZE 2
typedef struct {
char *ext;
char *mediatype;
} extn;
//Possible media types
extn extensions[] ={
{"gif", "image/gif" },
{"txt", "text/plain" },
{"jpg", "image/jpg" },
{"jpeg","image/jpeg"},
{"png", "image/png" },
{"ico", "image/ico" },
{"zip", "image/zip" },
{"gz", "image/gz" },
{"tar", "image/tar" },
{"htm", "text/html" },
{"html","text/html" },
{"php", "text/html" },
{"pdf","application/pdf"},
{"zip","application/octet-stream"},
{"rar","application/octet-stream"},
{0,0} };
//find webroot, add design
/*
A helper function
*/
void error(const char *msg) {
perror(msg);
exit(1);
}
/*
A helper function
*/
int get_file_size(int fd) {
struct stat stat_struct;
if (fstat(fd, &stat_struct) == -1)
return (1);
return (int) stat_struct.st_size;
}
/*
A helper function
*/
void send_new(int fd, char *msg) {
int len = strlen(msg);
if (send(fd, msg, len, 0) == -1) {
printf("Error in send\n");
}
}
/*
This function recieves the buffer
until an "End of line(EOL)" byte is recieved
*/
int recv_new(int fd, char *buffer) {
char *p = buffer; // Use of a pointer to the buffer rather than dealing with the buffer directly
int eol_matched = 0; // Use to check whether the recieved byte is matched with the buffer byte or not
while (recv(fd, p, 1, 0) != 0) // Start receiving 1 byte at a time
{
if (*p == EOL[eol_matched]) // if the byte matches with the first eol byte that is '\r'
{
++eol_matched;
if (eol_matched == EOL_SIZE) // if both the bytes matches with the EOL
{
*(p + 1 - EOL_SIZE) = '\0'; // End the string
return (strlen(buffer)); // Return the bytes recieved
}
} else {
eol_matched = 0;
}
p++; // Increment the pointer to receive next byte
}
return (0);
}
/*
A helper function: Returns the
web root location.
*/
char* webroot() {
// open the file "kill.txt" for reading
FILE *in = fopen("kill.txt", "rt");
// read the first line from the file
char buff[1000];
fgets(buff, 1000, in);
// close the stream
fclose(in);
char* nl_ptr = strrchr(buff, '\n');
if (nl_ptr != NULL)
*nl_ptr = '\0';
return strdup(buff);
}
/*
Handles php requests
*/
void php_cgi(char* script_path, int fd) {
send_new(fd, "HTTP/1.1 200 OK\n Server: Web Server in C\n Connection: close\n");
dup2(fd, STDOUT_FILENO);
char script[500];
strcpy(script, "SCRIPT_FILENAME=");
strcat(script, script_path);
putenv("GATEWAY_INTERFACE=CGI/1.1");
putenv(script);
putenv("QUERY_STRING=");
putenv("REQUEST_METHOD=GET");
putenv("REDIRECT_STATUS=true");
putenv("SERVER_PROTOCOL=HTTP/1.1");
putenv("REMOTE_HOST=127.0.0.1");
execl("/usr/bin/php-cgi", "php-cgi", NULL);
}
/*
This function parses the HTTP requests,
arrange resource locations,
check for supported media types,
serves files in a web root,
sends the HTTP error codes.
*/
int connection(int fd) {
char request[500], resource[500], *ptr;
int fd1, length;
if (recv_new(fd, request) == 0) {
printf("Receive Failed\n");
}
printf("%s\n", request);
// Check for a valid browser request
ptr = strstr(request, " HTTP/");
if (ptr == NULL) {
printf("NOT HTTP !\n");
} else {
*ptr = 0;
ptr = NULL;
if (strncmp(request, "GET ", 4) == 0) {
ptr = request + 4;
}
if (ptr == NULL) {
printf("Unknown Request ! \n");
} else {
if (ptr[strlen(ptr) - 1] == '/') {
strcat(ptr, "test.html");
}
strcpy(resource, webroot());
strcat(resource, ptr);
char* s = strchr(ptr, '.');
int i;
for (i = 0; extensions[i].ext != NULL; i++) {
if (strcmp(s + 1, extensions[i].ext) == 0) {
fd1 = open(resource, O_RDONLY, 0);
printf("Opening \"%s\"\n", resource);
if (fd1 == -1) {
printf("404 File not found Error\n");
send_new(fd, "HTTP/1.1 404 Not Found\r\n");
send_new(fd, "Server : Web Server in C\r\n\r\n");
send_new(fd, "<html><head><title>404 Not Found</head></title>");
send_new(fd, "<body><p>404 Not Found: The requested resource could not be found!</p></body></html>\r\n");
//Handling php requests
} else if (strcmp(extensions[i].ext, "php") == 0) {
php_cgi(resource, fd);
sleep(1);
close(fd);
exit(1);
} else {
printf("200 OK, Content-Type: %s\n\n",
extensions[i].mediatype);
send_new(fd, "HTTP/1.1 200 OK\r\n");
send_new(fd, "Server : Web Server in C\r\n\r\n");
if (ptr == request + 4) // if it is a GET request
{
if ((length = get_file_size(fd1)) == -1)
printf("Error in getting size !\n");
size_t total_bytes_sent = 0;
ssize_t bytes_sent;
while (total_bytes_sent < length) {
//Zero copy optimization
if ((bytes_sent = sendfile(fd, fd1, 0,
length - total_bytes_sent)) <= 0) {
if (errno == EINTR || errno == EAGAIN) {
continue;
}
perror("sendfile");
return -1;
}
total_bytes_sent += bytes_sent;
}
//why is it not appearing up to 11:30
}
}
break;
}
int size = sizeof(extensions) / sizeof(extensions[0]);
if (i == size - 2) {
printf("415 Unsupported Media Type\n");
send_new(fd, "HTTP/1.1 415 Unsupported Media Type\r\n");
send_new(fd, "Server : Web Server in C\r\n\r\n");
send_new(fd, "<html><head><title>415 Unsupported Media Type</head></title>");
send_new(fd, "<body><p>415 Unsupported Media Type!</p></body></html>");
}
}
close(fd);
}
}
shutdown(fd, SHUT_RDWR);
}
int main(int argc, char *argv[]) {
int sockfd, newsockfd, portno, pid;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
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);
/*
Server runs forever, forking off a separate
process for each connection.
*/
while (1) {
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if (newsockfd < 0)
error("ERROR on accept");
pid = fork();
if (pid < 0)
error("ERROR on fork");
if (pid == 0) {
close(sockfd);
connection(newsockfd);
exit(0);
} else
close(newsockfd);
} /* end of while */
close(sockfd);
return 0; /* we never get here */
}
NOTE: the kill.txt contains the directory of the server, the files(jpegs, gifs, etc.: /home/user/Desktop)
PROBLEM:
1. After I compile the program and execute it on my web browser as "localhost:port number/file" this is what appears on my web browser:
the image "http://localhost.... cannot be displayed because it contains errors.
And this is what appears on my terminal:
GET /sample5.gif HTTP/1.1
Opening "/home/user/Desktop/sample5.gif"
200 OK, Content-Type: image/gif
GET /favicon.ico HTTP/1.1
Opening "/home/user/Desktop/favicon.ico"
404 File not found Error
How do I fix this? Any help/comment would be greatly appreciated! Thanks.
Where is that favicon.ico bit coming from? /I looked this up and apparently having that favicon.ico bit is quite normal (can somebody please confirm this?)/
… I stumbled upon this amazing code from …
It is indeed amazing how bad it is.
At the end of the function int connection(int fd) there's:
close(fd);
}
}
shutdown(fd, SHUT_RDWR);
}
Browsers don't like the connection being reset by peer (due to close()) before it's tidily shut down. Move the close() after the shutdown().
The program neglects to reap child processes, thus a zombie process remains after each request. #include <signal.h> and add sigignore(SIGCHLD); at the start of main().
If the action for the SIGCHLD signal is set to SIG_IGN, child
processes of the calling processes will not be transformed into zombie
processes when they terminate.

How to get all html file with a HTTP GET request using c++?

I need to create a c++ console application that query a site in turn to get the html page.
The site is static because when I queried it in the url I see the html file, so I use this code:
send(Socket, "GET /it/ricette/q-torte_forno_statico.html HTTP/1.1\r\nHost: worldrecipes.expo2015.org/\r\nConnection: close\r\n\r\n", strlen("GET /it/ricette/q-torte_forno_statico.html HTTP/1.1\r\nHost: worldrecipes.expo2015.org\r\nConnection: close\r\n\r\n"), 0);
char buffer[1000000];
int nDataLength;
while ((nDataLength = recv(Socket, buffer, 1000000, 0)) > 0) {
int i = 0;
while (buffer[i] >= 32 || buffer[i] == '\n' || buffer[i] == '\r') {
cout << buffer[i];
i += 1;
}
}
It doesn't give me any errors but don't show me the whole html page and every time that I call send the request I get different answers ... why?
This code below seems to only work on the index page worldrecipes.expo2015.org and not the sub pages. You might want to look at more advanced webbrowser controls for visual studio for parsing and processing HTML.
Like here : http://www.codeproject.com/Articles/3365/Embed-an-HTML-control-in-your-own-window-using-pla
here : https://msdn.microsoft.com/en-us/library/aa752046(v=vs.85).aspx
and here : http://www.codeproject.com/Articles/3919/Using-the-WebBrowser-control-simplified
Example code:
#include <windows.h>
#include <string>
#include <stdio.h>
using std::string;
#pragma comment(lib,"ws2_32.lib")
HINSTANCE hInst;
WSADATA wsaData;
void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename);
SOCKET connectToServer(char *szServerName, WORD portNum);
int getHeaderLength(char *content);
char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut);
int main()
{
const int bufLen = 1024;
char *szUrl = "http://worldrecipes.expo2015.org/it/ricette/q-torte_forno_statico.html";
long fileSize;
char *memBuffer, *headerBuffer;
FILE *fp;
memBuffer = headerBuffer = NULL;
if ( WSAStartup(0x101, &wsaData) != 0)
return -1;
memBuffer = readUrl2(szUrl, fileSize, &headerBuffer);
printf("returned from readUrl\n");
printf("data returned:\n%s", memBuffer);
if (fileSize != 0)
{
printf("Got some data\n");
fp = fopen("downloaded.file", "wb");
fwrite(memBuffer, 1, fileSize, fp);
fclose(fp);
// SetDlgItemText(hwndDlg, IDC_EDIT4, headerBuffer);
// SetDlgItemText(hwndDlg, IDC_EDIT5, memBuffer);
delete(memBuffer);
delete(headerBuffer);
}
WSACleanup();
return 0;
}
void mParseUrl(char *mUrl, string &serverName, string &filepath, string &filename)
{
string::size_type n;
string url = mUrl;
if (url.substr(0,7) == "http://")
url.erase(0,7);
if (url.substr(0,8) == "https://")
url.erase(0,8);
n = url.find('/');
if (n != string::npos)
{
serverName = url.substr(0,n);
filepath = url.substr(n);
n = filepath.rfind('/');
filename = filepath.substr(n+1);
}
else
{
serverName = url;
filepath = "/";
filename = "";
}
}
SOCKET connectToServer(char *szServerName, WORD portNum)
{
struct hostent *hp;
unsigned int addr;
struct sockaddr_in server;
SOCKET conn;
conn = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (conn == INVALID_SOCKET)
return NULL;
if(inet_addr(szServerName)==INADDR_NONE)
{
hp=gethostbyname(szServerName);
}
else
{
addr=inet_addr(szServerName);
hp=gethostbyaddr((char*)&addr,sizeof(addr),AF_INET);
}
if(hp==NULL)
{
closesocket(conn);
return NULL;
}
server.sin_addr.s_addr=*((unsigned long*)hp->h_addr);
server.sin_family=AF_INET;
server.sin_port=htons(portNum);
if(connect(conn,(struct sockaddr*)&server,sizeof(server)))
{
closesocket(conn);
return NULL;
}
return conn;
}
int getHeaderLength(char *content)
{
const char *srchStr1 = "\r\n\r\n", *srchStr2 = "\n\r\n\r";
char *findPos;
int ofset = -1;
findPos = strstr(content, srchStr1);
if (findPos != NULL)
{
ofset = findPos - content;
ofset += strlen(srchStr1);
}
else
{
findPos = strstr(content, srchStr2);
if (findPos != NULL)
{
ofset = findPos - content;
ofset += strlen(srchStr2);
}
}
return ofset;
}
char *readUrl2(char *szUrl, long &bytesReturnedOut, char **headerOut)
{
const int bufSize = 512;
char readBuffer[bufSize], sendBuffer[bufSize], tmpBuffer[bufSize];
char *tmpResult=NULL, *result;
SOCKET conn;
string server, filepath, filename;
long totalBytesRead, thisReadSize, headerLen;
mParseUrl(szUrl, server, filepath, filename);
///////////// step 1, connect //////////////////////
conn = connectToServer((char*)server.c_str(), 80);
///////////// step 2, send GET request /////////////
sprintf(tmpBuffer, "GET %s HTTP/1.0", filepath.c_str());
strcpy(sendBuffer, tmpBuffer);
strcat(sendBuffer, "\r\n");
sprintf(tmpBuffer, "Host: %s", server.c_str());
strcat(sendBuffer, tmpBuffer);
strcat(sendBuffer, "\r\n");
strcat(sendBuffer, "\r\n");
send(conn, sendBuffer, strlen(sendBuffer), 0);
// SetWindowText(edit3Hwnd, sendBuffer);
printf("Buffer being sent:\n%s", sendBuffer);
///////////// step 3 - get received bytes ////////////////
// Receive until the peer closes the connection
totalBytesRead = 0;
while(1)
{
memset(readBuffer, 0, bufSize);
thisReadSize = recv (conn, readBuffer, bufSize, 0);
if ( thisReadSize <= 0 )
break;
tmpResult = (char*)realloc(tmpResult, thisReadSize+totalBytesRead);
memcpy(tmpResult+totalBytesRead, readBuffer, thisReadSize);
totalBytesRead += thisReadSize;
}
headerLen = getHeaderLength(tmpResult);
long contenLen = totalBytesRead-headerLen;
result = new char[contenLen+1];
memcpy(result, tmpResult+headerLen, contenLen);
result[contenLen] = 0x0;
char *myTmp;
myTmp = new char[headerLen+1];
strncpy(myTmp, tmpResult, headerLen);
myTmp[headerLen] = NULL;
delete(tmpResult);
*headerOut = myTmp;
bytesReturnedOut = contenLen;
closesocket(conn);
return(result);
}

msgrcv() function not returning in client process

My program is based on interprocess communication. The client send a filename which the server reads and returns its contents back to the client. The msgsnd() function seems to be working but there is no return to the client function when msgrcv() is invoked to read the files contents.
Here is my client program :
#include<sys/msg.h>
#include<sys/ipc.h>
#include<sys/types.h>
#include<string.h>
#include<stdio.h>
#include<fcntl.h>
#define MSGSIZE 10000
typedef struct
{
long mtype;
char msgtext[MSGSIZE];
} msg_buf;
int main()
{
int msgflag=IPC_CREAT | 0666;
key_t k1, k2;
msg_buf buf;
k1 = 1234;
k2 = 5678;
int msgqid1, msgqid2;
if(msgqid1=msgget(k1,msgflag)<0)
{
printf("\nClient online : the output message queue isn't available. Restart !\n");
return 0;
}
else
{
printf("\nClient online : the output message queue is available.\n Enter the file name : ");
scanf("%s",buf.msgtext);
}
buf.mtype = 1;
if(msgqid2=msgget(k2,msgflag)<0)
printf("\nClient: Input message queue unavailable. Restart !\n");
else
printf("\nClient : Input message queue available \n");
int buf_len = strlen(buf.msgtext)+1;
printf("Client: Sending file name : %s \n",buf.msgtext);
if(msgsnd(msgqid1,&buf,buf_len,IPC_NOWAIT)<0)
{
printf("Client : Error sending file name\n");
return 0;
}
printf("hello\n");
if((msgrcv(msgqid2,&buf,MSGSIZE,2,0))<0)
{
printf("Client : Error Recieving file contents from server\n");return 0;
}
else
{
printf("File Contents from the server as follows :\n ");
fputs(buf.msgtext,stdout);
printf("\n\n");
}
}
Here is my server program:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/msg.h>
#define MSGSIZE 10000
typedef struct msg_buf
{
long mtype;
char msgtext[MSGSIZE];
} msg_buf;
int main()
{
msg_buf buf;
key_t k1, k2;
int filesize, fileread, msgqid1, msgqid2;
k1 = 1234;
k2 = 5678;
int msgflag=IPC_CREAT | 0666;
if((msgqid1=msgget(k1,msgflag))<0)
{
printf("Server Online :Input message queue not available. Restart !\n");
return 0;
}
printf("Server Online :Input message queue available.\n");
if((msgrcv(msgqid1,&buf,MSGSIZE,1,0))<0)
{
printf("Server : Error receiving file name");
return 0;
}
printf("Server : File name %s received. \n",buf.msgtext);
if((msgqid2=msgget(k2,msgflag))<0)
{
printf("Server : Output message queue not available. Restart !\n");
return 0;
}
else
printf("Server Online : Output message queue available.\n");
fileread = open(buf.msgtext,O_RDONLY);
if(fileread<0)
{
printf("Server : File not found,%d \n",fileread);
return 0;
}
buf.mtype = 2;printf("Server : file found\n");
filesize = lseek(fileread,0,2);
lseek(fileread,0,0);
int n = read(fileread,buf.msgtext,filesize);
int buf_len = strlen(buf.msgtext)+1;
fputs(buf.msgtext,stdout);
if(msgsnd(msgqid2,&buf,buf_len,IPC_NOWAIT)>=0)
printf("Server : contents of the file sent to the client\n");
else
{
printf("Server : Error on sending file contents \n");
return 0;
}
}