Annotation of uae/src/fsdb.c, revision 1.1.1.2

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * Library of functions to make emulated filesystem as independent as
                      5:   * possible of the host filesystem's capabilities.
                      6:   *
                      7:   * Copyright 1999 Bernd Schmidt
                      8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: 
                     13: #include "config.h"
                     14: #include "threaddep/penguin.h"
                     15: #include "options.h"
                     16: #include "uae.h"
                     17: #include "memory.h"
                     18: #include "custom.h"
                     19: #include "readcpu.h"
                     20: #include "newcpu.h"
                     21: #include "filesys.h"
                     22: #include "autoconf.h"
                     23: #include "compiler.h"
                     24: #include "fsusage.h"
                     25: #include "native2amiga.h"
                     26: #include "scsidev.h"
                     27: #include "fsdb.h"
                     28: 
                     29: /* The on-disk format is as follows:
                     30:  * Offset 0, 1 byte, valid
                     31:  * Offset 1, 4 bytes, mode
                     32:  * Offset 5, 257 bytes, aname
                     33:  * Offset 263, 257 bytes, nname
                     34:  * Offset 518, 81 bytes, comment
                     35:  */
                     36: 
                     37: char *nname_begin (char *nname)
                     38: {
                     39:     char *p = strrchr (nname, FSDB_DIR_SEPARATOR);
                     40:     if (p)
                     41:        return p + 1;
                     42:     return nname;
                     43: }
                     44: 
                     45: /* Find the name REL in directory DIRNAME.  If we find a file that
                     46:  * has exactly the same name, return REL.  If we find a file that
                     47:  * has the same name when compared case-insensitively, return a
                     48:  * malloced string that contains the name we found.  If no file
                     49:  * exists that compares equal to REL, return 0.  */
                     50: char *fsdb_search_dir (const char *dirname, char *rel)
                     51: {
                     52:     char *p = 0;
                     53:     struct dirent *de;
                     54:     DIR *dir = opendir (dirname);
                     55: 
                     56:     /* This really shouldn't happen...  */
                     57:     if (! dir)
                     58:        return 0;
                     59:     
                     60:     while (p == 0 && (de = readdir (dir)) != 0) {
                     61:        if (strcmp (de->d_name, rel) == 0)
                     62:            p = rel;
                     63:        else if (strcasecmp (de->d_name, rel) == 0)
                     64:            p = my_strdup (de->d_name);
                     65:     }
                     66:     closedir (dir);
                     67:     return p;
                     68: }
                     69: 
                     70: static FILE *get_fsdb (a_inode *dir, const char *mode)
                     71: {
                     72:     char *n = build_nname (dir->nname, FSDB_FILE);
                     73:     FILE *f = fopen (n, mode);
                     74:     free (n);
                     75:     return f;
                     76: }
                     77: 
                     78: /* Prune the db file the first time this directory is opened in a session.  */
                     79: void fsdb_clean_dir (a_inode *dir)
                     80: {
                     81:     char buf[1 + 4 + 257 + 257 + 81];
                     82:     char *n = build_nname (dir->nname, FSDB_FILE);
                     83:     FILE *f = fopen (n, "r+b");
                     84:     off_t pos1 = 0, pos2 = 0;
                     85: 
                     86:     if (f == 0)
                     87:        return;
                     88:     for (;; pos2 += sizeof buf) {
                     89:        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
                     90:            break;
                     91:        if (buf[0] == 0)
                     92:            continue;
                     93:        if (pos1 != pos2) {
                     94:            fseek (f, pos1, SEEK_SET);
                     95:            fwrite (buf, 1, sizeof buf, f);
                     96:            fseek (f, pos2 + sizeof buf, SEEK_SET);
                     97:        }
                     98:        pos1 += sizeof buf;
                     99:     }
                    100:     fclose (f);
                    101:     truncate (n, pos1);
                    102:     free (n);
                    103: }
                    104: 
                    105: static a_inode *aino_from_buf (a_inode *base, char *buf)
                    106: {
                    107:     uae_u32 mode;
                    108:     a_inode *aino = (a_inode *) xmalloc (sizeof (a_inode));
                    109: 
                    110:     mode = do_get_mem_long ((uae_u32 *)(buf + 1));
                    111:     buf += 5;
                    112:     aino->aname = my_strdup (buf);
                    113:     buf += 257;
                    114:     aino->nname = build_nname (base->nname, buf);
                    115:     buf += 257;
                    116:     aino->comment = *buf != '\0' ? my_strdup (buf) : 0;
                    117:     fsdb_fill_file_attrs (aino);
                    118:     aino->amigaos_mode = mode;
                    119:     aino->has_dbentry = 1;
                    120:     aino->dirty = 0;
                    121:     return aino;
                    122: }
                    123: 
                    124: a_inode *fsdb_lookup_aino_aname (a_inode *base, const char *aname)
                    125: {
                    126:     FILE *f = get_fsdb (base, "rb");
                    127:     if (f == 0)
                    128:        return 0;
                    129:     for (;;) {
                    130:        char buf[1 + 4 + 257 + 257 + 81];
                    131:        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
1.1.1.2 ! root      132:            break;
1.1       root      133:        if (buf[0] == 0)
                    134:            continue;
                    135:        if (same_aname (buf + 5, aname)) {
                    136:            fclose (f);
                    137:            return aino_from_buf (base, buf);
                    138:        }
                    139:     }
                    140:     fclose (f);
                    141:     return 0;
                    142: }
                    143: 
                    144: a_inode *fsdb_lookup_aino_nname (a_inode *base, const char *nname)
                    145: {
                    146:     char buf[1 + 4 + 257 + 257 + 81];
                    147:     FILE *f = get_fsdb (base, "rb");
                    148:     if (f == 0)
                    149:        return 0;
                    150:     for (;;) {
                    151:        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
1.1.1.2 ! root      152:            break;
1.1       root      153:        if (buf[0] == 0)
                    154:            continue;
                    155:        if (strcmp (buf + 5 + 257, nname) == 0) {
                    156:            fclose (f);
                    157:            return aino_from_buf (base, buf);
                    158:        }
                    159:     }
                    160:     fclose (f);
                    161:     return 0;
                    162: }
                    163: 
                    164: int fsdb_used_as_nname (a_inode *base, const char *nname)
                    165: {
                    166:     char buf[1 + 4 + 257 + 257 + 81];
                    167:     FILE *f = get_fsdb (base, "rb");
                    168:     if (f == 0)
                    169:        return 0;
                    170:     for (;;) {
                    171:        if (fread (buf, 1, sizeof buf, f) < sizeof buf)
1.1.1.2 ! root      172:            break;
1.1       root      173:        if (buf[0] == 0)
                    174:            continue;
                    175:        if (strcmp (buf + 5 + 257, nname) == 0) {
                    176:            fclose (f);
                    177:            return 1;
                    178:        }
                    179:     }
                    180:     fclose (f);
                    181:     return 0;
                    182: }
                    183: 
                    184: static int needs_dbentry (a_inode *aino)
                    185: {
                    186:     const char *an_begin, *nn_begin;
                    187: 
                    188:     if (aino->deleted)
                    189:        return 0;
                    190:     
                    191:     if (! fsdb_mode_representable_p (aino) || aino->comment != 0)
                    192:        return 1;
                    193: 
                    194:     nn_begin = nname_begin (aino->nname);
                    195:     return strcmp (nn_begin, aino->aname) != 0;
                    196: }
                    197: 
                    198: static void write_aino (FILE *f, a_inode *aino)
                    199: {
                    200:     char buf[1 + 4 + 257 + 257 + 81];
                    201:     buf[0] = aino->needs_dbentry;
                    202:     do_put_mem_long ((uae_u32 *)(buf + 1), aino->amigaos_mode);
                    203:     strncpy (buf + 5, aino->aname, 256);
                    204:     buf[5 + 256] = '\0';
                    205:     strncpy (buf + 5 + 257, nname_begin (aino->nname), 256);
                    206:     buf[5 + 257 + 256] = '\0';
                    207:     strncpy (buf + 5 + 2*257, aino->comment ? aino->comment : "", 80);
                    208:     buf[5 + 2 * 257 + 80] = '\0';
                    209:     fwrite (buf, 1, sizeof buf, f);
                    210:     aino->has_dbentry = aino->needs_dbentry;
                    211: }
                    212: 
                    213: void fsdb_dir_writeback (a_inode *dir)
                    214: {
                    215:     FILE *f;
                    216:     int changes_needed = 0;
                    217:     a_inode *aino;
                    218: 
                    219:     /* First pass: clear dirty bits where unnecessary, and see if any work
                    220:      * needs to be done.  */
                    221:     for (aino = dir->child; aino; aino = aino->sibling) {
                    222:        if (! aino->dirty)
                    223:            continue;
                    224:        aino->needs_dbentry = needs_dbentry (aino);
1.1.1.2 ! root      225:        if (! aino->needs_dbentry)
1.1       root      226:            aino->dirty = 0;
1.1.1.2 ! root      227:        else
        !           228:            changes_needed = 1;
1.1       root      229:     }
                    230:     if (! changes_needed)
                    231:        return;
                    232: 
                    233:     f = get_fsdb (dir, "r+b");
                    234:     if (f == 0) {
                    235:        f = get_fsdb (dir, "w+b");
                    236:        if (f == 0)
                    237:            /* This shouldn't happen... */
                    238:            return;
                    239:     }
                    240: 
                    241:     for (aino = dir->child; aino; aino = aino->sibling) {
                    242:        off_t pos;
                    243: 
                    244:        if (! aino->dirty)
                    245:            continue;
                    246:        aino->dirty = 0;
                    247:        if (! aino->has_dbentry) {
                    248:            fseek (f, 0, SEEK_END);
                    249:            write_aino (f, aino);
                    250:            continue;
                    251:        }
                    252: 
                    253:        fseek (f, 0, SEEK_SET);
                    254:        pos = 0;
                    255:        for (;;) {
                    256:            char buf[1 + 4 + 257 + 257 + 81];
                    257:            if (fread (buf, 1, sizeof buf, f) < sizeof buf)
                    258:                /* Can't happen... */
                    259:                break;
                    260:            if (strcmp (buf + 5, aino->aname) == 0) {
                    261:                fseek (f, pos, SEEK_SET);
                    262:                write_aino (f, aino);
                    263:                break;
                    264:            }
                    265:            pos += sizeof buf;
                    266:        }
                    267:     }
                    268:     fclose (f);
                    269: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.