LinuxQuestions.org
Share your knowledge at the LQ Wiki.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 07-09-2010, 09:27 AM   #1
andy89038
LQ Newbie
 
Registered: Jul 2010
Posts: 2

Rep: Reputation: 0
Having issues with typedef struct in c


Thanks for taking the time to read my post. I'm trying to read from a config file and set my results to a struct so that I can access the parameters easily. My code was modified from a post by paulsm4 and is as follows:

Code:
#include <stdio.h>
#include <time.h>
#include <string.h>
#include <ctype.h>


typedef struct {
	char *base;
	char *alert_status_file;
	char *alert_email;
	char *log_file;
	int email_throttle;
	char *dbase;
	char *db_usr; 
	char *db_pass;
	char *test;
} CONFIG ;

#define MAXLEN 80


time_t get_time();
void get_config(CONFIG *conf);
void mysql();
trim (char* in_string);



int main ()
{
	printf("%ld hours since January 1, 1970. \n", get_time());
	
	CONFIG cfg;
	get_config(&cfg);
	
	printf("base is: %s \n",cfg.base);
	printf("dbase is: %s \n",cfg.dbase);
	printf("db_usr is: %s \n",cfg.db_usr);
	printf("alert_status_file is: %s \n",cfg.alert_status_file);
	printf("alert_email is: %s \n",cfg.alert_email);
	printf("log_file is: %s \n",cfg.log_file);
	printf("db_pass is: %s \n",cfg.db_pass);
	printf("email_throttle is: %s \n",cfg.email_throttle);
	return 0;
}
	
	
	
time_t get_time () {
	time_t seconds, rt_time;
	seconds = time (NULL);
	rt_time = seconds/3600;
	return rt_time;
}	



void get_config (CONFIG *conf)
{
	char *line, buffer[MAXLEN];
	char key[MAXLEN], value[MAXLEN];
	FILE *FH;
	
	FH = fopen("snort_alert.conf", "r");
	if (FH == NULL)
	{
		printf("Could not open snort_alert.conf\n");
		exit(1);
	}
	
	while (line = fgets(buffer, sizeof(buffer), FH) != NULL)
	{

		/* Skip blank lines and comments */
		if(buffer[0] == "\n" || buffer[0] == "#")
			continue;
		
		/*tokanize key value pairs*/
		line = strtok(buffer, "=");
		if(line == NULL){
			continue;
		}
		else {
			strncpy(key, line, MAXLEN);
			trim(key);
		}
		
		line = strtok(NULL, "=");
		if(line == NULL){
			continue;
		}
		else{
			strncpy(value, line, MAXLEN);
			trim(value);
		}
		
		printf("key = %s: value = %s\n",key,value);
		/* Copy into correct entry in parameters struct */
		if(!strcmp( key, "base"))
			conf->base = value;
		else if (!strcmp( key, "alert_status_file"))
			conf->alert_status_file = value;
		else if (!strcmp( key, "alert_email"))
			conf->alert_email = value;
		else if (!strcmp( key, "log_file"))	
			conf->log_file = value;
		else if (!strcmp( key, "email_throttle"))	
			conf->email_throttle = value;
		else if (!strcmp( key, "dbase"))
			conf->dbase = value;
		else if (!strcmp( key, "db_usr"))
			conf->db_usr = value;
		else if (!strcmp( key, "db_pass"))
			conf->db_pass = value;
		else
			printf("WARNING: %s/%s: Unknown name/value pair!\n", key, value); 
			

		
	}
		if(!strcmp(key, "alert_email"))
			printf("***key %s equals base.  Value was set to %s\n",key, conf->base);
		
	fclose(FH);
		printf("   base = %s\n   alert_status_file = %s\n",conf->base,conf->alert_status_file);
}

trim (char * in_string)
{
	/* Initialize start, end pointers */
	char *start_pos = in_string, *end_pos = &in_string[strlen (in_string) - 1];

	/* Trim and delimit right side */
	while ( (isspace (*end_pos)) && (end_pos >= start_pos) )
	{
		end_pos--;
	  *(end_pos+1) = '\0';
	}
	
	/* Trim left side */
	while ( (isspace (*start_pos)) && (start_pos < end_pos) )
	{
		start_pos++;
	}
	
	/* Copy finished string */
	strcpy (in_string, start_pos);
	return in_string;
}
config file
Code:
#snort alert config file

base = /etc/snort_alerts
dbase = snort
db_usr = _snort
email_throttle = 10
alert_status_file = alert_stat
alert_email = lahblah@blah.com
log_file = alert_log
db_pass= xxxxx
Pardon all my debugging statements.
The output is:
Code:
355189 hours since January 1, 1970.
key = base: value = /etc/snort_alerts
key = dbase: value = snort
key = db_usr: value = _snort
key = email_throttle: value = 10
key = alert_status_file: value = alert_stat
key = alert_email: value = blahblah@blah.com
key = log_file: value = alert_log
key = db_pass: value = xxxxx
   base = xxxxx
   alert_status_file = xxxxx
base is: xxxxx
dbase is: xxxxx
db_usr is: xxxxx
alert_status_file is: xxxxx
alert_email is: xxxxx
log_file is: xxxxx
db_pass is: xxxxx
email_throttle is: xxxxx
As you can see from the output everything seems to go fine up until I start trying to store my values. I'm thinking my problem is pointers but when I try to specify the size of the variables I start getting errors. I have a test case in which I can get it all to work fine and I'm not understanding why it works in my test case and not in the code above. I haven't done much C programming and any help you can provide would be greatly appreciated. Here is my test case that appears to work correctly...

Code:
#include <stdio.h>
#include <string.h>

typedef struct {
        char *a;
	char *b;
	char *c;
	char *d;
        int e;
} test ;

void get_value (test *p);



int main ()
{
        test mystructure;
        get_value(&mystructure);
        printf("The value of a is: %s.\n",mystructure.a);
		printf("The value of b is : %s\n",mystructure.b);
		printf("The value of c is : %s\n",mystructure.c);
		printf("The value of d is : %s\n",mystructure.d);
		printf("The value of e is : %d\n",mystructure.e);
        return 0;
}



void get_value (test *p)
{
		char *value1;
		char *value2;
		char *value3;
		char *value4;
		int value5;
		value1 = "Hello World";
		value2 = "tset1";
		value3 = "eh";
		value4 = "Testing";
		value5 = 10;
		if(!strcmp(value1, "Hello World"));
			p->a = value1;
        p->b = value2;
		p->c = value3;
		p->d = value4;
		p->e = value5;
}
 
Old 07-09-2010, 09:43 AM   #2
irmin
Member
 
Registered: Jan 2010
Location: the universe
Distribution: Slackware (modified), Slackware64 (modified), openSuSE (modified)
Posts: 342

Rep: Reputation: 62
Welcome to LQ,

I think I located your error and am able to explain it: The problem is with the pointers, as you said correctly. You are assigning the values as follows:
Code:
conf->email_throttle = value;
This will set conf->email_throttle to the address of value[0]. But every key you assign so will get the same value. This means in the end all pointers will point to the same memory region and thus will contain the same contents. You override the contents with strncpy in each iteration. Try to assign it in such a way:
Code:
if( conf->email_throttle ) {
  printf("WARNING: %s/%s: Reassigning name/value pair!\n", key, value); 
  free(conf->email_throttle);
}

conf->email_throttle = strdup(value);
But then you will have to free() the memory explicitly when the config object is no longer needed. To make the above code work, you will have to set all pointers to NULL, before reading the data. Otherwise your program may crash, since it tries to free some memory, that was not allocated on the heap before.
Please also note, that the code in the first example is unstable, since you passed the address of a stack object to the calling function. This means, that you are going to access some memory, that might be used by another function later and this may cause a SIGSEGV or this function may destroy your config values.

The second example works, since you assign to each pointer the beginning of a distinct memory region. Thus there will be no overwritings.

I hope this helps you.
 
Old 07-09-2010, 10:52 AM   #3
andy89038
LQ Newbie
 
Registered: Jul 2010
Posts: 2

Original Poster
Rep: Reputation: 0
Thank you for your response. I knew I was pointing to the same address I just wasn't seeing how to get around it.
 
  


Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
GCC compile problem:struct A have a member variable which is just a struct type name? leon.zcom Programming 3 04-18-2008 04:40 PM
C declaration problem for a "typedef struct". Spirals Linux - Software 3 03-17-2008 07:52 AM
typedef a union as a struct? KasperLotus Programming 3 03-09-2007 01:10 PM
g++ and wrong struct member addresses / struct size misreporting sonajiso Linux - General 5 05-22-2004 10:16 PM
switch statement converting struct char to struct int oceaneyes2 Programming 2 12-10-2003 04:30 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:08 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration