ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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;
}
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;
}
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:
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.