Is it possible to get list of files in directory using apache portable runtime? - apache

I need to get list of files in directory using APR. How can I do it?
I was looking for answer in documentation, but found nothing.
Thanks!

The function you want is apr_dir_open. I found the header files to be the best documentation for APR
http://apr.apache.org/docs/apr/1.4/group_apr_dir.html
Here is an example for reading "." and reporting errors if any were encountered
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <apr.h>
#include <apr_errno.h>
#include <apr_pools.h>
#include <apr_file_info.h>
static void apr_fatal(apr_status_t rv);
int main(void)
{
apr_pool_t *pool;
apr_status_t rv;
// Initialize APR and pool
apr_initialize();
if ((rv = apr_pool_create(&pool, NULL)) != APR_SUCCESS) {
apr_fatal(rv);
}
// Open the directory
apr_dir_t *dir;
if ((rv = apr_dir_open(&dir, ".", pool)) != APR_SUCCESS) {
apr_fatal(rv);
}
// Read the directory
apr_finfo_t finfo;
apr_int32_t wanted = APR_FINFO_NAME | APR_FINFO_SIZE;
while ((rv = apr_dir_read(&finfo, wanted, dir)) == APR_SUCCESS) {
printf("%s\t%10"PRIu64"\n", finfo.name, (uint64_t)finfo.size);
}
if (!APR_STATUS_IS_ENOENT(rv)) {
apr_fatal(rv);
}
// Clean up
apr_dir_close(dir);
apr_pool_destroy(pool);
apr_terminate();
return 0;
}
static void apr_fatal(apr_status_t rv)
{
const int bufsize = 1000;
char buf[bufsize+1];
printf("APR Error %d: %s\n", rv, apr_strerror(rv, buf, bufsize));
exit(1);
}

Related

Integrate boost-asio with file descriptor based socket api from KDB+

I'm relatively new to boost-asio and I'm wondering if it's possible to make it work with KDB+ api here.
I tried something like the below but it doesn't seem to work properly,
#include <iostream>
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#define KXVER 3
#include "kx/k.h"
using boost::asio::ip::tcp;
namespace posix = boost::asio::posix;
class Feedhandler
{
public:
Feedhandler(boost::asio::io_service &io_service) : m_qsvc(io_service) {
char host[] = "localhost";
int port = 6812;
m_fd = khpu(host, port, "user:pass");
m_qsvc.assign(m_fd);
start_operations();
K ret = k(m_fd, ".u.sub", ks(""), ks(""), (K)0);
}
void start_operations()
{
boost::asio::async_read(m_qsvc, boost::asio::null_buffers(),
boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
void handle_read(const boost::system::error_code& error, size_t size)
{
K data = k(m_fd,(S)0);
start_operations();
}
private:
int m_fd;
posix::stream_descriptor m_qsvc;
};
int main(int argc, char* argv[])
{
boost::asio::io_service io_service;
Feedhandler fh(io_service);
io_service.run();
return 0;
}
The handle_read method gets hit once and then subsequently there's no more call-backs.
Actually, it's better to use async_wait instead of async_read, like below,
m_qsvc.async_wait(boost::asio::posix::stream_descriptor::wait_read,
boost::bind(&Feedhandler::handle_read, this, boost::asio::placeholders::error) );

How can I stop the program inside the a parent or a child process?

I have this piece of code that I developed just to address a problem that I have in another large program that I am developing.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <limits.h>
#include <string>
#include <iostream>
using namespace std;
void processLine (char []);
void readLine(char []);
const int LIMIT = 512;
int main(int argc, char *argv[])
{
char oneLine[LINE_MAX];
readLine(oneLine);
return 0;
}
void readLine(char line[])
{
processLine(line);
//Otherstuff
------------
}
void processLine(char line[])
{
pid_t process;
int child_status;
string input;
cout << "Input: ";
cin >> input;
process = fork();
if(process == 0)
{ // do nothing
}
else
{
//parent
if(input == "quit")
{
printf("Quit command found ! \nExiting ");
for(int i = 0;i < 3;i++)
{
printf(".");
fflush(stdout);
sleep(1);
}
printf("\n");
exit(0);
}
else
{
wait(&child_status);
}
}
}
My goal is simple, When the user enter quit.
I will just display
Quit command found
Exiting ...
And there is a delay of one second between each of these three dots.
However the output that I get is
Quit command found
Exiting . other stuff ..
However, what seems to happen is that the parent process returns and then executes other stuff from the calling function before it continues to print the other two dots. How would I avoid the parent process from doing that ?
Use waitpid() like this:
pid_t childPid;
childPid = fork();
...
int returnStatus;
waitpid(childPid, &returnStatus, 0); // Parent process waits here for child to terminate.
Use it here
if(childPid == 0) // fork succeeded
{
// Do something
exit(0);
}
else // Main (parent) process after fork succeeds
{
int returnStatus;
waitpid(childPid, &returnStatus, 0);
}

Apache 2 loadable module fails to parse directive

I have an Apache 2.2 loadable module which is not handling directive processing correctly.
The module originally used a static configuration but now uses per-server allocation using a server configuration routine declared in the AP_MODULE_DECLARE_DATA. I've confirmed that the operational routines are mapping the configuration data correctly.
Everything works correctly when there is no TD_LOGDEBUG directive in the httpd.conf.
When there is a TD_LOGDEBUG directive, on entry to the "static const char *logdebug_cfg", it appears that the module config pointer "mconfig" in the call is null. If the pointer is taken as valid, the module segfaults at server start time. Debugging has been difficult due to the lack of server or request context at this point to produce Apache log messages.
Adding a conditional "if (scfg) {" around the directive parsing code (as seen at the Apache modules site) eliminates the segfault but it also apparently stops the parsing and storage from occurring. At runtime I see in the log:
mod_demotest: demotest - logdebug = 0x00078000
which is the value inserted at server configuration, rather than the expected 0x00000003 due to the "TD_LOGDEBUG 0x3" directive in httpd.conf
Again, this was all working code in the static-configuration original. The only mods to the code were for per-server configuration.
The code below has been cut down from the original module to the minimum which shows the problem.
I'd be grateful if anyone can offer insight into the issue.
#include "httpd.h"
#include "http_config.h"
#include "http_request.h"
#include "http_protocol.h"
#include "http_core.h"
#include "http_main.h"
#include "http_log.h"
#include "ap_mpm.h"
#include "apr_strings.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netdb.h>
#define MODULE_NAME "mod_demotest"
#define MODULE_VERSION "2.0.1" /* Module revision level */
module AP_MODULE_DECLARE_DATA demotest_module;
static int demotest_handler(request_rec *r);
static int demotest_post_config(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s);
typedef struct {
unsigned long logdebug;
} mod_config;
static void str_to_lower(char *string) {
while (*string) {
if ( (*string >= 'A') && (*string <= 'Z') ) *string = *string + 32;
string++;
}
}
unsigned long htoi(char *ptr) {
unsigned long value = 0;
char ch = *ptr;
str_to_lower(ptr);
while ( (ch == '0') || (ch == 'x') ) ch = *(++ptr);
while ( ( (ch >= '0') && (ch <= '9') ) || ( (ch >= 'a') && (ch <= 'f') ) ) {
if (ch >= '0' && ch <= '9')
value = (value << 4) + (ch - '0');
if (ch >= 'a' && ch <= 'f')
value = (value << 4) + (ch - 'a' + 10);
ch = *(++ptr);
}
return value;
}
static int demotest_handler
(request_rec *r) {
mod_config *scfg = ap_get_module_config(r->server->module_config,
&demotest_module);
ap_log_rerror(APLOG_MARK, APLOG_CRIT, 0, r,
"mod_demotest: demotest - logdebug = 0x%08x",
scfg->logdebug);
return DECLINED;
}
static const char *logdebug_cfg
(cmd_parms *parms, void *mconfig, const char *arg) {
mod_config *scfg = (mod_config *)mconfig;
if (scfg) {
scfg->logdebug = htoi((char *)arg);
}
return NULL;
}
static void *demotest_server_config
(apr_pool_t *p, server_rec *s) {
mod_config *scfg;
scfg = apr_palloc(p, sizeof(*scfg));
scfg->logdebug = 0x78000;
return (void *)scfg;
}
static int demotest_post_config
(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *s) {
const char *userdata_key = "demotest_init";
void *data = NULL;
apr_pool_userdata_get(&data, userdata_key, s->process->pool);
if (data == NULL) {
apr_pool_userdata_set((const void *)1, userdata_key,
apr_pool_cleanup_null, s->process->pool);
return OK;
}
ap_log_error(APLOG_MARK, APLOG_CRIT, 0, s,
MODULE_NAME " " MODULE_VERSION " started");
return OK;
}
static void register_hooks(apr_pool_t *p) {
ap_hook_post_config(demotest_post_config, NULL, NULL, APR_HOOK_MIDDLE);
ap_hook_access_checker(demotest_handler, NULL, NULL, APR_HOOK_MIDDLE);
}
static command_rec demotest_directives[] = {
AP_INIT_TAKE1("TD_LogDebug", logdebug_cfg, NULL, RSRC_CONF,
"Log internal trace/debug info. Default: 0x0000 = none"),
{NULL}
};
module AP_MODULE_DECLARE_DATA demotest_module = {
STANDARD20_MODULE_STUFF,
NULL, /* create per-dir config structures */
NULL, /* merge per-dir config structures */
demotest_server_config, /* create per-server config structures */
NULL, /* merge per-server config structures */
demotest_directives, /* table of config file commands */
register_hooks
};
Problem solved. The Apache Project example for this situation is strikingly incorrect. mconfig is not a pointer to the module configuration; it is always NULL at the call.
The resolution is shown below.
static const char *logdebug_cfg
(cmd_parms *parms, void *mconfig, const char *arg) {
/* Retrieve the per-server configuration */
mod_config *scfg = ap_get_module_config(parms->server->module_config, &torcheck_module);
scfg->logdebug = htoi((char *)arg);
return NULL;

read multiple files with quite similar names c++

I am reading a file from current directory
ifstream myfile;
myfile.open("version1.1.hex");
Now a situation is arising that if user updates version then there will be version1.2.hex or version1.3.hex ..so on in the current directory, but one file at a time will be present. I want to write a code now which will cater this future need of reading different file.
I'm writing this code in C++/CLI.
Since file listings are a bit environment-dependant I am not sure if this is helpful to you,
but here is an example how to achieve your goal under the mircosoft regime.
What is needed is the FindFirstFile / FindNextFile calls which query all files matching the fileSearchKey. Then you can use the cFileName part of WIN32_FIND_DATAA as parameter to your open command
string fileSearchKey = "version*";
WIN32_FIND_DATAA fd;
bool bFirstRun = true;
bool bFinishedRun = false;
HANDLE h = INVALID_HANDLE_VALUE;
while (!bFinishedRun)
{
if (bFirstRun)
{
h = FindFirstFileA(fileSearchKey.c_str(), &fd);
bFirstRun = false;
} else
{
if (FindNextFileA(h, &fd) != FALSE)
{
// Abort with error because it has more than one file or decide for the most recent version
} else
{
bFinishedRun = true;
}
}
}
// Load file
ifstream myfile;
myfile.open(fd.cFileName);
This code will look in the directory and take the first file, then quit.
WARNING : this will work only on linux
#include <iostream>
#include <string>
#include <vector>
#include <stdio.h>
#include <cstring>
#include <sys/types.h>
#include <dirent.h>
#include <sys/stat.h>
#include <unistd.h>
using namespace std;
int main ()
{
char n[20];
unsigned char isFolder = 0x4;
unsigned char isFile = 0x8;
DIR *dir;
struct dirent *ent;
dir = opendir ("./");
if (dir != NULL) {
/* print all the files and directories within directory */
while ((ent = readdir (dir)) != NULL) {
//folder sign
if(ent->d_type != isFolder && string(ent->d_name).find("version") != string::npos)
{
cout <<ent->d_name <<"\n";
// Your code
break;
}
}
closedir (dir);
} else {
/* could not open directory */
perror ("");
return 0;
}
cout << "=========" << endl;
}
In C++/CLI you should use the .net framework libraries for this. For instance you can use Directory::GetFiles.
using namespace System;
using namespace System::IO;
int main(array<System::String ^> ^args)
{
array<String^>^dirs = Directory::GetFiles(".", "version1.*.hex");
Collections::IEnumerator^ myEnum = dirs->GetEnumerator();
while (myEnum->MoveNext())
{
Console::WriteLine(myEnum->Current);
}
return 0;
}

simple linux device driver open call crash

I am trying to learn how to write a device driver in linux, following some reference from google and ldd3. i am able to insert the module below but when i tried to open the device in an application the kernel crashed.
The code and build steps followed as below :
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
#include <linux/ioport.h>
#include <asm/io.h>
#include <linux/interrupt.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <asm/uaccess.h>
#include <asm/irq.h>
#include <asm/param.h>
#include <linux/fs.h>
/* =============== Constant Definitions ============ */
#define SERIAL_IRQ 4
/* =============== Variable Definitions ============ */
static int SER_MAJOR = 0;
int ser_open(struct inode *inode, struct file *filp);
int ser_release(struct inode *inode, struct file *filp);
irqreturn_t my_ser_dev_isr(int irq,void *ser_data,struct pt_regs * pt_reg_var)
{
printk("\n\n ------- INTR raised -----------\n\n");
return 0;
}
int ser_open(struct inode *inode, struct file *filp)
{
if(request_irq(SERIAL_IRQ,&my_ser_dev_isr,1,"my_ser_dev_intr",NULL))
{
printk("\n interrupt req failed\n");
}
else
{
enable_irq(SERIAL_IRQ);
printk("\n!!!! ..obtained the requested interrupt and enabled\n");
}
}
int ser_release(struct inode *inode, struct file *filp)
{
disable_irq(SERIAL_IRQ);
free_irq(SERIAL_IRQ,NULL) ;
}
static struct file_operations ser_fops = {
open: ser_open,
release: ser_release
};
void *p = NULL;
irqreturn_t my_ser_dev_isr (int, void *, struct pt_regs *);
static int __init hello_start(void)
{
int ret_val=-1;
int result;
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
result = register_chrdev(SER_MAJOR,"SER_DEV",&ser_fops);
if(result < 0)
{
printk(KERN_WARNING"Can't get major %d\n",SER_MAJOR);
return result;
}
if(SER_MAJOR == 0)
{
SER_MAJOR = result;
printk("SER DEV Major Number : %d",SER_MAJOR );
}
return 0;
}
static void __exit hello_end(void)
{
// free_irq(SERIAL_IRQ,NULL);
//release_region(0x0031,1);
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile for module :
obj-m := hello.o
default:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
The application used for accesing is as follows :
#include <stdio.h> /* test.c */
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
static int dev;
int main(void)
{
char buff[40];
dev = open("/dev/my_ser_dev",O_RDONLY);
if(dev < 0)
{
printf( "Device Open ERROR!\n");
exit(1);
}
printf("Please push the GPIO_16 port!\n");
//read(dev,buff,40);
// scanf("%s",buff);
printf("%s\n",buff);
close(dev);
return 0;
}
insmod gave
[ 3837.312140] Loading hello module...
[ 3837.312147] Hello world
[ 3837.312218] SER DEV Major Number : 251
Then I created the special file using mknod /dev/my_ser_dev c 251 0
Executing the application caused kernel crash. I am using UBUNTU 3.2.0-23-generic-pae.
The function you are registering as your IRQ handler has the wrong prototype - it should be like
irqreturn_t irq_handler(int, void *);
Maybe you are referring to old documentation.