I want to implement a simple "cat file1 > file1" command in a C program. I have tried the following, but it does not work...
main () {
pid_t pid;
FILE *ip, *op;
char *args[3];
printf("Name of the executable program\n\t");
scanf("%s", &name[0]); // I entered cat here
printf("Name of the input file\n\t");
scanf("%s", &name[1]); //file1.txt
printf("Name of the output file\n\t");
scanf("%s", &name[0]); //file2.txt
pid = fork();
if(pid == -1)
perror("fork() error");
else if(pid > 0)
waitpid(-1, NULL, 0);
else if (pid == 0) {
op = fopen(name[2], "w");
close(1);
dup(op);
execlp(name[0], name[1], NULL);
}
return 0;
}// end of main()
I thought the execlp() will run cat file1.txt and its output will be redirected to file2.txt, but it's not and I don't know why. How do I do it?
scanf("%s", &name[0]); // I entered cat here
printf("Name of the input file\n\t");
scanf("%s", &name[1]); //file1.txt
printf("Name of the output file\n\t");
scanf("%s", &name[0]); //file2.txt
Clearly not a C&P of actual code - name should be args, and the last one should be "2" instead of 0.
Also, dup works on file descriptors, not FILE*, so need to look at open rather than fopen, or whatever method gets the fd from a FILE*
The first argument to execlp() is the name to be looked up; the second and following arguments are the argv list, starting with argv[0].
int execlp(const char *file, const char *arg0, ... /*, (char *)0 */);
For shell I/O redirection, it is easier to open files with open() than to use standard I/O (<stdio.h> and FILE *); you should also close the file you opened after the dup(), though it is easier to use dup2(). You need to allocate space to read the strings into; on many systems, the original code would crash because the pointers in str don't point anywhere. You should normally aim to exit with status 0 only if everything worked; otherwise, exit with a non-zero exit status.
This leads to:
#include <fcntl.h> /* open() */
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h> /* waitpid() */
#include <unistd.h> /* execlp(), fork(), dup2() */
int main(void)
{
pid_t pid;
pid_t corpse;
int status;
char name[3][50];
printf("Name of the executable program\n\t");
if (scanf("%49s", name[0]) != 1)
return(EXIT_FAILURE);
printf("Name of the input file\n\t");
if (scanf("%49s", name[1]) != 1)
return(EXIT_FAILURE);
printf("Name of the output file\n\t");
if (scanf("%49s", name[2]) != 1)
return(EXIT_FAILURE);
pid = fork();
if (pid == -1)
{
perror("fork() error");
return(EXIT_FAILURE);
}
else if (pid > 0)
corpse = waitpid(-1, &status, 0);
else
{
int fd = open(name[2], O_WRONLY|O_CREAT|O_EXCL, 0644);
if (fd < 0)
{
fprintf(stderr, "Failed to open %s for writing\n", name[2]);
return(EXIT_FAILURE);
}
dup2(fd, 1);
close(fd);
execlp(name[0], name[0], name[1], NULL);
fprintf(stderr, "Failed to exec %s\n", name[0]);
return(EXIT_FAILURE);
}
return(corpse == pid && status == 0 ? EXIT_SUCCESS : EXIT_FAILURE);
}
You have to either use fork() a process and reassign it's file descriptors to previously(manually) open()'ed file, or use system() call to make shell handle it for you.
Related
using Linux (ubuntu 20.04) machine, openssl 3.0.7 is installed , running a sample code for signing.
we followed below procedure for signing. getting segmentation fault in EVP_DigestFinal_ex.
segmentation fault is happening due to mdctx->algctx=0x0. while debugging the code mdctx->algctx is updated in EVP_DigestInit_ex but latter it was freed in EVP_DigestSignInit. not sure what we are missing and how to update mdctx->algctx to avoid the crash.
#include <stdio.h>
#include <string.h>
#include <openssl/evp.h>
#include <openssl/provider.h>
EVP_PKEY *pkey = NULL;
generate_key(){
EVP_PKEY_CTX *ctx=NULL;
pkey=EVP_PKEY_new();
ctx=EVP_PKEY_CTX_new(pkey,NULL);
ctx = EVP_PKEY_CTX_new_id(EVP_PKEY_RSA, NULL);
if (!ctx)
printf(" key gen failed");
if (EVP_PKEY_keygen_init(ctx) <= 0)
printf(" key gen failed");
if (EVP_PKEY_CTX_set_rsa_keygen_bits(ctx, 512) <= 0)
printf(" key gen failed");
/* Generate key */
if (EVP_PKEY_keygen(ctx, &pkey) <= 0)
printf(" key gen failed");
}
int main(int argc, char *argv[])
{
EVP_MD_CTX *mdctx;
const EVP_MD *m_md;
const EVP_MD *md;
EVP_PKEY *m_key;
EVP_PKEY *ed_pkey = NULL;
EVP_PKEY_CTX *ed_pctx = NULL;
// OSSL_PROVIDER *default;
size_t sign_len = 0;
u_int8_t m_sign_buf[2048];
int ret = 0;
char mess1[] = "Test Message\n";
char mess2[] = "Hello World\n";
unsigned char *outdigest = NULL;
unsigned int md_len = 0, i;
printf("args : %s\n",argv[1]);
//default = OSSL_PROVIDE_load(NULL, "default");
//md = EVP_get_digestbyname("SHA256");
//md = EVP_sha256();
md = EVP_MD_fetch(NULL, "SHA256", NULL); //;
if (md == NULL) {
printf("Unknown message digest %s\n", argv[1]);
exit(1);
}
generate_key();
printf("value of md %s\n",md);
mdctx = EVP_MD_CTX_new();
if((EVP_DigestInit_ex(mdctx, md, NULL)) != 1)
printf("EVP_DigestInit_ex failed \n");
if((EVP_DigestSignInit(mdctx, NULL, md, NULL, pkey)) != 1)
printf("EVP_DigestSignInit failed \n");
if((EVP_DigestSignUpdate(mdctx, mess1, strlen(mess1))) != 1)
printf("EVP_DigestSignUpdate failed \n");
//EVP_DigestUpdate(mdctx, mess2, strlen(mess2));
if((EVP_DigestSignFinal(mdctx, (u_int8_t*)NULL, &sign_len)) != 1)
printf("EVP_DigestSignFinal failed \n");
if((EVP_DigestSignFinal(mdctx, m_sign_buf, &sign_len)) != 1)
printf("EVP_DigestSignFinal 2 failed \n");
/* Allocate the output buffer */
outdigest = OPENSSL_malloc(EVP_MD_get_size(md));
if (outdigest == NULL)
printf("outdigest failed \n");
if((EVP_DigestFinal_ex(mdctx, outdigest, &md_len)) != 1)
printf("EVP_DigestFinal_ex failed \n");
EVP_MD_CTX_free(mdctx);
/* Print out the digest result */
BIO_dump_fp(stdout, outdigest, &md_len);
exit(0);
}
`
```
Thanks,
while debugging the code mdctx->algctx is updated in EVP_DigestInit_ex but latter it was freed in EVP_DigestSignInit. not sure what we are missing and how to update mdctx->algctx to avoid the crash.
CRASH Info:
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7d99422 in SHA256_Final (md=0x5555555a88d0 "\250UUU\005", c=0x0)
at ../openssl-3.0.7/include/crypto/md32_common.h:194
194 size_t n = c->num;
(gdb) bt
#0 0x00007ffff7d99422 in SHA256_Final (md=0x5555555a88d0 "\250UUU\005", c=0x0)
at ../openssl-3.0.7/include/crypto/md32_common.h:194
#1 0x00007ffff7e2628c in sha256_internal_final (ctx=0x0, out=0x5555555a88d0 "\250UUU\005", outl=0x7fffffffda98,
outsz=32) at ../openssl-3.0.7/providers/implementations/digests/sha2_prov.c:72
#2 0x00007ffff7cbadf6 in EVP_DigestFinal_ex (ctx=0x555555580d80, md=0x5555555a88d0 "\250UUU\005",
isize=0x7fffffffdad8) at ../openssl-3.0.7/crypto/evp/digest.c:446
#3 0x000055555555575f in main (argc=1, argv=0x7fffffffe458) at test2.c:90
I am new into using snort and I don't know how to properly create rules.
I want someone to explain me how to create a rule for detection of a specific content. For example: I want to generate an alert when I search on Google the word 'terrorism'.
I tried to create the rule with what I've seen on Youtube or Google, as examples, but none of them works and I don't know what to try anymore. For instance, I am using Snort 2.9.9
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"terrorism content found"; content:"terrorism"; nocase; sid:1000000;)
I don't have any errors from the local.rules file, but I got the line 'include $RULE_PATH/snort.rules' commented because of some problems with PulledPork.
I expect to have an alert in the CLI, but there is no output.
I know that this is already too late but here's the answer for future reference.
The packets are probably being sent using HTTPS connection (which is why they are encrypted).
This might be a reason why there are no alerts.
Please refer here for a detailed explanation.
rules are ready, u just replace, alert with sdrop:
find /home/www \( -type d -name .git -prune \) -o -type f -print0 | xargs -0 sed -i 's/subdomainA\.example\.com/subdomainB.example.com/g'
and you can use include in config file
O.K
Answer is here: http://manpages.ubuntu.com/manpages/xenial/man8/u2spewfoo.8.html
Download Snort source, Make logs costume, write ur code to get log stream in control
Then Build source and run
Be successful :)
It is possible to send alert messages and some packet relevant data
from snort through a unix socket, to perform additional separate
processing of alert data.
Snort has to be built with spo_unsock.c/h output plugin is built in and
-A unsock (or its equivalent through the config file) is
used. The unix socket file should be created in /dev/snort_alert. Your
‘client’ code should act as ‘server’ listening to this unix socket.
Snort will be sending you Alertpkt structures which contain alert
message, event id. Original datagram, libpcap pkthdr, and offsets to
datalink, netlayer, and transport layer headers.
Below is an example how unix sockets could be used. If you have any
comments bug reports, and feature requests, please contact
snort-devel#lists.sourceforge.net or drop me an email to fygrave at
tigerteam dot net.
-Fyodor
[for copyright notice, see snort distribution code]
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/un.h>
#include
#include "snort.h"
int sockfd;
void
sig_term (int sig)
{
printf (“Exiting!\n”);
close (sockfd);
unlink (UNSOCK_FILE);
exit (1);
}
int
main (void)
{
struct sockaddr_un snortaddr;
struct sockaddr_un bogus;
Alertpkt alert;
Packet *p;
int recv;
socklen_t len = sizeof (struct sockaddr_un);
if ((sockfd = socket (AF_UNIX, SOCK_DGRAM, 0)) < 0)
{
perror (“socket”);
exit (1);
}
bzero (&snortaddr, sizeof (snortaddr));
snortaddr.sun_family = AF_UNIX;
strcpy (snortaddr.sun_path, UNSOCK_FILE);
if (bind (sockfd, (struct sockaddr *) &snortaddr, sizeof (snortaddr)) < 0)
{
perror (“bind”);
exit (1);
}
signal(SIGINT, sig_term);
while ((recv = recvfrom (sockfd, (void *) &alert, sizeof (alert),
0, (struct sockaddr *) &bogus, &len)) > 0)
{
/* do validation of recv if you care */
if (!(alert.val & NOPACKET_STRUCT))
{
if ((p = calloc (1, sizeof (Packet))) == NULL)
{
perror ("calloc");
exit (1);
}
p->pkt = alert.pkt;
p->pkth = &alert.pkth;
if (alert.dlthdr)
p->eh = (EtherHdr *) (alert.pkt + alert.dlthdr);
if (alert.nethdr)
{
p->iph = (IPHdr *) (alert.pkt + alert.nethdr);
if (alert.transhdr)
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
p->tcph = (TCPHdr *) (alert.pkt + alert.transhdr);
break;
case IPPROTO_UDP:
p->udph = (UDPHdr *) (alert.pkt + alert.transhdr);
break;
case IPPROTO_ICMP:
p->icmph = (ICMPHdr *) (alert.pkt + alert.transhdr);
break;
default:
printf ("My, that's interesting.\n");
} /* case */
} /* thanshdr */
} /* nethdr */
if (alert.data)
p->data = alert.pkt + alert.data;
/* now do whatever you want with these packet structures */
} /* if (!NOPACKET_STRUCT) */
printf ("%s [%d]\n", alert.alertmsg, alert.event.event_id);
if (!(alert.val & NOPACKET_STRUCT))
if (p->iph && (p->tcph || p->udph || p->icmph))
{
switch (p->iph->ip_proto)
{
case IPPROTO_TCP:
printf ("TCP from: %s:%d ",
inet_ntoa (p->iph->ip_src),
ntohs (p->tcph->th_sport));
printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst),
ntohs (p->tcph->th_dport));
break;
case IPPROTO_UDP:
printf ("UDP from: %s:%d ",
inet_ntoa (p->iph->ip_src),
ntohs (p->udph->uh_sport));
printf ("to: %s:%d\n", inet_ntoa (p->iph->ip_dst),
ntohs (p->udph->uh_dport));
break;
case IPPROTO_ICMP:
printf ("ICMP type: %d code: %d from: %s ",
p->icmph->type,
p->icmph->code, inet_ntoa (p->iph->ip_src));
printf ("to: %s\n", inet_ntoa (p->iph->ip_dst));
break;
}
}
}
perror (“recvfrom”);
close (sockfd);
unlink (UNSOCK_FILE);
return 0;
}
I am writing c++ code (but my example is straight c) to talk to an AdaFruit Servo Motor Pi Hat, which uses the I2C bus to communicate with the Pi. I'm having a problem when trying to use the ioctl I2C_RDWR mechanism. I am getting a 'Bad Address' status back from the call. It doesn't matter what address I give it (the hat answers to 0x40, though), it always fails. I've boiled the code down into a short module, which is self contained. This is my first post to this site, so if I've done any faux pas, please forgive me.
When I run the attached code, I get the following response:
I2C_FUNC_I2C OK
I2C_FUNC_10BIT_ADDR
I2C_FUNC_PROTOCOL_MANGLING
I2C_FUNC_SMBUS_QUICK OK
I2C_FUNC_SMBUS_READ_BYTE OK
I2C_FUNC_SMBUS_WRITE_BYTE OK
I2C_FUNC_SMBUS_READ_BYTE_DATA OK
I2C_FUNC_SMBUS_WRITE_BYTE_DATA OK
I2C_FUNC_SMBUS_READ_WORD_DATA OK
I2C_FUNC_SMBUS_WRITE_WORD_DATA OK
I2C_FUNC_SMBUS_PROC_CALL OK
I2C_FUNC_SMBUS_READ_BLOCK_DATA
I2C_FUNC_SMBUS_WRITE_BLOCK_DATA OK
I2C_FUNC_SMBUS_READ_I2C_BLOCK OK
I2C_FUNC_SMBUS_WRITE_I2C_BLOCK OK
Write failed: Bad address
My Pi is a model B, version 2. I have enabled the i2c system and can see the i2c device:
crw-rw-rw- 1 root i2c 89, 1 Aug 31 23:02 i2c-1
Any help would be appreciated.
The code follows:
#include <unistd.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/i2c-dev.h>
#include <linux/i2c.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
int main() {
int file;
int devAddr = 0x40;
int status;
uint32_t funcs;
uint8_t data = 0xAA;
struct i2c_rdwr_ioctl_data request;
struct i2c_msg ioctlMsg[1];
file = open("/dev/i2c-1", O_RDWR);
if(file < 0) {
perror("could not open device");
return 1;
}
status = ioctl(file, I2C_FUNCS, &funcs);
if(status < 0) {
perror("could not get funcs");
return 3;
}
fprintf(stderr, "\nI2C_FUNC_I2C ");
if ( I2C_FUNC_I2C & funcs) fprintf(stderr, "\t\t\t\tOK");
fprintf(stderr, "\nI2C_FUNC_10BIT_ADDR ");
if ( I2C_FUNC_10BIT_ADDR & funcs) fprintf(stderr, "\t\t\tOK");
fprintf(stderr, "\nI2C_FUNC_PROTOCOL_MANGLING ");
if ( I2C_FUNC_PROTOCOL_MANGLING & funcs) fprintf(stderr, "\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_QUICK ");
if ( I2C_FUNC_SMBUS_QUICK & funcs) fprintf(stderr, "\t\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_BYTE ");
if ( I2C_FUNC_SMBUS_READ_BYTE & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_BYTE ");
if ( I2C_FUNC_SMBUS_WRITE_BYTE & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_BYTE_DATA ");
if ( I2C_FUNC_SMBUS_READ_BYTE_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_BYTE_DATA ");
if ( I2C_FUNC_SMBUS_WRITE_BYTE_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_WORD_DATA ");
if ( I2C_FUNC_SMBUS_READ_WORD_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_WORD_DATA ");
if ( I2C_FUNC_SMBUS_WRITE_WORD_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_PROC_CALL ");
if ( I2C_FUNC_SMBUS_PROC_CALL & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_BLOCK_DATA ");
if ( I2C_FUNC_SMBUS_READ_BLOCK_DATA & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_BLOCK_DATA ");
if ( I2C_FUNC_SMBUS_WRITE_BLOCK_DATA & funcs) fprintf(stderr, "\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_READ_I2C_BLOCK ");
if ( I2C_FUNC_SMBUS_READ_I2C_BLOCK & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\nI2C_FUNC_SMBUS_WRITE_I2C_BLOCK ");
if ( I2C_FUNC_SMBUS_WRITE_I2C_BLOCK & funcs) fprintf(stderr, "\t\tOK");
fprintf(stderr, "\n");
memset(ioctlMsg, 0, sizeof(struct i2c_rdwr_ioctl_data) * 2);
ioctlMsg[0].addr = 0x0;
ioctlMsg[0].flags = 0; /* write command */
ioctlMsg[0].len = 1;
ioctlMsg[0].buf = &data;
request.msgs = ioctlMsg;
request.nmsgs = 1;
status = ioctl(file, I2C_RDWR, request);
if(status < 0) {
perror("Write failed");
return 2;
}
close(file);
return 0;
}
I found my problem, turns out that the 'bad address' wasn't referring to the address of the I2C device, but the address of the block being sent in the ioctl command. I had forgotten to pass the address, as opposed to the value of the parameter in my call to ioctl.
I have been writing a lcd kernel driver for a LCD module. All was going well, I can write to the display, create a /dev/lcd node that I can write into and it will display the results on the screen. I thought using the llseek fops callback to position the cursor on the lcd would be good, this way I could use rewind fseek etc. However it is not working as I expected, below is a summary of what I am seeing:
The relevant lines of code from the driver side are:
loff_t lcd_llseek(struct file *filp, loff_t off, int whence)
{
switch (whence) {
case 0: // SEEK_SET
if (off > 4*LINE_LENGTH || off < 0) {
printk(KERN_ERR "unsupported SEEK_SET offset %llx\n", off);
return -EINVAL;
}
lcd_gotoxy(&lcd, off, 0, WHENCE_ABS);
break;
case 1: // SEEK_CUR
if (off > 4*LINE_LENGTH || off < -4*LINE_LENGTH) {
printk(KERN_ERR "unsupported SEEK_CUR offset %llx\n", off);
return -EINVAL;
}
lcd_gotoxy(&lcd, off, 0, WHENCE_REL);
break;
case 2: // SEEK_END (not supported, hence fall though)
default:
// how did we get here !
printk(KERN_ERR "unsupported seek operation\n");
return -EINVAL;
}
filp->f_pos = lcd.pos;
printk(KERN_INFO "lcd_llseek complete\n");
return lcd.pos;
}
int lcd_open(struct inode *inode, struct file *filp)
{
if (!atomic_dec_and_test(&lcd_available)) {
atomic_inc(&lcd_available);
return -EBUSY; // already open
}
return 0;
}
static struct file_operations fops = {
.owner = THIS_MODULE,
.write = lcd_write,
.llseek = lcd_llseek,
.open = lcd_open,
.release = lcd_release,
};
int lcd_init(void)
{
...
// allocate a new dev number (this can be dynamic or
// static if passed in as a module param)
if (major) {
devno = MKDEV(major, 0);
ret = register_chrdev_region(devno, 1, MODULE_NAME);
} else {
ret = alloc_chrdev_region(&devno, 0, 1, MODULE_NAME);
major = MAJOR(devno);
}
if (ret < 0) {
printk(KERN_ERR "alloc_chrdev_region failed\n");
goto fail;
}
// create a dummy class for the lcd
cl = class_create(THIS_MODULE, "lcd");
if (IS_ERR(cl)) {
printk(KERN_ERR "class_simple_create for class lcd failed\n");
goto fail1;
}
// create cdev interface
cdev_init(&cdev, &fops);
cdev.owner = THIS_MODULE;
ret = cdev_add(&cdev, devno, 1);
if (ret) {
printk(KERN_ERR "cdev_add failed\n");
goto fail2;
}
// create /sys/lcd/fplcd/dev so udev will add our device to /dev/fplcd
device = device_create(cl, NULL, devno, NULL, "lcd");
if (IS_ERR(device)) {
printk(KERN_ERR "device_create for fplcd failed\n");
goto fail3;
}
...
}
To test the lseek call I have the following unit test:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#define log(msg, ...) fprintf(stdout, __FILE__ ":%s():[%d]:" msg, __func__, __LINE__, __VA_ARGS__)
int lcd;
void test(void)
{
int k;
// a lot of hello's
log("hello world test\n",1);
if (lseek(lcd, 0, SEEK_CUR) == -1) {
log("failed to seek\n", 1);
}
}
int main(int argc, char **argv)
{
lcd = open("/dev/lcd", O_WRONLY);
if (lcd == -1) {
perror("unable to open lcd");
exit(EXIT_FAILURE);
}
test();
close(lcd);
return 0;
}
The files are cross compiled like so:
~/Workspace/ts4x00/lcd-module$ cat Makefile
obj-m += fls_lcd.o
all:
make -C $(KPATH) M=$(PWD) modules
$(CROSS_COMPILE)gcc -g -fPIC $(CFLAGS) lcd_unit_test.c -o lcd_unit_test
clean:
make -C $(KPATH) M=$(PWD) clean
rm -rf lcd_unit_test
~/Workspace/ts4x00/lcd-module$ make CFLAGS+="-march=armv4 -ffunction-sections -fdata-sections"
make -C ~/Workspace/ts4x00/linux-2.6.29 M=~/Workspace/ts4x00/lcd-module modules
make[1]: Entering directory `~/Workspace/ts4x00/linux-2.6.29'
CC [M] ~/Workspace/ts4x00/lcd-module/fls_lcd.o
~/Workspace/ts4x00/lcd-module/fls_lcd.c:443: warning: 'lcd_entry_mode' defined but not used
Building modules, stage 2.
MODPOST 1 modules
CC ~/Workspace/ts4x00/lcd-module/fls_lcd.mod.o
LD [M] ~/Workspace/ts4x00/lcd-module/fls_lcd.ko
make[1]: Leaving directory `~/Workspace/ts4x00/linux-2.6.29'
~/Workspace/ts4x00/arm-2008q3/bin/arm-none-linux-gnueabi-gcc -g -fPIC -march=armv4 -ffunction-sections -fdata-sections lcd_unit_test.c -o lcd_unit_test
This is the output of running the driver with the unit test is:
root#ts4700:~/devel# insmod ./fls_lcd.ko
root#ts4700:~/devel# ./lcd_unit_test
lcd_unit_test.c:test():[61]:hello world test
lcd_unit_test.c:test():[63]:failed to seek
root#ts4700:~/devel# dmesg
FLS LCD driver started
unsupported SEEK_SET offset bf0a573c
I cannot figure out why the parameters are being mucked up so badly on the kernel side, I tried to SEEK_CUR to position 0 and in the driver I get a SEEK_SET (no matter what I put in the unit test) and a crazy big number for off?
Does anyone know what is going on please ?
btw I am compiling for kernel 2.6.29 on a arm dev kit
OK sorry guys after trying to debug this all last night it comes down to compiling against the wrong kernel (I had KPATH left to a different config of the kernel than was on the sdcard)
sorry for wasting everyones time, but hopefully if someone is seeing what looks like a crazy stack in their kernel driver this might set them straight.
oh and thanks for all the help :)
I was trying to get CFtpServer's first example program running on a Windows 7 Pro, x64 system. After much beating around the bush and not believing what I was seeing, I got the problem down to the following simple program:
#include <iostream>
using namespace std;
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
#define die(code) { cerr << "die at " << __FILE__ << " " << __LINE__ << " "; exit(code); }
int main(int argc, char **argv)
{
short port = 21;
if (argc == 2) {
port = atoi(argv[1]);
}
WSADATA WSAData;
if ( WSAStartup( MAKEWORD(2, 2), &WSAData) != 0)
die(1);
SOCKET ls = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);//!!! proto 0 in ftpdmin!
if (ls == INVALID_SOCKET) die(1);
struct sockaddr_in sin;
sin.sin_family = AF_INET;
sin.sin_addr.s_addr = INADDR_ANY;
sin.sin_port = htons( port );
if (bind( ls, (struct sockaddr *) &sin, sizeof( struct sockaddr_in ) )
== SOCKET_ERROR) die(2);
if (listen( ls, 1 ) == SOCKET_ERROR ) //!!! backlog 1 in ftpdmin!
die(3);
// wait for connect, transmit till error
SOCKET ts;
for( ;; ) {
ts = accept( ls, NULL, NULL );
if (ts == INVALID_SOCKET) die(5);
// now write some things to that socket.
int i=0;
for(;;) {
char buf[256];
sprintf(buf, "%d Testing...\r\n",i+224);
if (send(ts, buf, strlen(buf), 0) < 0) {
DWORD err = WSAGetLastError();
cerr << "send failed with " << err << endl;
break;
}
Sleep(1000);
i = (i+1)%10;
}
Sleep(1000);
closesocket(ts);
}
}
This program opens the specified socket, listens on it for connections. When it gets a connection, it proceeds to write strings that bear a passing resemblance to the string an FTP server might use to respond to the PASV command. It will keep transmitting strings, once a second, until something goes wrong.
On my system, connecting to this 'server' using the nc.exe command, I see a few strings, then the socket will close (the error printed by the 'server' is 10053).
If I disabled the Windows firewall, I see strings as long as I care to leave the nc command running.
I've seen two different variations, and I don't know what causes the difference: Sometimes it would stop when it transmitted the string '227 ', later it started dying on '229 '. It's giving every appearance of being sensitive to the text being sent.
After 3 days of beating my head on this one, I have an answer: Window KB2754804. It's a bug, known to MS since somewhere in 2011. There is a Hotfix in the referenced Knowledge base article, but it doesn't seem to work for my tests, so I had to take the alternative route of disabling the Stateful FTP firewall.
I finally got to the KB article, from this SO entry.