Fix RPMLINT error
[platform/core/uifw/anthy.git] / src-diclib / conf.c
1 /*
2  * Anthy¤ÎÀßÄê¤Î¥Ç¡¼¥¿¥Ù¡¼¥¹
3  * conf_init¤ÇÀßÄꤵ¤ì¤ëÊÑ¿ô¤Èconf_override¤ÇÀßÄꤵ¤ì¤ë
4  * ÊÑ¿ô¤Î´Ø·¸¤ËÃí°Õ
5  *
6  * Copyright (C) 2000-2007 TABATA Yusuke
7  */
8 /*
9   This library is free software; you can redistribute it and/or
10   modify it under the terms of the GNU Lesser General Public
11   License as published by the Free Software Foundation; either
12   version 2 of the License, or (at your option) any later version.
13
14   This library is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17   Lesser General Public License for more details.
18
19   You should have received a copy of the GNU Lesser General Public
20   License along with this library; if not, write to the Free Software
21   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
22  */
23 #include <unistd.h>
24 #include <pwd.h>
25 #include <time.h>
26 #include <sys/types.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <anthy/alloc.h>
32 #include <anthy/conf.h>
33 #include <anthy/logger.h>
34
35 #include <config.h>
36
37 /** ÀßÄê¤ÎÊÑ¿ô¤ÈÃÍ */
38 struct val_ent {
39   /** ÊÑ¿ô̾ */
40   const char *var;
41   /** ÃÍ */
42   const char *val;
43   /** ¥ê¥¹¥È¤Î¼¡Í×ÁÇ */
44   struct val_ent *next;
45 };
46
47 static struct val_ent *ent_list;
48 /** ½é´ü²½ºÑ¤ß¥Õ¥é¥° */
49 static int confIsInit;
50 static allocator val_ent_ator;
51
52 static void
53 val_ent_dtor(void *p)
54 {
55   struct val_ent *v = p;
56   free((void *)v->var);
57   if (v->val) {
58     free((void *)v->val);
59   }
60 }
61
62 /** ÊÑ¿ô̾¤ËÂбþ¤¹¤ëval_ent¤ò¼èÆÀ¤¹¤ë */
63 static struct val_ent *
64 find_val_ent(const char *v)
65 {
66   struct val_ent *e;
67   for (e = ent_list; e; e = e->next) {
68     if(!strcmp(v, e->var)) {
69       return e;
70     }
71   }
72   e = malloc(sizeof(struct val_ent));
73   if (!e) {
74     return NULL;
75   }
76   e->var = strdup(v);
77   e->val = 0;
78   e->next = ent_list;
79   ent_list = e;
80   return e;
81 }
82
83 /** ${ÊÑ¿ô̾}¤Î·Á¤ÎÊÑ¿ô¤ÎÃͤò¼èÆÀ¤¹¤ë
84  */
85 static const char *
86 get_subst(const char *s)
87 {
88   if (s[0] == '$' && s[1] == '{' &&
89       strchr(s, '}')) {
90     struct val_ent *val;
91     char *var = strdup(&s[2]);
92     char *k = strchr(var, '}');
93     *k = 0;
94     val = find_val_ent(var);
95     free(var);
96     if (!val || !val->val) {
97       return "";
98     }
99     return val->val;
100   }
101   return NULL;
102 }
103
104 struct expand_buf {
105   int len;
106   int size;
107   char *buf;
108   char *cur;
109 };
110
111 static void
112 ensure_buffer(struct expand_buf *eb, int count)
113 {
114   int required = count - (eb->size - eb->len) + 16;
115   if (required > 0) {
116     eb->size += required;
117     eb->buf = realloc(eb->buf, eb->size);
118     eb->cur = &eb->buf[eb->len];
119   }
120 }
121
122 static char *
123 expand_string(const char *s)
124 {
125   struct expand_buf eb;
126   char *res;
127   eb.size = 256;
128   eb.buf = malloc(eb.size);
129   eb.cur = eb.buf;
130   eb.len = 0;
131
132   while (*s) {
133     const char *subst = get_subst(s);
134     if (subst) {
135       int len = strlen(subst);
136       ensure_buffer(&eb, len + 1);
137       *eb.cur = 0;
138       strcat(eb.buf, subst);
139       eb.cur += len;
140       eb.len += len;
141       s = strchr(s, '}');
142       s ++;
143     } else {
144       *eb.cur = *s;
145       /**/
146       eb.cur ++;
147       s++;
148       eb.len ++;
149     }
150     /**/
151     ensure_buffer(&eb, 256);
152   }
153   *eb.cur = 0;
154   /**/
155   res = strdup(eb.buf);
156   free(eb.buf);
157   return res;
158 }
159
160 static void
161 add_val(const char *var, const char *val)
162 {
163   struct val_ent *e;
164   e = find_val_ent(var);
165   if (e->val) {
166     free((void *)e->val);
167   }
168   e->val = expand_string(val);
169 }
170
171 static void
172 read_conf_file(void)
173 {
174   const char *fn;
175   FILE *fp;
176   char buf[1024];
177   fn = anthy_conf_get_str("CONFFILE");
178   fp = fopen(fn, "r");
179   if (!fp){
180     anthy_log(0, "Failed to open %s\n", fn);
181     return ;
182   }
183   while(fgets(buf, 1024, fp)) {
184     if (buf[0] != '#') {
185       char var[1024], val[1024];
186       if (sscanf(buf, "%s %s", var, val) == 2){
187         add_val(var, val);
188       }
189     }
190   }
191   fclose(fp);
192 }
193
194 void
195 anthy_do_conf_override(const char *var, const char *val)
196 {
197   if (!strcmp(var,"CONFFILE")) {
198     add_val(var, val);
199     anthy_do_conf_init();
200   }else{
201     anthy_do_conf_init();
202     add_val(var, val);
203   }
204 }
205
206 /* ¥æ¥Ë¡¼¥¯¤Ê¥»¥Ã¥·¥ç¥óID¤ò³ÎÊݤ¹¤ë */
207 #define SID_FORMAT      "%s-%08x-%05d" /* HOST-TIME-PID */
208 #define MAX_SID_LEN     (MAX_HOSTNAME+8+5+2)
209 #define MAX_HOSTNAME    64
210
211 static void
212 alloc_session_id(void)
213 {
214   time_t t;
215   pid_t pid;
216   char hn[MAX_HOSTNAME];
217   char sid[MAX_SID_LEN];
218   t = time(0);
219   pid = getpid();
220   gethostname(hn, MAX_HOSTNAME);
221   hn[MAX_HOSTNAME-1] = '\0';
222   sprintf(sid, SID_FORMAT, hn, (unsigned int)t & 0xffffffff, pid & 0xffff);
223   add_val("SESSION-ID", sid);
224 }
225
226 void
227 anthy_do_conf_init(void)
228 {
229
230   if (!confIsInit) {
231     const char *fn;
232     struct passwd *pw;
233     val_ent_ator = anthy_create_allocator(sizeof(struct val_ent), val_ent_dtor);
234     /*¥Ç¥Õ¥©¥ë¥È¤ÎÃͤòÀßÄꤹ¤ë¡£*/
235     add_val("VERSION", VERSION);
236     fn = anthy_conf_get_str("CONFFILE");
237     if (!fn){
238       add_val("CONFFILE", CONF_DIR"/anthy-conf");
239     }
240     pw = getpwuid(getuid());
241     add_val("HOME", pw->pw_dir);
242     alloc_session_id();
243     read_conf_file();
244     confIsInit = 1;
245   }
246 }
247
248 void
249 anthy_conf_free(void)
250 {
251   struct val_ent *e, *next;
252   for (e = ent_list; e; e = next) {
253     free((char *)e->var);
254     free((char *)e->val);
255     next = e->next;
256     free(e);
257   }
258   ent_list = NULL;
259   confIsInit = 0;
260 }
261
262 const char *
263 anthy_conf_get_str(const char *var)
264 {
265   struct val_ent *e;
266   e = find_val_ent(var);
267   return e->val;
268 }