How do I get headers from a LightTPD CGI app? - c

I have this simple CGI script (which I compile):
#include <stdio.h>
int main(int argc, char *argv[]) {
printf("Content-Type: text/plain\n\nHello world!\n");
for(register unsigned short i=argc; i>0;) {
--i; printf("argv[%d]=%s ", i, argv[i]);
}
}
But I can't figure out how to get any of the header information.
Here are the differences I've made to my default lighttpd.conf:
server.modules = ("mod_access", "mod_accesslog", "mod_alias",
"mod_cgi", "mod_compress", "mod_status", )
server.port = 8000
#### CGI module
$HTTP["url"] =~ "/cgi-bin/" {
cgi.assign = ( "" => "" )
}
cgi.assign = ( ".cgi" => "")
How do I get header information and arguments?
BTW: Is this the most efficient way of serving compiled C code?

Both #Stefan's links are broken, so decided to write the answer I found from research:
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("Content-Type: text/plain\n\nHello world!\n");
const char *method_str = getenv("REQUEST_METHOD");
for(register unsigned short i=argc; i>0;) {
--i; printf("argv[%d]=%s ", i, argv[i]);
}
printf("REQUEST_METHOD = %s", method_str);
}

Just read how CGI works. FastCGI is a variant that keeps the backend process running for multiple requests and doesn't involve forking on every request. There are many similar protocols (SCGI, uwsgi, ...).

Related

WordNet functions fail for non-base forms of words

I'm using the C API for WordNet. When I try the following code with the word "dog", it correctly tells me that "dog" is a noun. However, if I pass "dogs", it returns 0, indicating that the word is not in the database.
#include <stdio.h>
#include "../lib/wn.h"
int main(int argc, char *argv[]) {
unsigned rc;
if (wninit() == -1) {
perror("wninit() failed");
return 1;
}
rc = in_wn(argv[1], NOUN); // "dog" okay, "dogs" not okay.
printf("rc: %u\n", rc);
return 0;
}
I have set the WNSEARCHDIR correctly to the location of the database files.

fuse parsing custom arguments in C

Using libfuse in my c-project, I 'm trying to add custom command-line arguments and handle them.
Here is an example on which I rely
https://github.com/libfuse/libfuse/wiki/Option-Parsing
First, I tried to do the argument for the mount point configuration -с <pathtoconfig>
I tried many ways to describe an option like -c --config conf= -o conf=, but ineffectually
Please, help me find the right path to solve the problem :(
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <fuse.h>
#include "fuu_walk.h"
#include "jsmnload.h"
#define _JSMN_TOKEN_SIZE_ 256
#define _JSMN_BUFFER_SIZE_ 4096
#define MYFS_OPT(t, p, v) { t, offsetof(struct myfs_config, p), v }
struct myfs_config {
char *mystring;
} conf;
static struct fuse_opt myfs_opts[] = {
MYFS_OPT("-c %s", mystring, 1),
FUSE_OPT_END
};
jsmntok_t t[_JSMN_TOKEN_SIZE_];
char buf[_JSMN_BUFFER_SIZE_];
#if 0
= ""
"{\"root\": ["
"{\"path\":\"/\", \"mode\":\"drw-------\"},"
"{\"path\":\"/12ABC345DE67\", \"mode\":\"drw-------\"},"
"{\"path\":\"/12ABC345DE67/_XQ01\", \"mode\":\"-rw-------\"},"
"{\"path\":\"/12ABC345DE67/_XQ02\", \"mode\":\"-rw-------\"},"
"{\"path\":\"/12ABC345DE78\", \"mode\":\"drw-------\"},"
"{\"path\":\"/12ABC345DE89\", \"mode\":\"drw-------\"}"
"]}";
#endif
static int myfs_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs)
{
struct myfs_config *ptr = (struct myfs_config *)data;
FILE *conf;
int rc = 0;
//I wanna check the argument on the each iteration of fuse_opt_parse. It's just the debug printf
printf("arg = %s\t string %s\t key = %i\n", arg, ptr->mystring, key);
switch (key) {
case 1:
conf = fopen(ptr->mystring, "r");
rc = read(fileno(conf), buf, _JSMN_BUFFER_SIZE_);
if ( jsmnload(buf, t, _JSMN_TOKEN_SIZE_, fuu_mkfstree) < 0 ) {
printf("Error load configuration\n");
exit(-1);
}
}
return 1;
}
int main(int argc, char *argv[])
{
struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
memset(&conf, 0, sizeof(conf));
fuse_opt_parse(&args, &conf, myfs_opts, myfs_opt_proc);
return fuu_main(args.argc, args.argv);
}
Launch example
./appendix/fuu /mnt/cdrom/ -c /mnt/fs.json
As a result, printf in myfs_opt_proc function works only once and outputs
arg = /mnt/cdrom/ string (null) key = -2
Why myfs_opt_proc does not work for option -c?
I cannot comment so as an answer... looking at the reference you provided it seems to me that there is no option starting with -c. So result seems correct because fuse cannot parse this. Look at this snippet from your link:
fuse_opt_add_arg(&args, "-omodules=subdir,subdir=/foo");
You may try to announce options to fuse using -o.
Edit: Youre example differs from the linked one, try to add to following line to the defined struct:
FUSE_OPT_KEY("-c", "KEY_CONFIG");
and some line before
emum {
KEY_CONFIG
};
and parse it like this in youre myfs_opt_proc function
switch (key) {
case KEY_CONFIG:
/* ... */
. Summed up you missed declaring the -c key.

creating multiple recursive directories in c

I am completing cs50x (the edX (free) version of the Harvard cs50) course and am trying to be a bit tricky/lazy/test myself.
I am trying to use a C program to create all the directories I will need for my psets.
I have looked online and found that <sys/stat.h> includes the mkdir() function and therefore tried creating some nested loops to create all the necessary folders by doing something similar to mkdir {pset1,pset1/{standard,hacker},pset2,pset2{standard... to give me a directory structure like this:
pset1/Standard
pset1/Hacker
pset2/Standard
etc...
I came up with this:
#include <cs50.h>
#include <stdio.h>
#include <sys/stat.h>
int main(int argc, string argv[])
{
for(int i = 1; i <=8; i++)
{
string dir = argv[1];
sprintf(dir,"%s%i", argv[1], i);
mkdir(dir, 0777);
for(int j = 0; j<2; j++)
{
string subDir[] = {"Standard","Hacker"};
sprintf(dir,"%s%i/%s", argv[1], i, subDir[j]);
mkdir(dir, 0777);
}
}
}
However, the program only creates pset1 and completes, there are no subfolders, no pset2 etc.
Yes, you're being lazy since you seem to have very little knowledge of C, yet try to program in it. :)
C is not Python, there is no string interpolation/formatting operator. You have to call a function, specificially snprintf(). Read that manual page.
Also, you can't create a bunch of nested directories with a single call to mkdir(). Read the manual page.
To create nested directories, you're either going to have to build each's absolute path (i.e. each successive time you call mkdir() the path will be longer than the previous time), or actually enter each directory as you create it, and go from there.
To create a full path you can call mkdir() recursivly like this:
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int mkdirr(const char * path, const mode_t mode, const int fail_on_exist)
{
int result = 0;
char * dir = NULL;
do
{
if (NULL == path)
{
errno = EINVAL;
result = -1;
break;
}
if ((dir = strrchr(path, '/')))
{
*dir = '\0';
result = mkdirr(path, mode, fail_on_exist);
*dir = '/';
if (result)
{
break;
}
}
if (strlen(path))
{
if ((result = mkdir(path, mode)))
{
char s[PATH_MAX];
sprintf(s, "mkdir() failed for '%s'", path);
perror(s);
if ((EEXIST == result) && (0 == fail_on_exist))
{
result = 0;
}
else
{
break;
}
}
}
} while (0);
return result;
}
And then call mkdirr() like this;
int main(void)
{
char p[] = "test/1/2/3";
if (-1 == mkdirr(p, 0777, 0))
{
perror("mkdirr() failed()");
}
return 0;
}

Use of execle with wget command

I have edited my previous question.
As I had got the problem and the changed the code, now I have a different problem. If I use execle command, it only downloads one image using the wget command, otherwise it prints all the image names on the screen if the wget command does not execute. I do not understand when there is a while loop, then why does it only print one image.
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<limits.h>
#include<fcntl.h>
#include<sys/stat.h>
#include<sys/types.h>
#include<stdio.h>
void main(int argc, char*argv[])
{
int iFlag;
char cline[100];
FILE*fil = fopen("index.html","rt");
if(fil==NULL)
{
printf("Error in opening file");
}
char*tmpLine;
char*tok;
const char check[10] = "<img";
const char check2[10] = "src=";
char images[50];
strcpy(images,argv[1]);
while(fgets(cline,100,fil)!=NULL)
{
if(strstr(cline,check)!=NULL)
{
tmpLine=strstr(cline,check);
if(strstr(cline,check2)!=NULL)
{
tmpLine=strstr(cline,check2);
tok = strtok(tmpLine,"\"");
while(tok!=NULL)
{
tok = strtok(NULL,"\"");
if(tok[0]!='/')
{
strcat(images,"/");
strcat(images,tok);
printf("\nimage: %s\n",images);
iFlag = execle("/usr/bin/wget","wget","-o","logfile",images,NULL);
if(iFlag<0)
perror("EXECLE ERROR");
break;
}
else
break;
}
memset(&images[0], 50, sizeof(images));
strcpy(images,argv[1]);
}
}
}
}
A big problem is that the exec family of function replaces your process with that of the new program. That means that if the call to execle succeeds your program no longer exists.
You need to fork a new process if you want your own program to continue.

Expanding on a *, using glob

I'm trying to expand *, so I've done some research and it seems that glob is the function to use. Just like linux when you type ls *.c, it will return you all the files that contains .c
I've got myself to start so I know that I need to malloc glob_t first, so here it is:
glob_t *globbuf = (glob_t*)malloc(sizeof(glob_t));
After this, I'm not sure how to work this out... going through internet has shown me some examples, but I don't get quite how it works. This is what I figured out:
if(glob("*.c",GLOB_DOOFFS,NULL,globbuf)) {
// what am i supposed to write in here?}
globbuf->gl_pathv[0] = "ls";
Here's a simple, straight-forward example that Works As Expected:
#include <glob.h>
#include <stdio.h>
int foo(char const * epath, int eerrno) { return 0; }
int main()
{
glob_t globbuf = {0};
glob("*.c", GLOB_DOOFFS, foo, &globbuf);
for (size_t i = 0; i != globbuf.gl_pathc; ++i)
{
printf("Found: %s\n", globbuf.gl_pathv[i]);
}
globfree(&globbuf);
}

Resources