00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <eyedbconfig.h>
00025
00026 #include <eyedblib/filelib.h>
00027 #include <eyedblib/rpc_lib.h>
00028 #include <kern_p.h>
00029
00030 #define NEW_FILE_ACCESS
00031
00032 #define ACCESS_FILE_FMT \
00033 "eyedbsm [pid = %d] running under user %s [uid = %d] : "
00034
00035 namespace eyedbsm {
00036 const char *
00037 fileGet(const char *dbfile, const char ext[])
00038 {
00039 #define NN 4
00040 static char file[NN][512];
00041 static int n;
00042 char *p, *s;
00043
00044 if (n == NN)
00045 n = 0;
00046 s = file[n++];
00047 strcpy(s, dbfile);
00048 if (p = strrchr(s, '.'))
00049 *p = 0;
00050 strcat(s, ext);
00051
00052 return s;
00053 }
00054
00055 const char *
00056 shmfileGet(const char *dbfile)
00057 {
00058 return fileGet(dbfile, shmext);
00059 }
00060
00061 const char *
00062 dmpfileGet(const char *volfile)
00063 {
00064 return fileGet(volfile, dmpext);
00065 }
00066
00067 const char *
00068 objmapfileGet(const char *dbfile)
00069 {
00070 return fileGet(dbfile, ompext);
00071 }
00072
00073 Status
00074 checkVolMaxSize(unsigned int maxsize)
00075 {
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091 return Success;
00092 }
00093
00094 Boolean
00095 filelockS(int fd)
00096 {
00097 return ut_file_lock(fd, ut_LOCKS, ut_NOBLOCK) >= 0 ? True : False;
00098 }
00099
00100 Boolean
00101 filelockX(int fd)
00102 {
00103 return ut_file_lock(fd, ut_LOCKX, ut_NOBLOCK) >= 0 ? True : False;
00104 }
00105
00106 Boolean
00107 fileunlock(int fd)
00108 {
00109 return ut_file_unlock(fd) == 0 ? True : False;
00110 }
00111
00112 int
00113 shmfileOpen(const char *dbfile, bool strict_read)
00114 {
00115 int fd = open(shmfileGet(dbfile), strict_read ? O_RDONLY : O_RDWR);
00116
00117
00118 #ifndef NO_FILE_LOCK
00119 #error "NO_FILE_LOCK not defined"
00120 if (ut_file_lock(fd, ut_LOCKS, ut_NOBLOCK) < 0) {
00121 close(fd);
00122 return -1;
00123 }
00124 #endif
00125 return fd;
00126 }
00127
00128 int
00129 objmapfileOpen(const char *dbfile, int flag)
00130 {
00131 int fd = open(objmapfileGet(dbfile), flag);
00132 return fd;
00133 }
00134
00135 Status
00136 syserror(const char *fmt, ...)
00137 {
00138 Status status;
00139 char buf[1024];
00140 int const err = errno;
00141 va_list ap;
00142 va_start(ap, fmt);
00143
00144 if (!fmt)
00145 buf[0] = 0;
00146 else
00147 vsprintf(buf, fmt, ap);
00148
00149 va_end(ap);
00150
00151 if (errno)
00152 return statusMake(SYS_ERROR, "%s: %s", buf,
00153 strerror(err));
00154
00155 return statusMake(SYS_ERROR, "%s", buf);
00156 }
00157
00158 Status
00159 syscheck(const char *pre, long long c, const char *fmt, ...)
00160 {
00161 int const err = errno;
00162 va_list ap;
00163 va_start(ap, fmt);
00164
00165 if (c < 0)
00166 {
00167 Status status;
00168 char buf[256];
00169
00170 if (!fmt)
00171 buf[0] = 0;
00172 else
00173 vsprintf(buf, fmt, ap);
00174
00175 va_end(ap);
00176 return statusMake(SYS_ERROR, "%s%s: errno '%s'", pre, buf,
00177 strerror(err));
00178 }
00179
00180 va_end(ap);
00181 return Success;
00182 }
00183
00184 Status
00185 syscheckn(const char *pre, long long c, int n, const char *fmt, ...)
00186 {
00187 int const err = errno;
00188 va_list ap;
00189 va_start(ap, fmt);
00190
00191 if (c != n)
00192 {
00193 Status status;
00194 char buf[256];
00195
00196 if (!fmt)
00197 buf[0] = 0;
00198 else
00199 vsprintf(buf, fmt, ap);
00200
00201 va_end(ap);
00202 if (c < 0)
00203 return statusMake(SYS_ERROR, "%s%s: errno '%s'", pre, buf,
00204 strerror(err));
00205
00206 return statusMake(SYS_ERROR, "%s%s: invalid size read: %db "
00207 "expected, got %db", pre, buf,
00208 n, c);
00209 }
00210
00211 va_end(ap);
00212 return Success;
00213 }
00214
00215 static const char *
00216 user_get_from_uid(int uid)
00217 {
00218 struct passwd *p = getpwuid(uid);
00219
00220 if (!p)
00221 return "<unknown user>";
00222
00223 return p->pw_name;
00224 }
00225
00226 static const char *
00227 getmsgaccess(unsigned int flags)
00228 {
00229 return (flags == R_OK) ? "read" : "read/write";
00230 }
00231
00232 Status
00233 checkFileAccessFailed(Error err, const char *what, const char *file,
00234 unsigned int flags)
00235 {
00236 int uid = getuid();
00237 const char *user = user_get_from_uid(uid);
00238
00239
00240 if (errno == ENOENT)
00241 return statusMake(err,
00242 ACCESS_FILE_FMT "%s '%s' does not exist",
00243 rpc_getpid(), user, uid, what, file);
00244
00245 return statusMake(err,
00246 ACCESS_FILE_FMT "no %s access on %s '%s'",
00247 rpc_getpid(), user, uid,
00248 getmsgaccess(flags), what, file);
00249 }
00250
00251 Status
00252 checkFileAccess(Error err, const char *what, const char *file,
00253 unsigned int flags)
00254 {
00255 #ifdef NEW_FILE_ACCESS
00256 flags &= ~F_OK;
00257
00258 int fd;
00259
00260 if ((flags & W_OK) != 0) {
00261 fd = open(file, O_RDWR);
00262 }
00263 else {
00264 fd = open(file, O_RDONLY);
00265 }
00266
00267 if (fd >= 0) {
00268 close(fd);
00269 return Success;
00270 }
00271
00272 return checkFileAccessFailed(err, what, file, flags);
00273 #else
00274 if (flags != F_OK) {
00275
00276 if (access(file, F_OK))
00277 return checkFileAccessFailed(err, what, file, F_OK);
00278 }
00279
00280 flags &= ~F_OK;
00281 if (access(file, flags)) {
00282 printf("Access failed for %d\n", flags);
00283 if ((flags & W_OK)) {
00284 privilegeInit();
00285 int fd = open(file, O_RDWR);
00286 if (fd >= 0) {
00287 close(fd);
00288 printf("open OK!\n");
00289 }
00290 }
00291 else {
00292 privilegeInit();
00293 int fd = open(file, O_RDONLY);
00294 if (fd >= 0) {
00295 close(fd);
00296 printf("open OK!\n");
00297 }
00298 }
00299 return checkFileAccessFailed(err, what, file, flags);
00300 }
00301 return Success;
00302 #endif
00303 }
00304
00305 Status
00306 dopen(char const * pre, char const * file, int mode, int * const fdp,
00307 Boolean * const suser)
00308 {
00309 #ifdef NEW_FILE_ACCESS
00310 if ((*fdp = open(file, mode)) >= 0)
00311 return Success;
00312
00313 if (*fdp < 0) {
00314 return statusMake((errno == EACCES) ? INVALID_DBFILE_ACCESS : INVALID_DBFILE, "%sdatabase file '%s'", pre, file);
00315 }
00316
00317 if (suser)
00318 *suser = False;
00319
00320 return Success;
00321 #else
00322 Status s;
00323
00324 if ((*fdp = open(file, mode)) >= 0)
00325 return Success;
00326
00327 if ((s = privilegeAcquire()) != Success)
00328 return s;
00329
00330 *fdp = open(file, mode);
00331
00332 if ((s = privilegeRelease()) != Success)
00333 return s;
00334
00335 if (*fdp < 0) {
00336 return statusMake((errno == EACCES) ? INVALID_DBFILE_ACCESS : INVALID_DBFILE, "%sdatabase file '%s'", pre, file);
00337 }
00338 if (suser)
00339 *suser = False;
00340
00341 return Success;
00342 #endif
00343 }
00344
00345 Status
00346 fileSizesGet(const char *file, unsigned long long &filesize,
00347 unsigned long long &fileblksize)
00348 {
00349 struct stat st;
00350 if (stat(file, &st) < 0)
00351 return statusMake(ERROR, "cannot stat file `%s'", file);
00352
00353 filesize = st.st_size;
00354 fileblksize = st.st_blocks * 512;
00355
00356 return Success;
00357 }
00358
00359 Status
00360 fcouldnot(char const *pre, char const *what, char const *which)
00361 {
00362 int const err = errno;
00363 return statusMake(SYS_ERROR, "%ssystem error reported '%s' "
00364 "while performing %s(%s)",
00365 pre, strerror(err), what, (which ? which : ""));
00366 }
00367
00368 #define PWDMAX 1024
00369
00370 #if 0
00371 Status
00372 push_dir(const char *dbfile, char **pwd)
00373 {
00374 const char *dir = get_dir(dbfile);
00375
00376 if (!*dir) {
00377 *pwd = 0;
00378 return Success;
00379 }
00380
00381 *pwd = getcwd(0, PWDMAX);
00382 if (chdir(dir)) {
00383 free(*pwd);
00384 return statusMake(ERROR, "cannot change to directory '%s'", dir);
00385 }
00386
00387 return Success;
00388 }
00389 #endif
00390
00391 Status
00392 push_dir(const char *dbfile, char *pwd, unsigned int pwd_size)
00393 {
00394 const char *dir = get_dir(dbfile);
00395
00396 if (!*dir) {
00397 *pwd = 0;
00398 return Success;
00399 }
00400
00401 getcwd(pwd, pwd_size);
00402 if (chdir(dir)) {
00403 *pwd = 0;
00404 return statusMake(ERROR, "cannot change to directory '%s'", dir);
00405 }
00406
00407 return Success;
00408 }
00409
00410 Status
00411 pop_dir(char *pwd)
00412 {
00413 if (!pwd) {
00414 return Success;
00415 }
00416
00417 if (chdir(pwd)) {
00418 return statusMake(ERROR, "cannot change to directory '%s'", pwd);
00419 }
00420
00421 #if 0
00422 free(pwd);
00423 #endif
00424 return Success;
00425 }
00426
00427 const char *
00428 get_dir(const char *dbfile)
00429 {
00430 if (*dbfile == '/' && strrchr(dbfile, '/')) {
00431 static char dirname[4][256];
00432 static int dirname_cnt;
00433 char *q;
00434
00435 if (dirname_cnt == 4)
00436 dirname_cnt = 0;
00437
00438 strcpy(dirname[dirname_cnt], dbfile);
00439 q = strrchr(dirname[dirname_cnt], '/');
00440 *q = 0;
00441 return dirname[dirname_cnt++];
00442 }
00443
00444 return "";
00445 }
00446
00447 char *
00448 string_version(unsigned int version)
00449 {
00450 static const char version_fmt[] = "%d.%d.%d";
00451 static char s_version[32];
00452
00453 #define MAJORCOEF 100000
00454 #define MINORCOEF 1000
00455 int major = version/MAJORCOEF;
00456 int minor = (version - major*MAJORCOEF)/MINORCOEF;
00457 int bug_fixed = (version - major*MAJORCOEF - minor*MINORCOEF);
00458
00459 sprintf(s_version, version_fmt, major, minor, bug_fixed);
00460 return s_version;
00461 }
00462
00463 const char *
00464 get_time()
00465 {
00466 time_t t;
00467 char *c;
00468 time(&t);
00469 c = ctime(&t);
00470 c[strlen(c)-1] = 0;
00471 return c;
00472 }
00473
00474 Status
00475 backendInterrupt()
00476 {
00477 backend_interrupt = True;
00478 return Success;
00479 }
00480
00481 Status
00482 backendInterruptReset()
00483 {
00484 backend_interrupt = False;
00485 return Success;
00486 }
00487
00488 void display_invalid_oid(const Oid *oid, ObjectHeader *xobjh)
00489 {
00490 printf("eyedbsm: invalid oid: %s ", getOidString(oid));
00491 printf(", xobjh: %p", xobjh);
00492 if (xobjh) {
00493 printf(" , unique: %d, size: %u [%u]", x2h_u32(xobjh->unique),
00494 x2h_u32(xobjh->size),
00495 x2h_makeValid(xobjh->size));
00496 }
00497 printf("\n");
00498 }
00499
00500 #ifdef DICO_ALG
00501 int
00502 oid_cmp(Oid *a, Oid *b)
00503 {
00504 return (nsOidGet(dbh, a) - nsOidGet(dbh, b));
00505 }
00506 #endif
00507
00508 Boolean
00509 is_number(const char *s)
00510 {
00511 if (!*s)
00512 return False;
00513
00514 char c;
00515 while (c = *s++)
00516 if (!(c >= '0' && c <= '9'))
00517 return False;
00518
00519 return True;
00520 }
00521
00522 size_t
00523 fdSizeGet(int fd)
00524 {
00525 struct stat st;
00526
00527 if (fstat(fd, &st) < 0)
00528 return ~0;
00529
00530 return st.st_size;
00531 }
00532
00533 size_t
00534 fileSizeGet(const char *file)
00535 {
00536 struct stat st;
00537
00538 if (stat(file, &st) < 0)
00539 return ~0;
00540
00541 return st.st_size;
00542 }
00543 }