]> granicus.if.org Git - fcron/blob - convert-fcrontab.c
Applied indentation
[fcron] / convert-fcrontab.c
1
2 /*
3  * FCRON - periodic command scheduler 
4  *
5  *  Copyright 2000-2012 Thibault Godouet <fcron@free.fr>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  * 
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20  * 
21  *  The GNU General Public License can also be found in the file
22  *  `LICENSE' that comes with the fcron source distribution.
23  */
24
25
26 #include "convert-fcrontab.h"
27 #include "mem.h"
28
29
30 void info(void);
31 void usage(void);
32 void convert_file(char *file_name);
33 char *read_str(FILE * f, char *buf, int max);
34 void delete_file(cf_t * file);
35
36 char *cdir = FCRONTABS;         /* the dir where are stored users' fcrontabs */
37
38 /* needed by log part : */
39 char *prog_name = NULL;
40 char foreground = 1;
41 pid_t daemon_pid = 0;
42 uid_t rootuid = 0;
43 gid_t rootgid = 0;
44
45 void
46 info(void)
47     /* print some informations about this program :
48      * version, license */
49 {
50     fprintf(stderr,
51             "convert-fcrontab " VERSION_QUOTED "\n"
52             "Copyright " COPYRIGHT_QUOTED " Thibault Godouet <fcron@free.fr>\n"
53             "This program is free software distributed WITHOUT ANY WARRANTY.\n"
54             "See the GNU General Public License for more details.\n"
55             "\n"
56             "WARNING: this program is not supposed to be installed on the "
57             "system. It is only used at installation time to convert the "
58             "the binary fcrontabs in the old format (fcron < 1.1.0, which "
59             "was published in 2001) to the present one.");
60
61     exit(EXIT_OK);
62
63 }
64
65
66 void
67 usage()
68   /*  print a help message about command line options and exit */
69 {
70     fprintf(stderr, "\nconvert-fcrontab " VERSION_QUOTED "\n\n"
71             "convert-fcrontab -h\n"
72             "convert-fcrontab -V\n"
73             "convert-fcrontab user\n"
74             "  Update the fcrontab of \"user\" to fit the new binary format.\n"
75             "\n"
76             "WARNING: this program is not supposed to be installed on the "
77             "system. It is only used at installation time to convert the "
78             "the binary fcrontabs in the old format (fcron < 1.1.0, which "
79             "was published in 2001) to the present one.");
80
81     exit(EXIT_ERR);
82 }
83
84
85 char *
86 read_str(FILE * f, char *buf, int max)
87     /* return a pointer to string read from file f
88      * if it is non-zero length */
89 {
90     int i;
91
92     for (i = 0; i < max; i++)
93         if ((buf[i] = fgetc(f)) == '\0')
94             break;
95     buf[max - 1] = '\0';
96
97     if (strlen(buf) == 0)
98         return NULL;
99     else
100         return strdup2(buf);
101
102 }
103
104
105 void
106 delete_file(cf_t * file)
107     /* free a file if user_name is not null 
108      *   otherwise free all files */
109 {
110     cl_t *line = NULL;
111     cl_t *cur_line = NULL;
112
113
114     /* free lines */
115     cur_line = file->cf_line_base;
116     while ((line = cur_line) != NULL) {
117         cur_line = line->cl_next;
118         Free_safe(line->cl_shell);
119         Free_safe(line->cl_mailto);
120         Free_safe(line->cl_runas);
121         Free_safe(line);
122     }
123
124     /* free env variables */
125     env_list_destroy(file->cf_env_list);
126
127     /* finally free file itself */
128     Free_safe(file->cf_user);
129     Free_safe(file);
130
131 }
132
133
134 void
135 convert_file(char *file_name)
136 /* this functions is a mix of read_file() from version 1.0.3 and save_file(),
137  * so you can read more comments there */
138 {
139     cf_t *file = NULL;
140     cl_t *line = NULL;
141     char *env = NULL;
142     FILE *f = NULL;
143     char buf[LINE_LEN];
144     time_t t_save = 0;
145     struct stat file_stat;
146
147     explain("Converting %s's fcrontab ...", file_name);
148
149     Alloc(file, cf_t);
150     /* open file */
151     if ((f = fopen(file_name, "r")) == NULL)
152         die_e("Could not read %s", file_name);
153
154     if (fstat(fileno(f), &file_stat) != 0)
155         die_e("Could not stat %s", file_name);
156
157     bzero(buf, sizeof(buf));
158
159     if (fgets(buf, sizeof(buf), f) == NULL ||
160         strncmp(buf, "fcrontab-017\n", sizeof("fcrontab-017\n")) != 0) {
161
162         error("File %s is not valid: ignored.", file_name);
163         error("Maybe this file has been generated by a too old version "
164               "of fcron ( <= 0.9.4), or is already in the new binary format.");
165         error("In this case, you should reinstall it using fcrontab"
166               " (but be aware that you may lose some data as the last "
167               "execution time and date as if you run a fcrontab -z -n).");
168         exit(EXIT_ERR);
169     }
170
171     if ((file->cf_user = read_str(f, buf, sizeof(buf))) == NULL)
172         die_e("Cannot read user's name");
173
174     if (fscanf(f, "%" ATTR_SIZE_TIMET "d", CAST_TIMET_PTR & t_save) != 1)
175         error("could not get time and date of saving");
176
177     /* read env variables */
178     while ((env = read_str(f, buf, sizeof(buf))) != NULL) {
179         env_list_putenv(file->cf_env_list, env, 1);
180         Free_safe(env);
181     }
182
183     /* read lines */
184     Alloc(line, cl_t);
185     while (fread(line, sizeof(cl_t), 1, f) == 1) {
186
187         if ((line->cl_shell = read_str(f, buf, sizeof(buf))) == NULL) {
188             error("Line is not valid (empty shell command) : ignored");
189             continue;
190         }
191         if ((line->cl_runas = read_str(f, buf, sizeof(buf))) == NULL) {
192             error("Line is not valid (empty runas field) : ignored");
193             continue;
194         }
195         if ((line->cl_mailto = read_str(f, buf, sizeof(buf))) == NULL) {
196             error("Line is not valid (empty mailto field) : ignored");
197             continue;
198         }
199
200         line->cl_next = file->cf_line_base;
201         file->cf_line_base = line;
202         Alloc(line, cl_t);
203
204     }
205
206     Free_safe(line);
207
208     fclose(f);
209
210     /* open a temp file in write mode and truncate it */
211     strcpy(buf, "tmp_");
212     strncat(buf, file_name, sizeof(buf) - sizeof("tmp_") - 1);
213     buf[sizeof(buf) - 1] = '\0';
214
215     /* everything's ok : we can override the src file safely */
216     if (rename(buf, file_name) != 0)
217         error_e("Could not rename %s to %s", buf, file_name);
218
219     save_file_safe(file, file_name, "convert-fcrontab", file_stat.st_uid,
220                    file_stat.st_gid, t_save);
221
222     delete_file(file);
223 }
224
225 int
226 main(int argc, char *argv[])
227 {
228     int c;
229     extern char *optarg;
230     extern int optind, opterr, optopt;
231     char *user_to_update = NULL;
232
233     rootuid = get_user_uid_safe(ROOTNAME);
234     rootgid = get_group_gid_safe(ROOTGROUP);
235
236     if (strrchr(argv[0], '/') == NULL)
237         prog_name = argv[0];
238     else
239         prog_name = strrchr(argv[0], '/') + 1;
240
241
242     /* constants and variables defined by command line */
243
244     while (1) {
245         c = getopt(argc, argv, "chV");
246         if (c == EOF)
247             break;
248         switch (c) {
249
250         case 'V':
251             info();
252             break;
253
254         case 'h':
255             usage();
256             break;
257
258         case 'c':
259             Set(fcronconf, optarg);
260             break;
261
262         case ':':
263             fprintf(stderr, "(setopt) Missing parameter");
264             usage();
265
266         case '?':
267             usage();
268
269         default:
270             fprintf(stderr, "(setopt) Warning: getopt returned %c", c);
271         }
272     }
273
274     if (optind >= argc || argc != 2)
275         usage();
276
277     /* parse fcron.conf */
278     read_conf();
279
280     user_to_update = strdup2(argv[optind]);
281
282     if (chdir(cdir) != 0)
283         die_e("Could not change dir to " FCRONTABS);
284
285     convert_file(user_to_update);
286
287     exit(EXIT_OK);
288
289 }