merge with 0.30.213
[util-vserver.git] / lib / getvserverbyctx-compat.hc
1 // $Id: getvserverbyctx-compat.hc 2182 2005-10-25 16:20:07Z ensc $    --*- c -*--
2
3 // Copyright (C) 2003 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
4 //  
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; version 2 of the License.
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
19 #ifdef HAVE_CONFIG_H
20 #  include <config.h>
21 #endif
22
23 #include "vserver.h"
24 #include "internal.h"
25 #include "pathconfig.h"
26 #include "compat-c99.h"
27
28 #include <string.h>
29 #include <unistd.h>
30
31 #ifdef VC_ENABLE_API_COMPAT
32 #include <dirent.h>
33 #include <sys/types.h>
34
35
36 static char *
37 handleLegacy(xid_t xid)
38 {
39   DIR                   *dir = opendir(DEFAULT_PKGSTATEDIR);
40   struct dirent         *ep;
41   char *                result = 0;
42   
43   if (dir==0) return 0;
44   while ((ep=readdir(dir))!=0) {
45     char * const                name = ep->d_name;
46     size_t                      l    = name ? strlen(name) : 0;
47     xid_t                       cur_xid;
48
49     if (l<=4 || strcmp(name+l-4, ".ctx")!=0) continue;
50     name[l-4]   = '\0';
51     cur_xid = vc_getVserverCtx(name, vcCFG_LEGACY, false, 0);
52     if (cur_xid!=xid) continue;
53
54     result      = strdup(name);
55     break;
56   }
57
58   closedir(dir);
59   return result;
60 }
61 #else
62 static inline char *
63 handleLegacy(xid_t UNUSED xid)
64 {
65   return 0;
66 }
67 #endif
68
69 static char *
70 vc_getVserverByCtx_compat(xid_t ctx, vcCfgStyle *style, char const *revdir,
71                           bool validate_result)
72 {
73   if (revdir==0) revdir = DEFAULT_PKGSTATEREVDIR;
74
75   {
76   vcCfgStyle    cur_style = vcCFG_NONE;
77   size_t        l = strlen(revdir);
78   size_t        l1;
79   char          path[l + sizeof(unsigned int)*3 + 3];
80
81   strcpy(path, revdir);
82   path[l]      = '/';
83   l1 = utilvserver_fmt_uint(path+l+1, ctx);
84   path[l+1+l1] = '\0';
85
86   if (style==0 || *style==vcCFG_AUTO) {
87     if (access(path, F_OK)==0) cur_style = vcCFG_RECENT_FULL;
88     else                       cur_style = vcCFG_LEGACY;
89   }
90   else
91     cur_style = *style;
92
93   switch (cur_style) {
94     case vcCFG_RECENT_SHORT     :
95     case vcCFG_RECENT_FULL      :
96         // check if expected ctx == actual ctx (but only when this check is
97         // request)
98       if (validate_result &&
99           vc_getVserverCtx(path, vcCFG_RECENT_FULL, false, 0)!=ctx) return 0;
100
101       if (style) *style = vcCFG_RECENT_FULL;
102       return strdup(path);
103         // TODO: handle legacy
104     case vcCFG_LEGACY           :
105     {
106       char *    tmp = handleLegacy(ctx);
107       if (tmp && style)
108         *style = vcCFG_LEGACY;
109
110       return tmp;
111     }
112       
113     default             :
114       return 0;
115   }
116   }
117 }