Call C function with arguments on fastcgi web application - c

I'm developing a web app for a reservation system and so far I achieved to send a mail with libcurl and display the form in HTML using fcgi_stdio.h, but both separately.
This is how it looks
#define __USE_XOPEN
#define _GNU_SOURCE
#include <stdio.h>
#include <fcgi_stdio.h>
#include <string.h>
#include <stdlib.h>
#include "mail.h"
#include "booking.h"
int
main()
{
char to[20], name[20];
//char *year, *mon, *day, *hour, *min;
char date[20];
char num_guest[4], phone[10];
while (FCGI_Accept() >= 0) {
printf("Content-type: text/html\n\n");
printf("<h1>Welcome</h1>");
char *method = getenv("REQUEST_METHOD");
char form[2048] = {0};
char output[2048] = {0};
if(strcmp(method, "GET") == 0) {
strcpy(form,
"<form method='POST' action=''>"
"<input id='name' name='name' type='text'></input>"
"<br>"
"<input id='to' name='to' type='email'></input>"
"<br>"
"<input id='date' type='datetime-local' name='date' />"
"<br>"
"<input type='tel' "
"id='phone' name='phone' size='20' "
"minlenght='9' maxlenght='14' required>"
"<br>"
"<input type='number' id='num_guest' name='num_guest'"
"min='1' max='18'>"
"<br>"
"<input type='submit' value='Submit'>"
"</form>"
);
} else if (strcmp(method, "POST") == 0) {
int ilen = atoi(getenv("CONTENT_LENGTH"));
//char *bufp = malloc(ilen);
char *bufp = (char *) malloc(ilen * sizeof(char));
fread(bufp, ilen, 1, stdin);
printf("<h3>Thank you for your reservation!</h3>");
strcpy(output, bufp);
free(bufp);
/* declare data variables */
sscanf(output,
"name=%[^&]&to=%[^&]&date=%[^&]&phone=%[^&]&num_guest=%[^&]",
name, to, date, phone, num_guest);
replace(date, "%3A", ":"); // makes the date readable
replace(to, "%40", "#"); // makes the mail readable
}
printf(
"<div>"
"%s"
"</div>",
form
);
}
return 0;
}
The code above works fine, but I would like to call these functions after clicking the Submit button.
book_for(to, name, num_guest, phone, date);
send_mail("addr", "confirmation.mail");
Those functions alone and declaring before the arguments as char *name = 'some name'; work fine too sending the mail to the recipient.
Thanks for your help :)

Related

I am creating an embedded web server using Mongoose. How can I get the parameters in the URL(looking for something like req.getparameter() in Java)

void fn(struct mg_connection *c, int ev, void *ev_data, void *fn_data)
{
if (ev == MG_EV_HTTP_MSG)
{
struct mg_http_message *hm = (struct mg_http_message *) ev_data;
if (mg_http_match_uri(hm, "/api/hello")) // On /api/hello requests,
{
char html[1000];
strcpy(html, "<!DOCTYPE html>"
"<html>"
"<head>"
"</head>"
"<body>"
"<form action=\"sum\" method = \"GET\">"
"<label> Number 1</label>"
"<input type=\"text\" name=\"number1\"> <br>"
"<label> Number 2</label>"
"<input type=\"text\" name=\"number2\"><br>"
"<input type=\"submit\" value=\"Add\">"
"</form>"
"</body>"
"</html>");
mg_http_reply(c, 200, "Content-Type: text/html\r\n", html);
}
else if(mg_http_match_uri(hm, "/api/sum"))
{
struct mg_str params = hm->body;
double num1, num2;
if(mg_json_get_num(params, "$[0]", &num1) &&
mg_json_get_num(params,"$[1]", &num2))
{
mg_http_reply(c, 200, "Content-Type: text/plain\r\n", "result:%g\n", num1 + num2);
}
else
{
mg_http_reply(c, 500, "NULL", "%s","Parameters Missing");
}
}
else // For all other URIs,
{
mg_http_reply(c, 200, "Content-Type: text/plain\r\n", "%s\n", "Static Content");
}
}
}
void task1(void)
{
struct mg_mgr mgr;
mg_mgr_init(&mgr); // Init manager
mg_http_listen(&mgr, "http://10.0.0.6:8000", fn, &mgr); // Setup listener
for (;;) mg_mgr_poll(&mgr, 1000); // Event loop
}
In the code main.c calls task1(). When I type the URL "http://10.0.0.6:8000/api/hello" I am getting the html form. But on submitting the form I am not able to go to "http://10.0.0.6:8000/api/sum".
Tried
else if(mg_http_match_uri(hm, "/api/sum"))
{
mg_http_reply(c, 200, "Content-Type: text/plain\r\n", "%s\n", "Static Content");
}
and is working fine. I suspect the problem is in getting parameter values. In Java we have request.getparameter() for getting required parameters, Do we have something like that in mongoose.
So please tell me the correct way to get parameter values in a URL.
The problem is that you're submitting a form via GET, e.g. parameters are passed in the query string (in the URL). And you're getting parameters from the body.
There are two ways to fix your code.
Submit parameters in the HTTP body. To do that, change your form's method from GET to POST.
OR, get parameters from the query string. To do that, change struct mg_str params = hm->body; to struct mg_str params = hm->query;
Hope that helps.

Getting Bus error: 10 when I run my C code

I'm writing a function in C to make my web server display the directory listing as an HTML document. When I run make, everything seems to compile fine, but when I run the file, I keep getting bus error:10. Thank you for all of your help!
This is the HTML template that I want to write into the socket id to display when I run my file on localhost:3000 (or localhost:8000):
<ul>
<li><a href='./'>.</a></li>
<li><a href='../'>..</a></li>
<li><a href='.DS_Store'>.DS_Store</a></li>
<li><a href='resume/'>resume</a></li>
<li><a href='lolcode.html'>lolcode.html</a></li>
<li><a href='ybruf.pid'>ybruf.pid</a></li>
</ul>
This is my code for this function:
static bool process_dir(int sock_id, char *doc)
{
// Open the directory for reading
DIR *dir = opendir(doc);
/* if the dir failed to open */
if (dir == NULL)
{
syslog(LOG_ERR, "opendir(): %s", strerror(errno));
write_http_header(sock_id, PROTO "404 File Not Found",
"File Not Found");
return false;
}
// Write the header - we seem to be ok
// Technically, this is not correct. We must first fully read the direct
/* successfull open the dir */
write_http_header(sock_id, PROTO "200 OK", NULL);
// Define the template
struct dirent *dirp;
dirp = readdir(dir);
char dirp_name[1024]; // if it is a diretory then dirp_name will have /
char *ul_open = "<ul>\n";
char *ul_close = "</ul>";
write(sock_id, ul_open, strlen(ul_open));
char *li_open = "<li><a href='";
char *li_middle = "'>";
char *li_close = "</a></li>\n";
while (dirp != NULL)
{
// if it's a file, then just need to get the name
// for example: resume.html
strcpy(dirp_name, dirp->d_name);
if (dirp->d_type == DT_DIR)
{
// if it's a directory then need to have / at the end
// for example: resume/
strcat(dirp_name, "/");
}
// for example: <li><a href='resume/'>resume</a></ li>
write(sock_id, li_open, strlen(li_open));
write(sock_id, dirp_name, strlen(dirp_name));
write(sock_id, li_middle, strlen(li_middle));
write(sock_id, dirp->d_name, dirp->d_namlen);
write(sock_id, li_close, strlen(li_close));
dirp = readdir(dir);
}
write(sock_id, ul_close, strlen(ul_close));
errno = 0; // Assume no errors
closedir(dir);
if (errno)
{
// Too late to complain!
syslog(LOG_ERR, "%s", strerror(errno));
}
return errno == 0;
}

How to make an array of character in C

I am trying to make an array of character. I get this code and get error
#include<stdio.h>
#include<stdlib.h>
#include"boolean.h"
const char *skillNames[8];
skillNames[0] = "Darth Vader";
skillNames[1] = "Han Solo";
skillNames[2] = "Master Yoda";
skillNames[3] = "Luke Skywalker";
skillNames[4] = "Obi Wan Kenobi";
skillNames[5] = "Chewbacca";
skillNames[6] = "Emperor Palpatine";
skillNames[7] = "Princess Leia";
#include<stdio.h>
#include<stdlib.h>
#include"boolean.h"
int main() {
const char *skillNames[8];
skillNames[0] = "Darth Vader";
skillNames[1] = "Han Solo";
skillNames[2] = "Master Yoda";
skillNames[3] = "Luke Skywalker";
skillNames[4] = "Obi Wan Kenobi";
skillNames[5] = "Chewbacca";
skillNames[6] = "Emperor Palpatine";
skillNames[7] = "Princess Leia";
}
Put it inside a main function.
You can use the initialization syntax. You don't even need to mention the size of the array:
const char *skillNames[] = {
"Darth Vader", "Han Solo", "Master Yoda", "Luke Skywalker",
"Obi Wan Kenobi", "Chewbacca", "Emperor Palpatine", "Princess Leia",
};
Add a main() function and replace the #include"boolean.h" with #include<stdbool.h>. See if that fixes the error or not.
The full code can be like this:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
const char *skillNames[8];
skillNames[0] = "Darth Vader";
skillNames[1] = "Han Solo";
skillNames[2] = "Master Yoda";
skillNames[3] = "Luke Skywalker";
skillNames[4] = "Obi Wan Kenobi";
skillNames[5] = "Chewbacca";
skillNames[6] = "Emperor Palpatine";
skillNames[7] = "Princess Leia";
}

How to extract multiple numbers from string in C

I have a question. If I want to extract more than one float number in a string what should I do ?
I know that there are functions like strtof by which I can extract the number. The question is what if there are more than one number existing in string?
I just want and I know that only thing that is needed is pointer to the next character after finding the number. Then continue searching until it reaches \n but how?
EXAMPLE:
Imagine I have a report about rainfall of some towns during a year and I want to
extract rainfall for each town (when it gets to the \nreport for the town is finished ).
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char* data = "Rome:Jan 81.2,Feb 63.2,Mar 70.3,Apr 55.7,May 53.0,Jun 36.4,Jul 17.5,Aug 27.5,Sep 60.9,Oct 117.7,Nov 111.0,Dec 97.9\n"
"London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9\n"
"Paris:Jan 182.3,Feb 120.6,Mar 158.1,Apr 204.9,May 323.1,Jun 300.5,Jul 236.8,Aug 192.9,Sep 66.3,Oct 63.3,Nov 83.2,Dec 154.7\n"
"NY:Jan 108.7,Feb 101.8,Mar 131.9,Apr 93.5,May 98.8,Jun 93.6,Jul 102.2,Aug 131.8,Sep 92.0,Oct 82.3,Nov 107.8,Dec 94.2\n"
"Vancouver:Jan 145.7,Feb 121.4,Mar 102.3,Apr 69.2,May 55.8,Jun 47.1,Jul 31.3,Aug 37.0,Sep 59.6,Oct 116.3,Nov 154.6,Dec 171.5\n"
"Sydney:Jan 103.4,Feb 111.0,Mar 131.3,Apr 129.7,May 123.0,Jun 129.2,Jul 102.8,Aug 80.3,Sep 69.3,Oct 82.6,Nov 81.4,Dec 78.2\n"
"Bangkok:Jan 10.6,Feb 28.2,Mar 30.7,Apr 71.8,May 189.4,Jun 151.7,Jul 158.2,Aug 187.0,Sep 319.9,Oct 230.8,Nov 57.3,Dec 9.4\n"
"Tokyo:Jan 49.9,Feb 71.5,Mar 106.4,Apr 129.2,May 144.0,Jun 176.0,Jul 135.6,Aug 148.5,Sep 216.4,Oct 194.1,Nov 95.6,Dec 54.4\n"
"Beijing:Jan 3.9,Feb 4.7,Mar 8.2,Apr 18.4,May 33.0,Jun 78.1,Jul 224.3,Aug 170.0,Sep 58.4,Oct 18.0,Nov 9.3,Dec 2.7\n"
"Lima:Jan 1.2,Feb 0.9,Mar 0.7,Apr 0.4,May 0.6,Jun 1.8,Jul 4.4,Aug 3.1,Sep 3.3,Oct 1.7,Nov 0.5,Dec 0.7";
const char* towns[14] = {"Rome", "London", "Paris", "NY", "Vancouver", "Sydney", "Bangkok", "Tokyo",
"Beijing", "Lima", "Montevideo", "Caracas", "Madrid", "Berlin"};
size_t i = 0;
float nums[12];
char *ch_ptr = strstr(data,towns[0]); //pointing to first character
const char *stop ="\n";
while((ch_ptr++) != stop)
{
nums[i] = strtof(); ///How should I do it ????
i++;
}
return 0;
}
Using two nested for loops, the float value for each town and month can be captured.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char* data = "Rome:Jan 81.2,Feb 63.2,Mar 70.3,Apr 55.7,May 53.0,Jun 36.4,Jul 17.5,Aug 27.5,Sep 60.9,Oct 117.7,Nov 111.0,Dec 97.9\n"
"London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9\n"
"Paris:Jan 182.3,Feb 120.6,Mar 158.1,Apr 204.9,May 323.1,Jun 300.5,Jul 236.8,Aug 192.9,Sep 66.3,Oct 63.3,Nov 83.2,Dec 154.7\n"
"NY:Jan 108.7,Feb 101.8,Mar 131.9,Apr 93.5,May 98.8,Jun 93.6,Jul 102.2,Aug 131.8,Sep 92.0,Oct 82.3,Nov 107.8,Dec 94.2\n"
"Vancouver:Jan 145.7,Feb 121.4,Mar 102.3,Apr 69.2,May 55.8,Jun 47.1,Jul 31.3,Aug 37.0,Sep 59.6,Oct 116.3,Nov 154.6,Dec 171.5\n"
"Sydney:Jan 103.4,Feb 111.0,Mar 131.3,Apr 129.7,May 123.0,Jun 129.2,Jul 102.8,Aug 80.3,Sep 69.3,Oct 82.6,Nov 81.4,Dec 78.2\n"
"Bangkok:Jan 10.6,Feb 28.2,Mar 30.7,Apr 71.8,May 189.4,Jun 151.7,Jul 158.2,Aug 187.0,Sep 319.9,Oct 230.8,Nov 57.3,Dec 9.4\n"
"Tokyo:Jan 49.9,Feb 71.5,Mar 106.4,Apr 129.2,May 144.0,Jun 176.0,Jul 135.6,Aug 148.5,Sep 216.4,Oct 194.1,Nov 95.6,Dec 54.4\n"
"Beijing:Jan 3.9,Feb 4.7,Mar 8.2,Apr 18.4,May 33.0,Jun 78.1,Jul 224.3,Aug 170.0,Sep 58.4,Oct 18.0,Nov 9.3,Dec 2.7\n"
"Lima:Jan 1.2,Feb 0.9,Mar 0.7,Apr 0.4,May 0.6,Jun 1.8,Jul 4.4,Aug 3.1,Sep 3.3,Oct 1.7,Nov 0.5,Dec 0.7";
const char* months[12] = {"Jan", "Feb", "Mar", "Apr", "May", "Jun"
, "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
const char* towns[14] = {"Rome", "London", "Paris", "NY", "Vancouver", "Sydney", "Bangkok", "Tokyo",
"Beijing", "Lima", "Montevideo", "Caracas", "Madrid", "Berlin"};
size_t i = 0;
float nums[12];
char *end = NULL;
char *town_ptr = NULL;
char *month_ptr = NULL;
char monthid[100] = "";
char townid[100] = "";
for ( int town = 0; town < 14; town++)
{
if ( ( town_ptr = strstr ( data, towns[town]))) {
i = 0;
sscanf ( town_ptr, "%99[^:]", townid);
for ( int month = 0; month < 12; month++)
{
if ( ( month_ptr = strstr ( town_ptr, months[month]))) {
sscanf ( month_ptr, "%99s", monthid);
month_ptr += strlen ( months[month]);
nums[i] = strtof( month_ptr, &end);
if ( *end == ',' || *end == '\n' || *end == '\0') {
printf ( "%s %s nums[%d] = %f\n", townid, monthid, i, nums[i]);
i++;
}
}
}
}
}
return 0;
}
To parse from the town name to a newline. If a month was missing from a town, the previous code would use the month from the next town. This will iterate from the town name until twelve values, a newline, a '\0' or failure to parse a double.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv)
{
char* data = "Rome:Jan 81.2,Feb 63.2,Mar 70.3,Apr 55.7,May 53.0,Jun 36.4,Jul 17.5,Aug 27.5,Sep 60.9,Oct 117.7,Nov 111.0,Dec 97.9\n"
"London:Jan 48.0,Feb 38.9,Mar 39.9,Apr 42.2,May 47.3,Jun 52.1,Jul 59.5,Aug 57.2,Sep 55.4,Oct 62.0,Nov 59.0,Dec 52.9\n"
"Paris:Jan 182.3,Feb 120.6,Mar 158.1,Apr 204.9,May 323.1,Jun 300.5,Jul 236.8,Aug 192.9,Sep 66.3,Oct 63.3,Nov 83.2,Dec 154.7\n"
"NY:Jan 108.7,Feb 101.8,Mar 131.9,Apr 93.5,May 98.8,Jun 93.6,Jul 102.2,Aug 131.8,Sep 92.0,Oct 82.3,Nov 107.8,Dec 94.2\n"
"Vancouver:Jan 145.7,Feb 121.4,Mar 102.3,Apr 69.2,May 55.8,Jun 47.1,Jul 31.3,Aug 37.0,Sep 59.6,Oct 116.3,Nov 154.6,Dec 171.5\n"
"Sydney:Jan 103.4,Feb 111.0,Mar 131.3,Apr 129.7,May 123.0,Jun 129.2,Jul 102.8,Aug 80.3,Sep 69.3,Oct 82.6,Nov 81.4,Dec 78.2\n"
"Bangkok:Jan 10.6,Feb 28.2,Mar 30.7,Apr 71.8,May 189.4,Jun 151.7,Jul 158.2,Aug 187.0,Sep 319.9,Oct 230.8,Nov 57.3,Dec 9.4\n"
"Tokyo:Jan 49.9,Feb 71.5,Mar 106.4,Apr 129.2,May 144.0,Jun 176.0,Jul 135.6,Aug 148.5,Sep 216.4,Oct 194.1,Nov 95.6,Dec 54.4\n"
"Beijing:Jan 3.9,Feb 4.7,Mar 8.2,Apr 18.4,May 33.0,Jun 78.1,Jul 224.3,Aug 170.0,Sep 58.4,Oct 18.0,Nov 9.3,Dec 2.7\n"
"Lima:Jan 1.2,Feb 0.9,Mar 0.7,Apr 0.4,May 0.6,Jun 1.8,Jul 4.4,Aug 3.1,Sep 3.3,Oct 1.7,Nov 0.5,Dec 0.7";
const char* towns[14] = {"Rome", "London", "Paris", "NY", "Vancouver", "Sydney", "Bangkok", "Tokyo",
"Beijing", "Lima", "Montevideo", "Caracas", "Madrid", "Berlin"};
float nums[12];
char *end = NULL;
char *town_ptr = NULL;
char monthid[100] = "";
char townid[100] = "";
int span = 0;
for ( int town = 0; town < 14; town++)
{
if ( ( town_ptr = strstr ( data, towns[town]))) {//find the town name
sscanf ( town_ptr, "%99[^:]:%n", townid, &span);
int each = 0;
town_ptr += span;
do {
sscanf ( town_ptr, "%s%n", monthid, &span);
town_ptr += span;
nums[each] = strtod ( town_ptr, &end);
if ( end == town_ptr) {//failed to parse a double
break;
}
printf ( "%s %s nums[%d] = %f\n", townid, monthid, each, nums[each]);
town_ptr = end + 1;//to advance past the comma
each++;
} while ( each < 12 && *end != '\0' && *end != '\n');
}
}
return 0;
}

Copy a file's contents while ignoring characters between < and > in Java

I'm looking to write a program that reads from a html file and copies the contents but it ignores the html tags without using replaceAll. Also the stripping of html tags must be done in a different method. The file looks like this :
<html>
<head>
<title>My web page</title>
</head>
<body>
<p>There are many pictures of my cat here,
as well as my <b>very cool</b> blog page,
which contains <font color="red">awesome
stuff about my trip to Vegas.</p>
Here's my cat now:<img src="cat.jpg">
</body>
</html>
And I'd like my program to display the following:
My web page
There are many pictures of my cat here,
as well as my very cool blog page,
which contains awesome
stuff about my trip to Vegas.
Here's my cat now:
public static void main(String[] args) {
String html = " <html>\n"
+ " <head>\n"
+ " <title>My web page</title>\n"
+ " </head>\n"
+ " <body>\n"
+ " <p>There are many pictures of my cat here,\n"
+ " as well as my <b>very cool</b> blog page,\n"
+ " which contains <font color=\"red\">awesome\n"
+ " stuff about my trip to Vegas.</p>\n"
+ "\n"
+ "\n"
+ " Here's my cat now:<img src=\"cat.jpg\">\n"
+ " </body>\n"
+ " </html>";
boolean inTag = false;
StringBuilder finalString = new StringBuilder();
int length = html.length();
for (int i = 0; i < length; i++) {
char c = html.charAt(i);
if ('<' == c) {
inTag = true;
} else if ('>' == c) {
inTag = false;
} else if (!inTag) {
finalString.append(c);
}
}
System.out.print(finalString);
}

Resources