char *cue_locate_audio_container_file(const char *pathname,unsigned tnum)
{
    char *cue_filename=g_strdup(pathname);
    char *container_filename=NULL;

    // make sure we're trying to work against a file ending with ".cue"

    // if file does't exists, assume it's virtual and try moving up one level
    // to find the actual cue file''
    if (	 access (cue_filename, R_OK) != 0 ) {
        remove_suffix(cue_filename,'/');
        if (  !g_str_has_suffix(cue_filename,".cue")) {
            return NULL;
        }
    }

    // check that we ere either passed a filename ending in ".cue"
    // or located one above, based on what was passed.

    if  ( ! g_str_has_suffix(cue_filename,".cue"))
        return NULL;

    // get filename referenced inside cue file
    container_filename=cue_file_get_filename(cue_filename,tnum);
    g_free(cue_filename);
    if(container_filename != NULL )  {
        char *directory = g_strdup(pathname);
        remove_suffix(directory, '/');
        container_filename=g_strconcat(directory,"/", container_filename,NULL);
        g_free(directory);
    }

    // file was located in the same directory as cue file
    if ( access (container_filename, R_OK) ==0 )
        return container_filename;

    g_free(container_filename);

    // Now, try to guess the audio/container filename by removing the cue suffix
    // "CDImage.flac.cue"
    container_filename = g_strdup(pathname);
    remove_suffix(container_filename, '.');

    if ( access (container_filename, R_OK) !=0
       ) {
        g_free(container_filename);
        return NULL;
    }

    return container_filename;

}
Пример #2
0
const_string *
kpathsea_fontmap_lookup (kpathsea kpse, const_string key)
{
  const_string *ret;
  string suffix = find_suffix (key);

  if (kpse->map.size == 0) {
    read_all_maps (kpse);
  }

  ret = (const_string *) hash_lookup (kpse->map, key);
  if (!ret) {
    /* OK, the original KEY didn't work.  Let's check for the KEY without
       an extension -- perhaps they gave foobar.tfm, but the mapping only
       defines `foobar'.  */
    if (suffix) {
      string base_key = remove_suffix (key);
      ret = (const_string *) hash_lookup (kpse->map, base_key);
      free (base_key);
    }
  }

  /* Append any original suffix.  */
  if (ret && suffix) {
    const_string *elt;
    for (elt = ret; *elt; elt++) {
      *elt = extend_filename (*elt, suffix);
    }
  }

  return ret;
}
Пример #3
0
static void
feel_1_browse(struct name_list *el)
{
    char *title;

    if (el == NULL)
        return;
    title = el->name;
    if (title[0] == '\\')	/* directory */
    {
        if (vs.drawer[strlen(vs.drawer)-1] == '\\')  /* aviod double slash */
            title++;
        if (!dir_too_long(vs.drawer, title))
        {
            strcat(vs.drawer, title);
            new_bdrawer();
        }
    }
    else if (title[0] != 0)
    {
        strcpy(vs.file, title);
        strcpy(cpi_name, title);
        if (got_suffix(vs.file))
            remove_suffix(vs.file);
    }
}
Пример #4
0
void set_logfile(const char *file)
{
	char *path;
	char _path[1024] = {};
	char tmp[1024] = {};
	int v_haspath = has_path(file);

	if (!v_haspath)
	{
		if ((path = getenv("LOG")) == NULL && (path = getenv("log")) == NULL)
			memcpy(_path, " ", 1);
		else
		{
			memcpy(_path, path, strlen(path));
			if (_path[strlen(path) - 1] != '/' || _path[strlen(path) - 1] != '\\')
			{
				_path[strlen(path)] = '/';
				_path[strlen(path) + 1] = 0;
			}
		}
	}

	memset(debugfile, 0, sizeof(debugfile));
	remove_suffix(file, tmp);
	if (v_haspath)
		sprintf(debugfile, "%s.log", tmp);
	else
		sprintf(debugfile, "%s/%s.log", _path, tmp);
}
Пример #5
0
string
make_stem_suffix (string name, string stem_suffix)
{
    string suffix = find_suffix (name);

    name = remove_suffix (name);

    return suffix == NULL
           ? concat (name, stem_suffix)
           : concat4 (name, stem_suffix, ".", suffix);
}
Пример #6
0
int main(int argc, char *argv[])
{
    char *line;

    if (argc == 2 || argc == 3) {
	strip_trailing_slashes(argv[1]);
	line = basename(argv[1]);
	if (argc == 3)
	    remove_suffix(line, argv[2]);
	write(STDOUT_FILENO, line, strlen(line));
	write(STDOUT_FILENO, "\n", 1);
    }
    
    return 0;
}
Пример #7
0
static void
draw_cpi_name(Flicmenu *m)
{
    char buf[81];

    /* deal with auto-extending BS to make up cpi_name */
    strcpy(cpi_name, vs.file);
    if (got_suffix(cpi_name))
        remove_suffix(cpi_name);
    strcpy(buf, cpi_name);
    strcat(cpi_name, ".FLI");
    buf[8] = 0;	/* just make sure not too long... */
    m->text = buf;
    blacktext(m);
}
Пример #8
0
      std::string operator()(const utils::piece& word)
      {
	icu::UnicodeString uword = icu::UnicodeString::fromUTF8(icu::StringPiece(word.data(), word.size()));
	
	normalize_ya_alef_maqsoura(uword);
	
	normalize_aggressive(uword);
	
	remove_prefix(uword);
	
	remove_suffix(uword);
	
	std::string word_stemmed;
	uword.toUTF8String(word_stemmed);
	
	return word_stemmed;
      }
Пример #9
0
tree
create_tmp_var_name (const char *prefix)
{
  char *tmp_name;

  if (prefix)
    {
      char *preftmp = ASTRDUP (prefix);

      remove_suffix (preftmp, strlen (preftmp));
      clean_symbol_name (preftmp);

      prefix = preftmp;
    }

  ASM_FORMAT_PRIVATE_NAME (tmp_name, prefix ? prefix : "T", tmp_var_id_num++);
  return get_identifier (tmp_name);
}
static struct tag *
cue_cue_tag_load(const char *file,	const unsigned int tnum)
{
    struct tag* tag = NULL;
    char* char_tnum = NULL;
    char* ptr = NULL;
    //	unsigned int sample_rate = 0;
#ifdef HAVE_CUE /* libcue */
    FILE* cs_file;
#endif /* libcue */

    ptr = g_strdup(file);
    remove_suffix(ptr,'/');

#ifdef HAVE_CUE /* libcue */

    cs_file = fopen(ptr, "rt");
    g_free(ptr);
    if (cs_file != NULL) {
        tag = cue_tag_file(cs_file, tnum);
        fclose(cs_file);
    }
#else
    g_free(ptr);
#endif /* libcue */

    if (tag == NULL)
        return NULL;

    char_tnum = g_strdup_printf("%u", tnum);

    if (char_tnum != NULL) {
        tag_add_item(tag, TAG_TRACK, char_tnum);
        g_free(char_tnum);
    }

    //	if (sample_rate != 0)
    //	{
    //		tag->time = (unsigned int)(track_time/sample_rate);
    //	}

    return tag;
}
long cue_container_track_times(const char* pathname,const unsigned int tnum, int flag)
{
    struct Cd *cd=NULL;
    unsigned int n_tracks=0;
    long time_ms=0;

    char *cue_filename=g_strdup(pathname);
    remove_suffix(cue_filename,'/');


    // check that filename ends in .cue
    // check that cue file actually exists
    // check that we succesfuly parse the cue file
    if ( !g_str_has_suffix(cue_filename,".cue")
            || 0 != access (cue_filename, R_OK)
            ||  (( cd = cue_get_cd(cue_filename) ) == NULL)) {
        g_free(cue_filename);
        return 0;
    }

    g_free(cue_filename);

    n_tracks=(unsigned) cd_get_ntrack(cd);

    if ( tnum <= n_tracks && flag == 0 ) {
        // return start time of track
        struct Track * tr = cd_get_track(cd, tnum);
        time_ms =  (track_get_start(tr) );
        time_ms*= 1000.0 /75.0;
        free(tr);
    } else if ( tnum < n_tracks && flag == 1  ) {
        // return end time of track, for all but the last track
        struct Track * tr = cd_get_track(cd, tnum);
        time_ms = track_get_start(tr);
        time_ms+=track_get_length(tr);
        time_ms =time_ms*1000.0 /75.0;
        free(tr);
    }

    return time_ms;

}
Пример #12
0
/* kpse:lookup("plain.tex", {}) */
static int do_lua_kpathsea_lookup(lua_State * L, kpathsea kpse, int idx)
{
    int i;
    string ret = NULL;
    string *ret_list = NULL;
    const_string name = NULL;
    string user_path = NULL;
    boolean show_all = false;
    boolean must_exist = false;
    kpse_file_format_type user_format = kpse_last_format;
    int dpi = 600;
    str_list_type subdir_paths = { 0, NULL };
    unsigned saved_debug = kpse->debug;
    int saved_mktexpk = kpse->format_info[kpse_pk_format].program_enabled_p;
    int saved_mktexmf = kpse->format_info[kpse_mf_format].program_enabled_p;
    int saved_mktextex = kpse->format_info[kpse_tex_format].program_enabled_p;
    int saved_mktextfm = kpse->format_info[kpse_tfm_format].program_enabled_p;
    name = luaL_checkstring(L, idx);
    /* todo: fetch parameter values */

    if (lua_type(L, idx + 1) == LUA_TTABLE) {
        lua_pushstring(L, "format");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TSTRING) {
            int op = luaL_checkoption(L, -1, NULL, filetypenames);
            user_format = filetypes[op];
        }
        lua_pop(L, 1);
        lua_pushstring(L, "dpi");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TNUMBER) {
            dpi = (int) lua_tointeger(L, -1);
        }
        lua_pop(L, 1);
        lua_pushstring(L, "debug");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TNUMBER) {
            int d = 0;
            d = (int) lua_tointeger(L, -1);
            kpse->debug |= d;
        }
        lua_pop(L, 1);
        lua_pushstring(L, "path");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TSTRING) {
            user_path = xstrdup(lua_tostring(L, -1));
        }
        lua_pop(L, 1);
        lua_pushstring(L, "all");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            show_all = lua_toboolean(L, -1);
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktexpk");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "pk", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktextex");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "tex", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktexmf");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "mf", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);

        lua_pushstring(L, "mktextfm");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            kpathsea_maketex_option(kpse, "tfm", lua_toboolean(L, -1));
        }
        lua_pop(L, 1);


        lua_pushstring(L, "mustexist");
        lua_gettable(L, idx + 1);
        if (lua_type(L, -1) == LUA_TBOOLEAN) {
            must_exist = lua_toboolean(L, -1);
        }
        lua_pop(L, 1);
        lua_pushstring(L, "subdir");
        lua_gettable(L, idx + 1);
        if (lua_istable(L, -1)) {
            lua_pushnil(L);
            while (lua_next(L, -2) != 0) {      /* numeric value */
                if (lua_type(L, -1) == LUA_TSTRING) {
                    char *s = xstrdup(lua_tostring(L, -1));
                    str_list_add(&subdir_paths, s);
                    xfree(s);
                }
                lua_pop(L, 1);
            }
        } else if (lua_type(L, -1) == LUA_TSTRING) {
            char *s = xstrdup(lua_tostring(L, -1));
            str_list_add(&subdir_paths, s);
            xfree(s);
        }
        lua_pop(L, 1);
        if (STR_LIST_LENGTH(subdir_paths) > 0) {
            show_all = 1;
        }
    }
    if (user_path) {
        /* Translate ; to : if that's our ENV_SEP.  See cnf.c.  */
        if (IS_ENV_SEP(':')) {
            string loc;
            for (loc = user_path; *loc; loc++) {
                if (*loc == ';')
                    *loc = ':';
            }
        }
        user_path = kpathsea_path_expand(kpse, user_path);
        if (show_all) {
            ret_list = kpathsea_all_path_search(kpse, user_path, name);
        } else {
            ret = kpathsea_path_search(kpse, user_path, name, must_exist);
        }
        free(user_path);
    } else {
        /* No user-specified search path, check user format or guess from NAME.  */
        kpse_file_format_type fmt;
        if (user_format != kpse_last_format)
            fmt = user_format;
        else
            fmt = find_format(kpse, name, true);

        switch (fmt) {
        case kpse_pk_format:
        case kpse_gf_format:
        case kpse_any_glyph_format:
            {
                kpse_glyph_file_type glyph_ret;
                string temp = remove_suffix (name);
                /* Try to extract the resolution from the name.  */
                unsigned local_dpi = find_dpi(name);
                if (!local_dpi)
                    local_dpi = (unsigned) dpi;
                ret =
                    kpathsea_find_glyph(kpse, temp, local_dpi,
                                        fmt, &glyph_ret);
                if (temp != name)
                    free (temp);
            }
            break;

        case kpse_last_format:
            /* If the suffix isn't recognized, assume it's a tex file. */
            fmt = kpse_tex_format;
            /* fall through */

        default:
            if (show_all) {
                ret_list =
                    kpathsea_find_file_generic(kpse, name, fmt, must_exist,
                                               true);
            } else {
                ret = kpathsea_find_file(kpse, name, fmt, must_exist);
            }
        }
    }

    /* Turn single return into a null-terminated list for uniform treatment.  */
    if (ret) {
        ret_list = XTALLOC(2, string);
        ret_list[0] = ret;
        ret_list[1] = NULL;
    }

    /* Filter by subdirectories, if specified.  */
    if (STR_LIST_LENGTH(subdir_paths) > 0) {
        string *new_list = subdir_match(subdir_paths, ret_list);
        free(ret_list);
        ret_list = new_list;
    }
    kpse->debug = saved_debug;
    kpse->format_info[kpse_pk_format].program_enabled_p = saved_mktexpk;
    kpse->format_info[kpse_mf_format].program_enabled_p = saved_mktexmf;
    kpse->format_info[kpse_tex_format].program_enabled_p = saved_mktextex;
    kpse->format_info[kpse_tfm_format].program_enabled_p = saved_mktextfm;

    /* Print output.  */
    i = 0;
    if (ret_list) {
        for (; ret_list[i]; i++) {
            lua_pushstring(L, ret_list[i]);
        }
        free(ret_list);
    }
    if (i == 0) {
        i++;
        lua_pushnil(L);
    }
    return i;
}
Пример #13
0
void
kpse_set_program_name P2C(const_string, argv0, const_string, progname)
{
  string ext, sdir, sdir_parent, sdir_grandparent;
  string s = getenv ("KPATHSEA_DEBUG");
#ifdef WIN32
  string debug_output = getenv("KPATHSEA_DEBUG_OUTPUT");
  string append_debug_output = getenv("KPATHSEA_DEBUG_APPEND");
  int err, olderr;
#endif
  
  /* Set debugging stuff first, in case we end up doing debuggable stuff
     during this initialization.  */
  if (s) {
    kpathsea_debug |= atoi (s);
  }

#ifndef HAVE_PROGRAM_INVOCATION_NAME
#if defined(WIN32)
  /* Set various info about user. Among many things,
     ensure that HOME is set. If debug_paths is on, 
     turn on some message if $HOME is not found. */
  if (KPSE_DEBUG_P(KPSE_DEBUG_PATHS)) {
    set_home_warning();
  }
  init_user_info();

  /* redirect stderr to debug_output. Easier to send logfiles. */
  if (debug_output) {
    int flags =  _O_CREAT | _O_TRUNC | _O_RDWR;
    err = -1;
    if (_stricmp(debug_output, "con") == 0
       || _stricmp(debug_output, "con:") == 0) {
      err = _fileno(stdout);
    } else {
      if (append_debug_output) {
        flags =  _O_CREAT | _O_APPEND | _O_WRONLY;
      } else {
        flags =  _O_CREAT | _O_TRUNC | _O_WRONLY;
        xputenv("KPATHSEA_DEBUG_APPEND", "yes");
      }
    }

    if ((err < 0)
        && (err = _open(debug_output, flags, _S_IREAD | _S_IWRITE)) == -1)
    {
      WARNING1("Can't open %s for stderr redirection!\n", debug_output);
      perror(debug_output);
    } else if ((olderr = _dup(fileno(stderr))) == -1) {
      WARNING("Can't dup() stderr!\n");
      close(err);
    } else if (_dup2(err, fileno(stderr)) == -1) {
      WARNING1("Can't redirect stderr to %s!\n", debug_output);
      close(olderr);
      close(err);
    } else {
      close(err);
    }
  }
  /* Win95 always gives the short filename for argv0, not the long one.
     There is only this way to catch it. It makes all the selfdir stuff
     useless for win32. */
  {
    char short_path[PATH_MAX], path[PATH_MAX], *fp;
      
    /* SearchPath() always gives back an absolute directory */
    if (SearchPath(NULL, argv0, ".exe", PATH_MAX, short_path, &fp) == 0)
        FATAL1("Can't determine where the executable %s is.\n", argv0);
    if (!win32_get_long_filename(short_path, path, sizeof(path))) {
        FATAL1("This path points to an invalid file : %s\n", short_path);
    }
    /* slashify the dirname */
    for (fp = path; fp && *fp; fp++)
        if (IS_DIR_SEP(*fp)) *fp = DIR_SEP;
    /* sdir will be the directory of the executable, ie: c:/TeX/bin */
    sdir = xdirname(path);
    program_invocation_name = xstrdup(xbasename(path));
  }

#elif defined(__DJGPP__)

  /* DJGPP programs support long filenames on Windows 95, but ARGV0 there
     is always made with the short 8+3 aliases of all the pathname elements.
     If long names are supported, we need to convert that to a long name.

     All we really need is to call `_truename', but most of the code
     below is required to deal with the special case of networked drives.  */
  if (pathconf (argv0, _PC_NAME_MAX) > 12) {
    char long_progname[PATH_MAX];

    if (_truename (argv0, long_progname)) {
      char *fp;

      if (long_progname[1] != ':') {
	/* A complication: `_truename' returns network-specific string at
	   the beginning of `long_progname' when the program resides on a
	   networked drive, and DOS calls cannot grok such pathnames.  We
	   need to convert the filesystem name back to a drive letter.  */
	char rootname[PATH_MAX], rootdir[4];

	if (argv0[0] && argv0[1] == ':')
	  rootdir[0] = argv0[0]; /* explicit drive in `argv0' */
	else
	  rootdir[0] = getdisk () + 'A';
	rootdir[1] = ':';
	rootdir[2] = '\\';
	rootdir[3] = '\0';
	if (_truename (rootdir, rootname)) {
	  /* Find out where `rootname' ends in `long_progname' and replace
	     it with the drive letter.  */
	  int root_len = strlen (rootname);

 	  if (IS_DIR_SEP (rootname[root_len - 1]))
            root_len--;	/* keep the trailing slash */
	  long_progname[0] = rootdir[0];
	  long_progname[1] = ':';
	  memmove (long_progname + 2, long_progname + root_len,
		   strlen (long_progname + root_len) + 1);
	}
      }

      /* Convert everything to canonical form.  */
      if (long_progname[0] >= 'A' && long_progname[0] <= 'Z')
	long_progname[0] += 'a' - 'A'; /* make drive lower case, for beauty */
      for (fp = long_progname; *fp; fp++)
	if (IS_DIR_SEP (*fp))
	  *fp = DIR_SEP;

      program_invocation_name = xstrdup (long_progname);
    }
    else
      /* If `_truename' failed, God help them, because we won't...  */
      program_invocation_name = xstrdup (argv0);
  }
  else
    program_invocation_name = xstrdup (argv0);

#else /* !WIN32 && !__DJGPP__ */

  program_invocation_name = xstrdup (argv0);

#endif
#endif /* not HAVE_PROGRAM_INVOCATION_NAME */

  /* We need to find SELFAUTOLOC *before* removing the ".exe" suffix from
     the program_name, otherwise the PATH search inside selfdir will fail,
     since `prog' doesn't exists as a file, there's `prog.exe' instead.  */
#ifndef WIN32
  sdir = selfdir (program_invocation_name);
#endif
  /* SELFAUTODIR is actually the parent of the invocation directory,
     and SELFAUTOPARENT the grandparent.  This is how teTeX did it.  */
  xputenv ("SELFAUTOLOC", sdir);
  sdir_parent = xdirname (sdir);
  xputenv ("SELFAUTODIR", sdir_parent);
  sdir_grandparent = xdirname (sdir_parent);
  xputenv ("SELFAUTOPARENT", sdir_grandparent);

  free (sdir);
  free (sdir_parent);
  free (sdir_grandparent);

#ifndef HAVE_PROGRAM_INVOCATION_NAME
  program_invocation_short_name = (string)xbasename (program_invocation_name);
#endif

  if (progname) {
    kpse_program_name = xstrdup (progname);
  } else {
    /* If configured --enable-shared and running from the build directory
       with the wrapper scripts (e.g., for make check), the binaries will
       be named foo.exe instead of foo.  Or possibly if we're running on a
       DOSISH system.  */
    ext = find_suffix (program_invocation_short_name);
    if (ext && FILESTRCASEEQ (ext, "exe")) {
      kpse_program_name = remove_suffix (program_invocation_short_name);
    } else {
      kpse_program_name = xstrdup (program_invocation_short_name);
    }
  }
  xputenv("progname", kpse_program_name);
}
static struct input_stream *
input_file_open(const char *filename,
		GMutex *mutex, GCond *cond,
		GError **error_r)
{
	int fd, ret;
	struct stat st;
	struct file_input_stream *fis;

	if (!g_path_is_absolute(filename))
		return NULL;

	fd = open_cloexec(filename, O_RDONLY|O_BINARY, 0);
        if (fd < 0)  {
		// the filename doesn't exist	
		// try and open uri as if it were a track inside a container
		char* pathname = NULL;
		unsigned tnum;

		pathname = g_strdup(filename);
		remove_suffix(pathname,'/');

		tnum = cue_vtrack_tnum(filename);
		if ( tnum == 0 )
			tnum=1; // use filename from first track of cue file if no track found 
			
                if( g_str_has_suffix(pathname,".cue"))
                    pathname=cue_locate_audio_container_file(pathname,tnum) ;

		fd = open_cloexec(pathname, O_RDONLY|O_BINARY, 0);
		g_free(pathname);

		if (fd < 0) {
			if (errno != ENOENT && errno != ENOTDIR)
				g_set_error(error_r, file_quark(), errno,
						"Failed to open \"%s\": %s",
						filename, g_strerror(errno));
			return NULL;
		}
	}

	ret = fstat(fd, &st);
	if (ret < 0) {
		g_set_error(error_r, file_quark(), errno,
			    "Failed to stat \"%s\": %s",
			    filename, g_strerror(errno));
		close(fd);
		return NULL;
	}

	if (!S_ISREG(st.st_mode)) {
		g_set_error(error_r, file_quark(), 0,
			    "Not a regular file: %s", filename);
		close(fd);
		return NULL;
	}

#ifdef POSIX_FADV_SEQUENTIAL
	posix_fadvise(fd, (off_t)0, st.st_size, POSIX_FADV_SEQUENTIAL);
#endif

	fis = g_new(struct file_input_stream, 1);
	input_stream_init(&fis->base, &input_plugin_file, filename,
			  mutex, cond);

	fis->base.size = st.st_size;
	fis->base.seekable = true;
	fis->base.ready = true;

	fis->fd = fd;

	return &fis->base;
}
Пример #15
0
static void file_action(char *filename) {
  struct stat buf;
  int st;
  int link = 0;
  char *outfile;
  char *infile;
  char *buffer = NULL;

  infile = filename;  /* but it may be changed below */

  st = lstat(infile, &buf);

  if (st) {
    int save_errno = errno;
    
    /* if file didn't exist and decrypting, try if suffixed file exists */
    if (errno==ENOENT 
	&& (cmd.mode==DECRYPT || cmd.mode==CAT || cmd.mode==KEYCHANGE 
	    || cmd.mode==UNIXCRYPT) 
	&& cmd.suffix[0]!=0) {
      buffer = xalloc(strlen(filename)+strlen(cmd.suffix)+1, cmd.name);

      strcpy(buffer, infile);
      strcat(buffer, cmd.suffix);
      infile=buffer;
      st = lstat(infile, &buf);
    }
    if (st) {
      fprintf(stderr, "%s: %s: %s\n", cmd.name, filename, strerror(save_errno));
      io_errors++;
      goto done;
    }
  }
  
  /* if link following is enabled, follow links */
  if (cmd.symlinks && S_ISLNK(buf.st_mode)) {
    link = 1;
    st = stat(infile, &buf);
    if (st) {
      fprintf(stderr, "%s: %s: %s\n", cmd.name, infile, strerror(errno));
      io_errors++;
      goto done;
    }
  }

  /* assert st==0 */

  /* if file is not a regular file, skip */
  if (S_ISLNK(buf.st_mode)) {
    if (cmd.verbose>=0) {
      fprintf(stderr, "%s: %s: is a symbolic link -- ignored\n", cmd.name, infile);
      symlink_warnings++;
    }
    goto done;
  }
  if (!S_ISREG(buf.st_mode)) {
    if (cmd.verbose>=0) {
      fprintf(stderr, "%s: %s: is not a regular file -- ignored\n", cmd.name, 
	      infile);
      isreg_warnings++;
    }
    goto done;
  }
  
  /* now we have a regular file, and we have followed a link if
     appropriate. */

  if (cmd.mode==ENCRYPT || cmd.mode==DECRYPT || cmd.mode==KEYCHANGE) {
    /* determine outfile name */
    switch (cmd.mode) {
    case ENCRYPT: default:
      if (cmd.strictsuffix && cmd.suffix[0] != 0 && has_suffix(infile, cmd.suffix)) {
	if (cmd.verbose>=0) {
	  fprintf(stderr, "%s: %s already has %s suffix -- ignored\n", cmd.name, infile, cmd.suffix); 
	  strict_warnings++;
	}
	goto done;
      }
      outfile = add_suffix(infile, cmd.suffix);
      break;
    case DECRYPT:
      outfile = remove_suffix(infile, cmd.suffix);
      break;
    case KEYCHANGE:
      outfile = infile;
      break;
    }
    
    /* if outfile exists and cmd.force is not set, prompt whether to
       overwrite */
    if (!cmd.force && strcmp(infile, outfile) && 
	file_exists(outfile)) {
      fprintf(stderr, "%s: %s already exists; overwrite (y or n)? ", cmd.name, 
	      outfile);
      fflush(stderr);
      if (prompt()==0) {
	fprintf(stderr, "Not overwritten.\n");
	goto done;
      }
    }
    if (cmd.tmpfiles) {
      action_tmpfiles(infile, outfile);
    } else {
      action_overwrite(infile, outfile);
    }
  } else {
    action_cat(infile);
  }
 done:
  free(buffer);
  return;
}