Esempio n. 1
0
int main(int argc, char **argv)
{
    int c, lockfd, ret = -1;
    int dump=0, scan=0, rebuild=0, prep_upgrade=0, rebuildindexes=0, dumpindexes=0, force=0;
    dbd_flags_t flags = 0;
    char *volpath;
    int cdir;
    AFPObj obj = { 0 };
    struct vol *vol;

    if (geteuid() != 0) {
        usage();
        exit(EXIT_FAILURE);
    }
    /* Inhereting perms in ad_mkdir etc requires this */
    ad_setfuid(0);

    while ((c = getopt(argc, argv, ":cCdefFinrstuvx")) != -1) {
        switch(c) {
        case 'c':
            flags |= DBD_FLAGS_CLEANUP;
            break;
        case 'C':
            flags |= DBD_FLAGS_V2TOEA;
            break;
        case 'd':
            dump = 1;
            break;
        case 'i':
            dumpindexes = 1;
            break;
        case 's':
            scan = 1;
            flags |= DBD_FLAGS_SCAN;
            break;
        case 'n':
            nocniddb = 1; /* FIXME: this could/should be a flag too for consistency */
            break;
        case 'r':
            rebuild = 1;
            break;
        case 't':
            flags |= DBD_FLAGS_STATS;
            break;
        case 'u':
            prep_upgrade = 1;
            break;
        case 'v':
            verbose = 1;
            break;
        case 'e':
            exclusive = 1;
            flags |= DBD_FLAGS_EXCL;
            break;
        case 'x':
            rebuildindexes = 1;
            break;
        case 'f':
            force = 1;
            exclusive = 1;
            flags |= DBD_FLAGS_FORCE | DBD_FLAGS_EXCL;
            break;
        case 'F':
            obj.cmdlineconfigfile = strdup(optarg);
            break;
        case ':':
        case '?':
            usage();
            exit(EXIT_FAILURE);
            break;
        }
    }

    if ((dump + scan + rebuild + prep_upgrade) != 1) {
        usage();
        exit(EXIT_FAILURE);
    }

    if ( (optind + 1) != argc ) {
        usage();
        exit(EXIT_FAILURE);
    }
    volpath = argv[optind];

    setvbuf(stdout, (char *) NULL, _IONBF, 0);

    /* Remember cwd */
    if ((cdir = open(".", O_RDONLY)) < 0) {
        dbd_log( LOGSTD, "Can't open dir: %s", strerror(errno));
        exit(EXIT_FAILURE);
    }
        
    /* Setup signal handling */
    set_signal();

    /* Setup logging. Should be portable among *NIXes */
    if (!verbose)
        setuplog("default:info", "/dev/tty");
    else
        setuplog("default:debug", "/dev/tty");

    /* Load config */
    if (afp_config_parse(&obj, "dbd") != 0) {
        dbd_log( LOGSTD, "Couldn't load afp.conf");
        exit(EXIT_FAILURE);
    }

    if (load_volumes(&obj, NULL) != 0) {
        dbd_log( LOGSTD, "Couldn't load volumes");
        exit(EXIT_FAILURE);
    }

    if ((vol = getvolbypath(&obj, volpath)) == NULL) {
        dbd_log( LOGSTD, "Couldn't find volume for '%s'", volpath);
        exit(EXIT_FAILURE);
    }

    if (load_charset(vol) != 0) {
        dbd_log( LOGSTD, "Couldn't load charsets for '%s'", volpath);
        exit(EXIT_FAILURE);
    }

    pack_setvol(vol);

    if (vol->v_adouble == AD_VERSION_EA)
        dbd_log( LOGDEBUG, "adouble:ea volume");
    else if (vol->v_adouble == AD_VERSION2)
        dbd_log( LOGDEBUG, "adouble:v2 volume");
    else {
        dbd_log( LOGSTD, "unknown adouble volume");
        exit(EXIT_FAILURE);
    }

    /* -C v2 to ea conversion only on adouble:ea volumes */
    if ((flags & DBD_FLAGS_V2TOEA) && (vol->v_adouble!= AD_VERSION_EA)) {
        dbd_log( LOGSTD, "Can't run adouble:v2 to adouble:ea conversion because not an adouble:ea volume");
        exit(EXIT_FAILURE);
    }

    /* Sanity checks to ensure we can touch this volume */
    if (vol->v_vfs_ea != AFPVOL_EA_AD && vol->v_vfs_ea != AFPVOL_EA_SYS) {
        dbd_log( LOGSTD, "Unknown Extended Attributes option: %u", vol->v_vfs_ea);
        exit(EXIT_FAILURE);        
    }

    /* Enuser dbpath is there, create if necessary */
    struct stat st;
    if (stat(vol->v_dbpath, &st) != 0) {
        if (errno != ENOENT) {
            dbd_log( LOGSTD, "Can't stat dbpath \"%s\": %s", vol->v_dbpath, strerror(errno));
            exit(EXIT_FAILURE);        
        }
        if ((mkdir(vol->v_dbpath, 0755)) != 0) {
            dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", vol->v_dbpath, strerror(errno));
            exit(EXIT_FAILURE);
        }        
    }

    /* Put "/.AppleDB" at end of volpath, get path from volinfo file */
    if ( (strlen(vol->v_dbpath) + strlen("/.AppleDB")) > MAXPATHLEN ) {
        dbd_log( LOGSTD, "Volume pathname too long");
        exit(EXIT_FAILURE);        
    }
    strncpy(dbpath, vol->v_dbpath, MAXPATHLEN - strlen("/.AppleDB"));
    strcat(dbpath, "/.AppleDB");

    /* Check or create dbpath */
    int dbdirfd = open(dbpath, O_RDONLY);
    if (dbdirfd == -1 && errno == ENOENT) {
        if (errno == ENOENT) {
            if ((mkdir(dbpath, 0755)) != 0) {
                dbd_log( LOGSTD, "Can't create .AppleDB for \"%s\": %s", dbpath, strerror(errno));
                exit(EXIT_FAILURE);
            }
        } else {
            dbd_log( LOGSTD, "Somethings wrong with .AppleDB for \"%s\", giving up: %s", dbpath, strerror(errno));
            exit(EXIT_FAILURE);
        }
    } else {
        close(dbdirfd);
    }

    /* Get db lock */
    if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1)
        goto exit_noenv;
    if (db_locked != LOCK_EXCL) {
        /* Couldn't get exclusive lock, try shared lock if -e wasn't requested */
        if (exclusive) {
            dbd_log(LOGSTD, "Database is in use and exlusive was requested");
            goto exit_noenv;
        }
        if ((db_locked = get_lock(LOCK_SHRD, NULL)) != LOCK_SHRD)
            goto exit_noenv;
    }

    /* Check if -f is requested and wipe db if yes */
    if ((flags & DBD_FLAGS_FORCE) && rebuild) {
        char cmd[8 + MAXPATHLEN];
        if ((db_locked = get_lock(LOCK_FREE, NULL)) != 0)
            goto exit_noenv;

        snprintf(cmd, 8 + MAXPATHLEN, "rm -rf \"%s\"", dbpath);
        dbd_log( LOGDEBUG, "Removing old database of volume: '%s'", volpath);
        system(cmd);
        if ((mkdir(dbpath, 0755)) != 0) {
            dbd_log( LOGSTD, "Can't create dbpath \"%s\": %s", dbpath, strerror(errno));
            exit(EXIT_FAILURE);
        }
        dbd_log( LOGDEBUG, "Removed old database.");
        if ((db_locked = get_lock(LOCK_EXCL, dbpath)) == -1)
            goto exit_noenv;
    }

    /* 
       Lets start with the BerkeleyDB stuff
    */
    if ( ! nocniddb) {
        if ((dbd = dbif_init(dbpath, "cnid2.db")) == NULL)
            goto exit_noenv;
        
        if (dbif_env_open(dbd,
                          &db_param,
                          (db_locked == LOCK_EXCL) ? (DBOPTIONS | DB_RECOVER) : DBOPTIONS) < 0) {
            dbd_log( LOGSTD, "error opening database!");
            goto exit_noenv;
        }

        if (db_locked == LOCK_EXCL)
            dbd_log( LOGDEBUG, "Finished recovery.");

        if (dbif_open(dbd, NULL, rebuildindexes) < 0) {
            dbif_close(dbd);
            goto exit_failure;
        }

        /* Prepare upgrade ? We're done */
        if (prep_upgrade) {
            (void)dbif_txn_close(dbd, 1);
            goto cleanup;
        }
    }

    /* Downgrade db lock if not running exclusive */
    if (!exclusive && (db_locked == LOCK_EXCL)) {
        if (get_lock(LOCK_UNLOCK, NULL) != 0)
            goto exit_failure;
        if (get_lock(LOCK_SHRD, NULL) != LOCK_SHRD)
            goto exit_failure;
    }

    /* Now execute given command scan|rebuild|dump */
    if (dump && ! nocniddb) {
        if (dbif_dump(dbd, dumpindexes) < 0) {
            dbd_log( LOGSTD, "Error dumping database");
        }
    } else if ((rebuild && ! nocniddb) || scan) {
        if (cmd_dbd_scanvol(dbd, vol, flags) < 0) {
            dbd_log( LOGSTD, "Error repairing database.");
        }
    }

cleanup:
    /* Cleanup */
    dbd_log(LOGDEBUG, "Closing db");
    if (! nocniddb) {
        if (dbif_close(dbd) < 0) {
            dbd_log( LOGSTD, "Error closing database");
            goto exit_failure;
        }
    }

exit_success:
    ret = 0;

exit_failure:
    if (dbif_env_remove(dbpath) < 0) {
        dbd_log( LOGSTD, "Error removing BerkeleyDB database environment");
        ret++;
    }
    get_lock(0, NULL);

exit_noenv:    
    if ((fchdir(cdir)) < 0)
        dbd_log(LOGSTD, "fchdir: %s", strerror(errno));

    if (ret == 0)
        exit(EXIT_SUCCESS);
    else
        exit(EXIT_FAILURE);
}
Esempio n. 2
0
int
main(int argc, char **argv)
{
   FILE *file;

   cons_CharsetEntry *cp = 0;

   int len = 0, i, mb = 0;

   char buf[4096];

   UniRecord *rp;

   /* unicode-order */
   Coll uni;

   /* charset-order */
   Coll cs;

   Coll out;

   Coll cmp;

   char *fname;

   if (argc < 2)
   {
      fprintf(stderr, "usage: %s charset_file [cs_file1...] < unicode_data\n", argv[0]);
      exit(1);
   }

   for (i = 1; i < argc; i++)
   {
      fname = argv[i];
      file = fopen(fname, "r");
      if (!file)
      {
	 fprintf(stderr, "cannot open %s: %s\n", fname, strerror(errno));
	 exit(2);
      }

      fprintf(stderr, "load charset '%s'\n", fname);
      if (load_charset(file, &cp, &len))
      {
	 fprintf(stderr, "cannot read %s: %s\n", fname, strerror(errno));
	 exit(3);
      }
      fprintf(stderr, "loaded %d entries\n", len);
      fclose(file);
#ifdef DBG
      fprintf(stderr, "readed %d charset entries\n", len);
#endif
   }

   init_Coll(&uni, 0, cmp_UniRecord);
   init_Coll(&cs, 0, cmp_CSRecord);
   init_Coll(&out, 0, 0);
   init_Coll(&cmp, 0, cmp_UniRecord);

   while (fgets(buf, sizeof(buf), stdin))
   {
      int l;

      char *s;

      rp = (UniRecord *) calloc(1, sizeof(*rp));
      l = strlen(buf);
      if (l > 0 && buf[--l] == '\n')
	 buf[l] = 0;
      if (!l)
	 break;

      s = strdup(buf);
		rp->mem_of_UniRecord = s;

		rp->hex_of_UniRecord = s;
		rp->no_of_UniRecord = strtoul(s, 0, 16);
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->name_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->cat_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->comb_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->bidir_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->decomp_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->dec_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->dig_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->num_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->mirror_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->name1_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->comment_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->upper_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->lower_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->title_of_UniRecord = s;
      l = strcspn(s, ";");
      s += l;
      *s++ = 0;

		rp->cp_of_UniRecord = in_map(cp, len, rp->no_of_UniRecord);
		if (rp->cp_of_UniRecord)
      {
			remove_char(&uni, rp->cp_of_UniRecord->ch_of_cons_CharsetEntry);
			remove_char(&cs, rp->cp_of_UniRecord->ch_of_cons_CharsetEntry);
	 insert_Coll(&uni, rp);
	 insert_Coll(&cs, rp);
      }
      else
      {
			free(rp->mem_of_UniRecord);
	 free(rp);
      }
   }
   fprintf(stderr, "appended %d uni %d chars\n", uni.count_of_Coll, cs.count_of_Coll);

#ifdef DBG
fprintf(stderr, "uni: %d\n", uni.count_of_Coll);
for (i = 0; i < uni.count_of_Coll; i++)
   {
      rp = (UniRecord *) uni.items[i];
		fprintf(stderr, "hex; 	'%s'\n", rp->hex_of_UniRecord);
		fprintf(stderr, "name;   '%s'\n", rp->name_of_UniRecord);
		fprintf(stderr, "cat;    '%s'\n", rp->cat_of_UniRecord);
		fprintf(stderr, "comb;   '%s'\n", rp->comb_of_UniRecord);
		fprintf(stderr, "bidir;  '%s'\n", rp->bidir_of_UniRecord);
		fprintf(stderr, "decomp; '%s'\n", rp->decomp_of_UniRecord);
		fprintf(stderr, "dec;    '%s'\n", rp->dec_of_UniRecord);
		fprintf(stderr, "dig;    '%s'\n", rp->dig_of_UniRecord);
		fprintf(stderr, "num;    '%s'\n", rp->num_of_UniRecord);
		fprintf(stderr, "mirror; '%s'\n", rp->mirror_of_UniRecord);
		fprintf(stderr, "name1;  '%s'\n", rp->name1_of_UniRecord);
		fprintf(stderr, "comment;'%s'\n", rp->comment_of_UniRecord);
		fprintf(stderr, "upper;  '%s'\n", rp->upper_of_UniRecord);
		fprintf(stderr, "lower;  '%s'\n", rp->lower_of_UniRecord);
		fprintf(stderr, "title;  '%s'\n", rp->title_of_UniRecord);
      fprintf(stderr, "\n");
   }
#endif
#ifdef DBG1
fprintf(stderr, "cs: %d\n", cs.count_of_Coll);
for (i = 0; i < cs.count_of_Coll; i++)
   {
      rp = (UniRecord *) cs.items[i];
		fprintf(stderr, "ch=%d\n", rp->cp_of_UniRecord->ch_of_cons_CharsetEntry);
		fprintf(stderr, "hex; 	'%s'\n", rp->hex_of_UniRecord);
		fprintf(stderr, "name;   '%s'\n", rp->name_of_UniRecord);
		fprintf(stderr, "cat;    '%s'\n", rp->cat_of_UniRecord);
		fprintf(stderr, "comb;   '%s'\n", rp->comb_of_UniRecord);
		fprintf(stderr, "bidir;  '%s'\n", rp->bidir_of_UniRecord);
		fprintf(stderr, "decomp; '%s'\n", rp->decomp_of_UniRecord);
		fprintf(stderr, "dec;    '%s'\n", rp->dec_of_UniRecord);
		fprintf(stderr, "dig;    '%s'\n", rp->dig_of_UniRecord);
		fprintf(stderr, "num;    '%s'\n", rp->num_of_UniRecord);
		fprintf(stderr, "mirror; '%s'\n", rp->mirror_of_UniRecord);
		fprintf(stderr, "name1;  '%s'\n", rp->name1_of_UniRecord);
		fprintf(stderr, "comment;'%s'\n", rp->comment_of_UniRecord);
		fprintf(stderr, "upper;  '%s'\n", rp->upper_of_UniRecord);
		fprintf(stderr, "lower;  '%s'\n", rp->lower_of_UniRecord);
		fprintf(stderr, "title;  '%s'\n", rp->title_of_UniRecord);
      fprintf(stderr, "\n");
   }
#endif

   for (i = 0; i < 256; i++)
   {
      UniRecord *rp = find_ch(&cs, i);

      if (!rp)
      {
	 cons_CharsetEntry *cp = (cons_CharsetEntry *) calloc(sizeof(cons_CharsetEntry *), 1);

	 rp = (UniRecord *) calloc(sizeof(UniRecord), 1);
	 rp->no_of_UniRecord = i;
	 rp->ch_of_UniRecord = i;
	 cp->ch_of_cons_CharsetEntry = i;
	 cp->unich_of_cons_CharsetEntry = i;
	 rp->cp_of_UniRecord = cp;
	 rp->hex_of_UniRecord = "";
	 rp->name_of_UniRecord = "";
	 rp->cat_of_UniRecord = "";
	 rp->comb_of_UniRecord = "";
	 rp->bidir_of_UniRecord = "";
	 rp->decomp_of_UniRecord = "";
	 rp->dec_of_UniRecord = "";
	 rp->dig_of_UniRecord = "";
	 rp->num_of_UniRecord = "";
	 rp->mirror_of_UniRecord = "";
	 rp->name1_of_UniRecord = "";
	 rp->comment_of_UniRecord = "";
	 rp->upper_of_UniRecord = "";
	 rp->lower_of_UniRecord = "";
	 rp->title_of_UniRecord = "";
      }
            if (rp->cp_of_UniRecord->ch_of_cons_CharsetEntry < 256)
      {
	 append_Coll(&out, rp);
	 insert_Coll(&cmp, rp);
      }
   }

#ifdef DBG3
fprintf(stderr, "cmp: %d\n", cmp.count_of_Coll);
for (i = 0; i < cmp.count_of_Coll; i++)
   {
		rp = (UniRecord *) cmp.items_of_Coll[i];
		fprintf(stderr, "ch=%d\n", rp->cp_of_UniRecord->ch_of_cons_CharsetEntry);
		fprintf(stderr, "hex; 	'%s'\n", rp->hex_of_UniRecord);
		fprintf(stderr, "name;   '%s'\n", rp->name_of_UniRecord);
		fprintf(stderr, "cat;    '%s'\n", rp->cat_of_UniRecord);
		fprintf(stderr, "comb;   '%s'\n", rp->comb_of_UniRecord);
		fprintf(stderr, "bidir;  '%s'\n", rp->bidir_of_UniRecord);
		fprintf(stderr, "decomp; '%s'\n", rp->decomp_of_UniRecord);
		fprintf(stderr, "dec;    '%s'\n", rp->dec_of_UniRecord);
		fprintf(stderr, "dig;    '%s'\n", rp->dig_of_UniRecord);
		fprintf(stderr, "num;    '%s'\n", rp->num_of_UniRecord);
		fprintf(stderr, "mirror; '%s'\n", rp->mirror_of_UniRecord);
		fprintf(stderr, "name1;  '%s'\n", rp->name1_of_UniRecord);
		fprintf(stderr, "comment;'%s'\n", rp->comment_of_UniRecord);
		fprintf(stderr, "upper;  '%s'\n", rp->upper_of_UniRecord);
		fprintf(stderr, "lower;  '%s'\n", rp->lower_of_UniRecord);
		fprintf(stderr, "title;  '%s'\n", rp->title_of_UniRecord);
      fprintf(stderr, "\n");
   }
#endif

   printf("# generated by gen_tbl from sources");
   for (i = 1; i < argc; i++)
      printf(" %s", argv[i]);
   printf("\n# cmptbl\n");
   for (i = 0; i < 256; i++)
   {
      int ch;

      ch = find_cmp(&cmp, i);
      printf("%d\n", ch);
   }
   printf("# uptbl\n");
	for (i = 0; i < out.count_of_Coll; i++)
   {
      UniRecord *rp1;

      int ch;

		rp = (UniRecord *) out.items_of_Coll[i];
      if (!rp)
      {
	 printf("%d\n", i);
	 continue;
      }
      if (!strcasecmp(rp->cat_of_UniRecord, "Ll") && rp->upper_of_UniRecord)
      {
			unsigned long unich = strtoul(rp->upper_of_UniRecord, 0, 16);

	 rp1 = find_uni(&uni, unich);
	 if (rp1)
		 ch = rp1->cp_of_UniRecord->ch_of_cons_CharsetEntry;
	 else
		 ch = rp->cp_of_UniRecord->ch_of_cons_CharsetEntry;
      }
      else
			ch = rp->cp_of_UniRecord->ch_of_cons_CharsetEntry;

      printf("%d\n", ch);
   }

   printf("# lowtbl\n");
	for (i = 0; i < out.count_of_Coll; i++)
   {
      UniRecord *rp1;

      int ch;

		rp = (UniRecord *) out.items_of_Coll[i];
      if (!rp)
      {
	 printf("%d\n", i);
	 continue;
      }
      if (!strcasecmp(rp->cat_of_UniRecord, "Lu") && rp->lower_of_UniRecord)
      {
			unsigned long unich = strtoul(rp->lower_of_UniRecord, 0, 16);

	 rp1 = find_uni(&uni, unich);
	 if (rp1)
		 ch = rp1->cp_of_UniRecord->ch_of_cons_CharsetEntry;
	 else
		 ch = rp->cp_of_UniRecord->ch_of_cons_CharsetEntry;
      }
      else
			ch = rp->cp_of_UniRecord->ch_of_cons_CharsetEntry;

      printf("%d\n", ch);
   }

   printf("# isalpha\n");
	for (i = 0; i < out.count_of_Coll; i++)
   {
      int r = 0;

      char *s;

		rp = (UniRecord *) out.items_of_Coll[i];
      if (!rp)
      {
	 printf("0\n");
	 continue;
      }
      s = rp->cat_of_UniRecord;
      if (s && s[0] == 'L')
	 r = 1;
      printf("%d\n", r);
   }

   printf("# pgtbl\n");
	for (i = 0; i < out.count_of_Coll; i++)
   {
      int r = 0;

      char *s;

		rp = (UniRecord *) out.items_of_Coll[i];
      if (!rp)
      {
	 printf("0\n");
	 continue;
      }
      s = rp->cat_of_UniRecord;
		if (!strcmp(s, "So") && rp->no_of_UniRecord >= 0x2500 && rp->no_of_UniRecord < 0x25ff)
			r = pg_chars[rp->no_of_UniRecord - 0x2500];
      printf("%d\n", r);
   }

   printf("# multibyte\n%d\n", mb ? 1 : 0);

   return 0;
}