1 /* qmail-dotfile.c - qmail dotfile ($HOME/.qmail*) lookup routines
2  * Copyright (C) 2010  Bruce Guenter <bruce@untroubled.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18 #include <bglibs/sysdeps.h>
19 #include <ctype.h>
20 #include <errno.h>
21 #include <sys/stat.h>
22 
23 #include <bglibs/str.h>
24 
25 #include "qmail.h"
26 
qmail_dotfile_exists(const struct qmail_user * user,const char * ext,str * path)27 int qmail_dotfile_exists(const struct qmail_user* user, const char* ext,
28 			 str* path)
29 {
30   struct stat st;
31   int split;
32   int baselen;
33 
34   /* System users are not required to have a .qmail file */
35   if (user->dash == 0)
36     return ext == 0 || *ext == 0;
37 
38   if (!str_copy(path, &user->homedir)) return -1;
39   if (!str_cats(path, "/.qmail")) return -1;
40   baselen = path->len;
41   if (!str_catc(path, user->dash)) return -1;
42   if (!str_cat(path, &user->ext)) return -1;
43   if (ext != 0) {
44     while (*ext) {
45       if (!str_catc(path, isupper(*ext)
46 		    ? tolower(*ext)
47 		    : (*ext == '.')
48 		    ? ':'
49 		    : *ext))
50 	return -1;
51       ++ext;
52     }
53   }
54 
55   split = path->len;
56   for (;;) {
57     if (stat(path->s, &st) == 0)
58       return 1;
59     if (errno != ENOENT)
60       return -1;
61     if ((split = str_findprev(path, '-', split - 1)) == -1
62 	|| split < baselen)
63       break;
64     path->len = split + 1;
65     if (!str_cats(path, "default")) return -1;
66   }
67   return 0;
68 }
69