Exemple #1
0
temp_init::temp_init()
{
    // First, choose a location for creating temporary files...
    const char *tem;
    // using the first match for any of the environment specs in listed order.
    if (
        (tem = getenv(GROFF_TMPDIR_ENVVAR)) == NULL
        && (tem = getenv(TMPDIR_ENVVAR)) == NULL
#if defined(__MSDOS__) || defined(_WIN32)
        // If we didn't find a match for either of the above
        // (which are preferred, regardless of the host operating system),
        // and we are hosted on either MS-Windows or MS-DOS,
        // then try the Microsoft conventions.
        && (tem = getenv(WIN32_TMPDIR_ENVVAR)) == NULL
        && (tem = getenv(MSDOS_TMPDIR_ENVVAR)) == NULL
#endif
    )
        // If we didn't find an environment spec fall back to this default.
        tem = DEFAULT_TMPDIR;
    size_t tem_len = strlen(tem);
    const char *tem_end = tem + tem_len - 1;
    int need_slash = strchr(DIR_SEPS, *tem_end) == NULL ? 1 : 0;
    char *tem2 = new char[tem_len + need_slash + 1];
    strcpy(tem2, tem);
    if (need_slash)
        strcat(tem2, "/");
    const char *tem3 = TMPFILE_PREFIX_LONG;
    if (file_name_max(tem2) <= 14) {
        tem3 = TMPFILE_PREFIX_SHORT;
        use_short_postfix = 1;
    }
    tmpfile_prefix_len = tem_len + need_slash + strlen(tem3);
    tmpfile_prefix = new char[tmpfile_prefix_len + 1];
    strcpy(tmpfile_prefix, tem2);
    strcat(tmpfile_prefix, tem3);
    a_delete tem2;
}
Exemple #2
0
int main(int argc, char **argv)
{
  program_name = argv[0];
  static char stderr_buf[BUFSIZ];
  setbuf(stderr, stderr_buf);
  
  const char *base_name = 0;
  typedef int (*parser_t)(const char *);
  parser_t parser = do_file;
  const char *directory = 0;
  const char *foption = 0;
  int opt;
  static const struct option long_options[] = {
    { "help", no_argument, 0, CHAR_MAX + 1 },
    { "version", no_argument, 0, 'v' },
    { NULL, 0, 0, 0 }
  };
  while ((opt = getopt_long(argc, argv, "c:o:h:i:k:l:t:n:c:d:f:vw",
			    long_options, NULL))
	 != EOF)
    switch (opt) {
    case 'c':
      common_words_file = optarg;
      break;
    case 'd':
      directory = optarg;
      break;
    case 'f':
      foption = optarg;
      break;
    case 'h':
      check_integer_arg('h', optarg, 1, &hash_table_size);
      if (!is_prime(hash_table_size)) {
	while (!is_prime(++hash_table_size))
	  ;
	warning("%1 not prime: using %2 instead", optarg, hash_table_size);
      }
      break;
    case 'i':
      ignore_fields = optarg;
      break;
    case 'k':
      check_integer_arg('k', optarg, 1, &max_keys_per_item);
      break;
    case 'l':
      check_integer_arg('l', optarg, 0, &shortest_len);
      break;
    case 'n':
      check_integer_arg('n', optarg, 0, &n_ignore_words);
      break;
    case 'o':
      base_name = optarg;
      break;
    case 't':
      check_integer_arg('t', optarg, 1, &truncate_len);
      break;
    case 'w':
      parser = do_whole_file;
      break;
    case 'v':
      printf("GNU indxbib (groff) version %s\n", Version_string);
      exit(0);
      break;
    case CHAR_MAX + 1: // --help
      usage(stdout);
      exit(0);
      break;
    case '?':
      usage(stderr);
      exit(1);
      break;
    default:
      assert(0);
      break;
    }
  if (optind >= argc && foption == 0)
    fatal("no files and no -f option");
  if (!directory) {
    char *path = get_cwd();
    store_filename(path);
    a_delete path;
  }
  else
    store_filename(directory);
  init_hash_table();
  store_filename(common_words_file);
  store_filename(ignore_fields);
  key_buffer = new char[truncate_len];
  read_common_words_file();
  if (!base_name)
    base_name = optind < argc ? argv[optind] : DEFAULT_INDEX_NAME;
  const char *p = strrchr(base_name, DIR_SEPS[0]), *p1;
  const char *sep = &DIR_SEPS[1];
  while (*sep) {
    p1 = strrchr(base_name, *sep);
    if (p1 && (!p || p1 > p))
      p = p1;
    sep++;
  }
  size_t name_max;
  if (p) {
    char *dir = strsave(base_name);
    dir[p - base_name] = '\0';
    name_max = file_name_max(dir);
    a_delete dir;
  }
  else
    name_max = file_name_max(".");
  const char *filename = p ? p + 1 : base_name;
  if (strlen(filename) + sizeof(INDEX_SUFFIX) - 1 > name_max)
    fatal("`%1.%2' is too long for a filename", filename, INDEX_SUFFIX);
  if (p) {
    p++;
    temp_index_file = new char[p - base_name + sizeof(TEMP_INDEX_TEMPLATE)];
    memcpy(temp_index_file, base_name, p - base_name);
    strcpy(temp_index_file + (p - base_name), TEMP_INDEX_TEMPLATE);
  }
  else {
    temp_index_file = strsave(TEMP_INDEX_TEMPLATE);
  }
  catch_fatal_signals();
  int fd = mkstemp(temp_index_file);
  if (fd < 0)
    fatal("can't create temporary index file: %1", strerror(errno));
  indxfp = fdopen(fd, FOPEN_WB);
  if (indxfp == 0)
    fatal("fdopen failed");
  if (fseek(indxfp, sizeof(index_header), 0) < 0)
    fatal("can't seek past index header: %1", strerror(errno));
  int failed = 0;
  if (foption) {
    FILE *fp = stdin;
    if (strcmp(foption, "-") != 0) {
      errno = 0;
      fp = fopen(foption, "r");
      if (!fp)
	fatal("can't open `%1': %2", foption, strerror(errno));
    }
    string path;
    int lineno = 1;
    for (;;) {
      int c;
      for (c = getc(fp); c != '\n' && c != EOF; c = getc(fp)) {
	if (c == '\0')
	  error_with_file_and_line(foption, lineno,
				   "nul character in pathname ignored");
	else
	  path += c;
      }
      if (path.length() > 0) {
	path += '\0';
	if (!(*parser)(path.contents()))
	  failed = 1;
	path.clear();
      }
      if (c == EOF)
	break;
      lineno++;
    }
    if (fp != stdin)
      fclose(fp);
  }
  for (int i = optind; i < argc; i++)
    if (!(*parser)(argv[i]))
      failed = 1;
  write_hash_table();
  if (fclose(indxfp) < 0)
    fatal("error closing temporary index file: %1", strerror(errno));
  char *index_file = new char[strlen(base_name) + sizeof(INDEX_SUFFIX)];    
  strcpy(index_file, base_name);
  strcat(index_file, INDEX_SUFFIX);
#ifdef HAVE_RENAME
#ifdef __EMX__
  if (access(index_file, R_OK) == 0)
    unlink(index_file);
#endif /* __EMX__ */
  if (rename(temp_index_file, index_file) < 0) {
#ifdef __MSDOS__
    // RENAME could fail on plain MSDOS filesystems because
    // INDEX_FILE is an invalid filename, e.g. it has multiple dots.
    char *fname = p ? index_file + (p - base_name) : 0;
    char *dot = 0;

    // Replace the dot with an underscore and try again.
    if (fname
        && (dot = strchr(fname, '.')) != 0
        && strcmp(dot, INDEX_SUFFIX) != 0)
      *dot = '_';
    if (rename(temp_index_file, index_file) < 0)
#endif
    fatal("can't rename temporary index file: %1", strerror(errno));
  }
#else /* not HAVE_RENAME */
  ignore_fatal_signals();
  if (unlink(index_file) < 0) {
    if (errno != ENOENT)
      fatal("can't unlink `%1': %2", index_file, strerror(errno));
  }
  if (link(temp_index_file, index_file) < 0)
    fatal("can't link temporary index file: %1", strerror(errno));
  if (unlink(temp_index_file) < 0)
    fatal("can't unlink temporary index file: %1", strerror(errno));
#endif /* not HAVE_RENAME */
  temp_index_file = 0;
  return failed;
}