1 /* This file is part of the Project Athena Zephyr Notification System.
2 * It contains source for the ZGetVariable, ZSetVariable, and ZUnsetVariable
3 * functions.
4 *
5 * Created by: Robert French
6 *
7 * Copyright (c) 1987 by the Massachusetts Institute of Technology.
8 * For copying and distribution information, see the file
9 * "mit-copyright.h".
10 */
11
12 #include "libpurple/internal.h"
13 #include "internal.h"
14 #include "util.h"
15
16 #include <ctype.h>
17 #ifndef WIN32
18 #include <pwd.h>
19 #endif
20
21 static char *get_localvarfile __P((void));
22 static char *get_varval __P((char *fn, char *val));
23 static int varline __P((char *bfr, char *var));
24
ZGetVariable(var)25 char *ZGetVariable(var)
26 char *var;
27 {
28 char *varfile, *ret;
29
30 if ((varfile = get_localvarfile()) == NULL)
31 return ((char *)0);
32
33 ret = get_varval(varfile, var);
34 g_free(varfile);
35 if (ret != ZERR_NONE)
36 return ret;
37
38 #ifdef WIN32
39 varfile = g_strdup("C:\\zephyr\\zephyr.var");
40 #else
41 varfile = g_strdup_printf("%s/zephyr.vars", CONFDIR);
42 #endif
43 ret = get_varval(varfile, var);
44 g_free(varfile);
45
46 return ret;
47 }
48
ZSetVariable(var,value)49 Code_t ZSetVariable(var, value)
50 char *var;
51 char *value;
52 {
53 int written;
54 FILE *fpin, *fpout;
55 char *varfile, *varfilebackup, varbfr[512];
56
57 written = 0;
58
59 if ((varfile = get_localvarfile()) == NULL)
60 return (ZERR_INTERNAL);
61
62 varfilebackup = g_strconcat(varfile, ".backup", NULL);
63
64 if (!(fpout = fopen(varfilebackup, "w"))) {
65 g_free(varfile);
66 g_free(varfilebackup);
67 return (errno);
68 }
69 if ((fpin = fopen(varfile, "r")) != NULL) {
70 while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
71 if (varbfr[strlen(varbfr)-1] < ' ')
72 varbfr[strlen(varbfr)-1] = '\0';
73 if (varline(varbfr, var)) {
74 fprintf(fpout, "%s = %s\n", var, value);
75 written = 1;
76 }
77 else
78 fprintf(fpout, "%s\n", varbfr);
79 }
80 (void) fclose(fpin); /* don't care about errs on input */
81 }
82 if (!written)
83 fprintf(fpout, "%s = %s\n", var, value);
84 if (fclose(fpout) == EOF) {
85 g_free(varfilebackup);
86 g_free(varfile);
87 return(EIO); /* can't rely on errno */
88 }
89 if (rename(varfilebackup, varfile)) {
90 g_free(varfilebackup);
91 g_free(varfile);
92 return (errno);
93 }
94 g_free(varfilebackup);
95 g_free(varfile);
96 return (ZERR_NONE);
97 }
98
ZUnsetVariable(var)99 Code_t ZUnsetVariable(var)
100 char *var;
101 {
102 FILE *fpin, *fpout;
103 char *varfile, *varfilebackup, varbfr[512];
104
105 if ((varfile = get_localvarfile()) == NULL)
106 return (ZERR_INTERNAL);
107
108 varfilebackup = g_strconcat(varfile, ".backup", NULL);
109
110 if (!(fpout = fopen(varfilebackup, "w"))) {
111 g_free(varfile);
112 g_free(varfilebackup);
113 return (errno);
114 }
115 if ((fpin = fopen(varfile, "r")) != NULL) {
116 while (fgets(varbfr, sizeof varbfr, fpin) != (char *) 0) {
117 if (varbfr[strlen(varbfr)-1] < ' ')
118 varbfr[strlen(varbfr)-1] = '\0';
119 if (!varline(varbfr, var))
120 fprintf(fpout, "%s\n", varbfr);
121 }
122 (void) fclose(fpin); /* don't care about read close errs */
123 }
124 if (fclose(fpout) == EOF) {
125 g_free(varfilebackup);
126 g_free(varfile);
127 return(EIO); /* errno isn't reliable */
128 }
129 if (rename(varfilebackup, varfile)) {
130 g_free(varfilebackup);
131 g_free(varfile);
132 return (errno);
133 }
134 g_free(varfilebackup);
135 g_free(varfile);
136 return (ZERR_NONE);
137 }
138
get_localvarfile(void)139 static char *get_localvarfile(void)
140 {
141 const char *base;
142 #ifndef WIN32
143 struct passwd *pwd;
144 base = purple_home_dir();
145 #else
146 base = getenv("HOME");
147 if (!base)
148 base = getenv("HOMEPATH");
149 if (!base)
150 base = "C:\\";
151 #endif
152 if (!base) {
153 #ifndef WIN32
154 if (!(pwd = getpwuid((int) getuid()))) {
155 fprintf(stderr, "Zephyr internal failure: Can't find your entry in /etc/passwd\n");
156 return NULL;
157 }
158 base = pwd->pw_dir;
159 #endif
160 }
161
162 return g_strconcat(base, "/.zephyr.vars", NULL);
163 }
164
get_varval(fn,var)165 static char *get_varval(fn, var)
166 char *fn;
167 char *var;
168 {
169 FILE *fp;
170 static char varbfr[512];
171 int i;
172
173 fp = fopen(fn, "r");
174 if (!fp)
175 return ((char *)0);
176
177 while (fgets(varbfr, sizeof varbfr, fp) != (char *) 0) {
178 if (varbfr[strlen(varbfr)-1] < ' ')
179 varbfr[strlen(varbfr)-1] = '\0';
180 if (!(i = varline(varbfr, var)))
181 continue;
182 (void) fclose(fp); /* open read-only, don't care */
183 return (varbfr+i);
184 }
185 (void) fclose(fp); /* open read-only, don't care */
186 return ((char *)0);
187 }
188
189 /* If the variable in the line bfr[] is the same as var, return index to
190 the variable value, else return 0. */
varline(bfr,var)191 static int varline(bfr, var)
192 char *bfr;
193 char *var;
194 {
195 register char *cp;
196
197
198 if (!bfr[0] || bfr[0] == '#') /* comment or null line */
199 return (0);
200
201 cp = bfr;
202 while (*cp && !isspace(*cp) && (*cp != '='))
203 cp++;
204
205 #ifndef WIN32
206 #define max(a,b) ((a > b) ? (a) : (b))
207 #endif
208
209 if (g_ascii_strncasecmp(bfr, var, max(strlen(var), (gsize)(cp - bfr))))
210 return(0); /* var is not the var in
211 bfr ==> no match */
212
213 cp = strchr(bfr, '=');
214 if (!cp)
215 return(0);
216 cp++;
217 while (*cp && isspace(*cp)) /* space up to variable value */
218 cp++;
219
220 return (cp - bfr); /* return index */
221 }
222