00001 #include "ace/Capabilities.h"
00002 #include "ace/OS_NS_ctype.h"
00003 #include "ace/OS_Memory.h"
00004 #include "ace/OS_NS_string.h"
00005
00006 #if !defined (__ACE_INLINE__)
00007 #include "ace/Capabilities.inl"
00008 #endif
00009
00010 #include "ace/OS_NS_stdio.h"
00011
00012 ACE_RCSID (ace,
00013 Capabilities,
00014 "$Id: Capabilities.cpp 80826 2008-03-04 14:51:23Z wotte $")
00015
00016
00017 #define ACE_ESC ((ACE_TCHAR)0x1b)
00018
00019 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00020
00021 ACE_CapEntry::~ACE_CapEntry (void)
00022 {
00023 }
00024
00025 ACE_Capabilities::ACE_Capabilities (void)
00026 : caps_ ()
00027 {
00028 }
00029
00030 ACE_Capabilities::~ACE_Capabilities (void)
00031 {
00032 this->resetcaps ();
00033 }
00034
00035 const ACE_TCHAR *
00036 ACE_Capabilities::parse (const ACE_TCHAR *buf, ACE_TString &cap)
00037 {
00038 while (*buf != ACE_TEXT ('\0') && *buf != ACE_TEXT (','))
00039 {
00040 if (*buf == ACE_TEXT ('\\'))
00041 {
00042 ++buf;
00043 if (*buf == ACE_TEXT ('E') || *buf == ACE_TEXT ('e'))
00044 {
00045 cap += ACE_ESC;
00046 ++buf;
00047 continue;
00048 }
00049 else if (*buf == ACE_TEXT ('r'))
00050 {
00051 cap += ACE_TEXT ('\r');
00052 ++buf;
00053 continue;
00054 }
00055 else if (*buf == ACE_TEXT ('n'))
00056 {
00057 cap += ACE_TEXT ('\n');
00058 ++buf;
00059 continue;
00060 }
00061 else if (*buf == ACE_TEXT ('t'))
00062 {
00063 cap += ACE_TEXT ('\t');
00064 ++buf;
00065 continue;
00066 }
00067 else if (*buf == ACE_TEXT ('\\'))
00068 {
00069 cap += *buf++;
00070 continue;
00071 }
00072 if (ACE_OS::ace_isdigit(*buf))
00073 {
00074
00075 int oc = 0;
00076 for (int i = 0;
00077 i < 3 && *buf && ACE_OS::ace_isdigit (*buf);
00078 i++)
00079 oc = oc * 8 + (*buf++ - ACE_TEXT ('0'));
00080
00081 cap += (ACE_TCHAR) oc;
00082 continue;
00083 }
00084 }
00085 cap += *buf++;
00086 }
00087 return buf;
00088 }
00089
00090 const ACE_TCHAR *
00091 ACE_Capabilities::parse (const ACE_TCHAR *buf, int &cap)
00092 {
00093 int n = 0;
00094
00095 while (*buf && ACE_OS::ace_isdigit (*buf))
00096 n = n * 10 + (*buf++ - ACE_TEXT ('0'));
00097
00098 cap = n;
00099
00100 return buf;
00101 }
00102
00103 void
00104 ACE_Capabilities::resetcaps (void)
00105 {
00106 for (CAPABILITIES_MAP::ITERATOR iter (this->caps_);
00107 !iter.done ();
00108 iter.advance ())
00109 {
00110 CAPABILITIES_MAP::ENTRY *entry = 0;
00111 iter.next (entry);
00112 delete entry->int_id_;
00113 }
00114
00115 this->caps_.close ();
00116 this->caps_.open ();
00117 }
00118
00119 int
00120 ACE_Capabilities::fillent (const ACE_TCHAR *buf)
00121 {
00122 this->resetcaps ();
00123 while (*buf)
00124 {
00125 ACE_TString s;
00126 int n;
00127 ACE_TString name;
00128 ACE_CapEntry *ce;
00129
00130
00131 while (*buf && ACE_OS::ace_isspace(*buf)) buf++;
00132
00133
00134 if (*buf == ACE_TEXT ('\0'))
00135 break;
00136
00137 if (*buf == ACE_TEXT ('#'))
00138 {
00139 while (*buf && *buf != ACE_TEXT ('\n'))
00140 buf++;
00141 if (*buf == ACE_TEXT ('\n'))
00142 buf++;
00143 continue;
00144 }
00145 while(*buf && *buf != ACE_TEXT ('=')
00146 && *buf!= ACE_TEXT ('#')
00147 && *buf != ACE_TEXT (','))
00148 name += *buf++;
00149
00150
00151 switch (*buf)
00152 {
00153 case ACE_TEXT ('='):
00154
00155 buf = this->parse (buf + 1, s);
00156 ACE_NEW_RETURN (ce,
00157 ACE_StringCapEntry (s),
00158 -1);
00159 if (this->caps_.bind (name, ce) == -1)
00160 {
00161 delete ce;
00162 return -1;
00163 }
00164 break;
00165 case ACE_TEXT ('#'):
00166
00167 buf = this->parse (buf + 1, n);
00168 ACE_NEW_RETURN (ce,
00169 ACE_IntCapEntry (n),
00170 -1);
00171 if (this->caps_.bind (name, ce) == -1)
00172 {
00173 delete ce;
00174 return -1;
00175 }
00176 break;
00177 case ACE_TEXT (','):
00178
00179 ACE_NEW_RETURN (ce,
00180 ACE_BoolCapEntry (1),
00181 -1);
00182 if (this->caps_.bind (name, ce) == -1)
00183 {
00184 delete ce;
00185 return -1;
00186 }
00187 break;
00188 default:
00189 return 0;
00190 }
00191
00192 if (*buf++ != ACE_TEXT (','))
00193 return -1;
00194 }
00195
00196 return 0;
00197 }
00198
00199 int
00200 ACE_Capabilities::is_entry (const ACE_TCHAR *name, const ACE_TCHAR *line)
00201 {
00202 for (;;)
00203 {
00204
00205 while (*line && ACE_OS::ace_isspace(*line))
00206 ++line;
00207
00208
00209 if (*line == ACE_TEXT ('\0'))
00210 break;
00211
00212
00213 ACE_TString nextname;
00214 while (*line && *line != ACE_TEXT ('|') && *line != ACE_TEXT (','))
00215 nextname += *line++;
00216
00217
00218 if (ACE_OS::strcmp (nextname.c_str (), name) == 0)
00219 return 1;
00220
00221
00222 if (*line == ACE_TEXT ('|') || *line == ACE_TEXT (','))
00223 ++line;
00224 else
00225 {
00226 ACE_DEBUG ((LM_DEBUG,
00227 ACE_TEXT ("Invalid entry\n")));
00228 break;
00229 }
00230 }
00231 return 0;
00232 }
00233
00234 int
00235 ACE_Capabilities::getline (FILE *fp, ACE_TString &line)
00236 {
00237 int ch;
00238
00239 line.set (0, 0);
00240
00241 while ((ch = ACE_OS::fgetc (fp)) != EOF && ch != ACE_TEXT ('\n'))
00242 line += (ACE_TCHAR) ch;
00243
00244 if (ch == EOF && line.length () == 0)
00245 return -1;
00246 else
00247 return 0;
00248 }
00249
00250 int
00251 ACE_Capabilities::getval (const ACE_TCHAR *keyname, ACE_TString &val)
00252 {
00253 ACE_CapEntry* cap = 0;
00254 if (this->caps_.find (keyname, cap) == -1)
00255 return -1;
00256
00257 ACE_StringCapEntry *scap =
00258 dynamic_cast<ACE_StringCapEntry *> (cap);
00259 if (scap == 0)
00260 return -1;
00261
00262 val = scap->getval ();
00263 return 0;
00264 }
00265
00266 int
00267 ACE_Capabilities::getval (const ACE_TCHAR *keyname, int &val)
00268 {
00269 ACE_CapEntry *cap = 0;
00270 if (this->caps_.find (keyname, cap) == -1)
00271 return -1;
00272
00273 ACE_IntCapEntry *icap =
00274 dynamic_cast<ACE_IntCapEntry *> (cap);
00275 if (icap != 0)
00276 {
00277 val = icap->getval ();
00278 return 0;
00279 }
00280
00281 ACE_BoolCapEntry *bcap =
00282 dynamic_cast<ACE_BoolCapEntry *> (cap);
00283
00284 if (bcap == 0)
00285 return -1;
00286
00287 val = bcap->getval ();
00288 return 0;
00289 }
00290
00291 #if !defined (ACE_IS_SPLITTING)
00292 static int
00293 is_empty (const ACE_TCHAR *line)
00294 {
00295 while (*line && ACE_OS::ace_isspace (*line))
00296 ++line;
00297
00298 return *line == ACE_TEXT ('\0') || *line == ACE_TEXT ('#');
00299 }
00300
00301 static int
00302 is_line (const ACE_TCHAR *line)
00303 {
00304 while (*line && ACE_OS::ace_isspace (*line))
00305 ++line;
00306
00307 return *line != ACE_TEXT ('\0');
00308 }
00309 #endif
00310
00311 int
00312 ACE_Capabilities::getent (const ACE_TCHAR *fname, const ACE_TCHAR *name)
00313 {
00314 FILE *fp = ACE_OS::fopen (fname, ACE_TEXT ("r"));
00315
00316 if (fp == 0)
00317 ACE_ERROR_RETURN ((LM_ERROR,
00318 ACE_TEXT ("Can't open %s file\n"),
00319 fname),
00320 -1);
00321
00322 int done;
00323 ACE_TString line;
00324
00325 while (0 == (done = (this->getline (fp, line) == -1))
00326 && is_empty (line.c_str ()))
00327 continue;
00328
00329 while (!done)
00330 {
00331 ACE_TString newline;
00332 ACE_TString description;
00333
00334 while (0 == (done = (this->getline (fp, newline) == -1)))
00335 if (is_line (newline.c_str ()))
00336 description += newline;
00337 else
00338 break;
00339
00340 if (this->is_entry (name, line.c_str()))
00341 {
00342 ACE_OS::fclose (fp);
00343 return this->fillent (description.c_str ());
00344 }
00345
00346 line = newline;
00347 while (!done && is_empty (line.c_str ()))
00348 done = this->getline (fp, line) == -1;
00349 }
00350
00351 ACE_OS::fclose (fp);
00352 return -1;
00353 }
00354
00355 ACE_END_VERSIONED_NAMESPACE_DECL