libcfe  0.12.1
some useful C-functions
config_files.c
Go to the documentation of this file.
1 #include "config.h"
2 #include "config_files.h"
3 
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include <sys/types.h>
8 #include <sys/stat.h>
9 #include <pwd.h>
10 #include <fcntl.h>
11 #include <errno.h>
12 #include <unistd.h>
13 #include <envz.h>
14 
15 #include "check_path_exists.h"
16 #include "len.h"
17 
18 #define ROUNDUP(a, b) (((a) & ~((b)-1)) + (b))
19 
20 int add_config_file(char **list, size_t *list_len, size_t *list_size, unsigned char id, char *file, size_t file_len, unsigned int check_path)
21 {
22  static char *home_dir = NULL;
23  static size_t home_dir_len = 0;
24  char *ptr;
25 
26  if(home_dir == NULL)
27  {
28  struct passwd *pw = NULL;
29 
30  /* search for the users home dir.
31  * First lookup the enviroment variable HOME,
32  * if this is not set lookup the directory in the userdatabse
33  * if there is still no match and uid is 0, try /root
34  * and finaly fail.
35  */
36  if(getenv("HOME") != NULL)
37  home_dir = strdup(getenv("HOME"));
38  else if((pw = getpwuid(getuid())) == NULL)
39  {
40  if(pw->pw_dir != NULL)
41  home_dir = strdup(pw->pw_dir);
42  else if(pw->pw_dir == NULL && pw->pw_uid == 0 && check_dir_exists("/root", PATH_R | PATH_W) == 0)
43  home_dir = strdup("/root");
44  }
45 
46  /* check if the home directory exists, if not fail */
47  if(home_dir == NULL || check_dir_exists(home_dir, PATH_W) != 0)
48  {
49  errno = ENOENT;
50  return -1;
51  }
52  home_dir_len = str_len(home_dir);
53  }
54 
55  if(*list == NULL || *list_size < *list_len + home_dir_len + 1 + file_len + 3)
56  {
57  if(*list == NULL) *list_len = 0;
58  *list_size = ROUNDUP(*list_len + home_dir_len + 1 + file_len + 3, 32);
59  ptr = (char *)realloc(*list, *list_size);
60  if(ptr == NULL)
61  {
62  errno = ENOMEM;
63  return -1;
64  }
65  *list = ptr;
66  }
67 
68  (*list)[(*list_len)++] = id;
69  (*list)[(*list_len)++] = '=';
70  ptr = *list + *list_len;
71  strncpy(*list + *list_len, home_dir, home_dir_len);
72  *list_len += home_dir_len;
73  if(file[0] == '/' && home_dir[home_dir_len - 1] == '/')
74  {
75  file++;
76  file_len--;
77  }
78  else if(file[0] != '/' && home_dir[home_dir_len - 1] != '/')
79  (*list)[(*list_len)++] = '/';
80 
81  strncpy(*list + *list_len, file, file_len);
82  *list_len += file_len;
83  (*list)[(*list_len)++] = '\0';
84 
85  if((check_path & S_IFMT) > 0)
86  {
87  if(check_path_exists(ptr, check_path & S_IFMT, check_path & (PATH_R | PATH_W | PATH_X)) == 0)
88  return 0;
89  else if((check_path & CREATE_PATH) == CREATE_PATH)
90  { /* requested path does not exists, try to create it */
91  if(S_ISDIR(check_path & S_IFMT))
92  return mkdir(ptr, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IXGRP);
93  else if(S_ISREG(check_path & S_IFMT))
94  {
95  int fd = open(ptr, O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP);
96  if(fd == -1)
97  return -1;
98  close(fd);
99  return 0;
100  }
101  errno = ENOENT;
102  return -1;
103  }
104  else
105  { /* path does not exists and CREATE_PATH is not specified */
106  errno = ENOENT;
107  return -1;
108  }
109  }
110  return 0;
111 }
112 
113 char *get_config_file(char *list, size_t list_size, unsigned char id)
114 {
115  char s[2];
116  s[0] = id;
117  s[1] = '\0';
118  return envz_get(list, list_size, s);
119 }
#define PATH_R
request read permission
#define PATH_W
request write permission
char * get_config_file(char *list, size_t list_size, unsigned char id)
Definition: config_files.c:113
#define str_len(s)
Shorthand for counting '\0' terminating strings. See _len for more info.
Definition: len.h:17
#define check_dir_exists(dir, mode)
int add_config_file(char **list, size_t *list_len, size_t *list_size, unsigned char id, char *file, size_t file_len, unsigned int check_path)
Definition: config_files.c:20
#define PATH_X
request execute permission
int check_path_exists(const char *path, mode_t type, mode_t mode)
#define ROUNDUP(a, b)
Definition: config_files.c:18
#define CREATE_PATH
Definition: config_files.h:6