extern void suffix_set(const char *suffix) { // Empty suffix and suffixes having a directory separator are // rejected. Such suffixes would break things later. if (suffix[0] == '\0' || has_dir_sep(suffix)) message_fatal(_("%s: Invalid filename suffix"), optarg); // Replace the old custom_suffix (if any) with the new suffix. free(custom_suffix); custom_suffix = xstrdup(suffix); return; }
static int get_script_path(struct LuaSDL_StartInfo *info, char *app) { char spec[MAX_PATH+1]; char seg[MAX_PATH+1]; char *path = info->dir_app; /* * decide on where to grab the main script from, one of: * (1) current working directory + script path given in argument * (2) executable's directory + standard init file */ if (app) { strcpy(path, info->dir_cwd); strcpy(spec, app); } else { strcpy(path, info->dir_exe); strcpy(spec, SCRIPT_DEFAULT); } app = spec; /* check for absolute path specification */ if (is_dir_sep(&app) || is_drive_spec(&app)) { size_t sz = app - spec; path[sz] = '\0'; while (sz--) { path[sz] = spec[sz]; } } /* normalize script path if relative, last seg is actual filename */ while(has_dir_sep(&app, seg)) { if (strcmp(seg, ".") == 0) { /* do nothing, consume the segment */ } else if (strcmp(seg, "..") == 0) { /* remove a segment from the path */ remove_seg(path); } else { /* path segment, add it to path */ if (strlen(seg) + strlen(path) < MAX_PATH) { strcat(path, seg); strcat(path, info->dir_sep); } else { return 1; } } } /* end while */ if (*seg == '\0') /* no final segment means no file given, use default name */ strcpy(info->appname, SCRIPT_DEFAULT); else strcpy(info->appname, seg); return 0; }
/// \brief Appends suffix to src_name /// /// In contrast to uncompressed_name(), we check only suffixes that are valid /// for the specified file format. static char * compressed_name(const char *src_name, size_t src_len) { // The order of these must match the order in args.h. static const char *const all_suffixes[][4] = { { ".xz", ".txz", NULL }, { ".lzma", #ifdef __DJGPP__ ".lzm", #endif ".tlz", NULL /* }, { ".gz", ".tgz", NULL */ }, { // --format=raw requires specifying the suffix // manually or using stdout. NULL } }; // args.c ensures this. assert(opt_format != FORMAT_AUTO); const size_t format = opt_format - 1; const char *const *suffixes = all_suffixes[format]; // Look for known filename suffixes and refuse to compress them. for (size_t i = 0; suffixes[i] != NULL; ++i) { if (test_suffix(suffixes[i], src_name, src_len) != 0) { msg_suffix(src_name, suffixes[i]); return NULL; } } #ifdef __DJGPP__ // Recognize also the special suffix that is used when long // filename (LFN) support isn't available. This suffix is // recognized on LFN systems too. if (opt_format == FORMAT_XZ && has_sfn_suffix(src_name, src_len)) { msg_suffix(src_name, "-"); return NULL; } #endif if (custom_suffix != NULL) { if (test_suffix(custom_suffix, src_name, src_len) != 0) { msg_suffix(src_name, custom_suffix); return NULL; } } // TODO: Hmm, maybe it would be better to validate this in args.c, // since the suffix handling when decoding is weird now. if (opt_format == FORMAT_RAW && custom_suffix == NULL) { message_error(_("%s: With --format=raw, " "--suffix=.SUF is required unless " "writing to stdout"), src_name); return NULL; } const char *suffix = custom_suffix != NULL ? custom_suffix : suffixes[0]; size_t suffix_len = strlen(suffix); #ifdef __DJGPP__ if (!_use_lfn(src_name)) { // Long filename (LFN) support isn't available and we are // limited to 8.3 short filenames (SFN). // // Look for suffix separator from the filename, and make sure // that it is in the filename, not in a directory name. const char *sufsep = strrchr(src_name, '.'); if (sufsep == NULL || sufsep[1] == '\0' || has_dir_sep(sufsep)) { // src_name has no filename extension. // // Examples: // xz foo -> foo.xz // xz -F lzma foo -> foo.lzm // xz -S x foo -> foox // xz -S x foo. -> foo.x // xz -S x.y foo -> foox.y // xz -S .x foo -> foo.x // xz -S .x foo. -> foo.x // // Avoid double dots: if (sufsep != NULL && sufsep[1] == '\0' && suffix[0] == '.') --src_len; } else if (custom_suffix == NULL && strcasecmp(sufsep, ".tar") == 0) { // ".tar" is handled specially. // // Examples: // xz foo.tar -> foo.txz // xz -F lzma foo.tar -> foo.tlz static const char *const tar_suffixes[] = { ".txz", ".tlz", // ".tgz", }; suffix = tar_suffixes[format]; suffix_len = 4; src_len -= 4; } else { if (custom_suffix == NULL && opt_format == FORMAT_XZ) { // Instead of the .xz suffix, use a single // character at the end of the filename // extension. This is to minimize name // conflicts when compressing multiple files // with the same basename. E.g. foo.txt and // foo.exe become foo.tx- and foo.ex-. Dash // is rare as the last character of the // filename extension, so it seems to be // quite safe choice and it stands out better // in directory listings than e.g. x. For // comparison, gzip uses z. suffix = "-"; suffix_len = 1; } if (suffix[0] == '.') { // The first character of the suffix is a dot. // Throw away the original filename extension // and replace it with the new suffix. // // Examples: // xz -F lzma foo.txt -> foo.lzm // xz -S .x foo.txt -> foo.x src_len = sufsep - src_name; } else { // The first character of the suffix is not // a dot. Preserve the first 0-2 characters // of the original filename extension. // // Examples: // xz foo.txt -> foo.tx- // xz -S x foo.c -> foo.cx // xz -S ab foo.c -> foo.cab // xz -S ab foo.txt -> foo.tab // xz -S abc foo.txt -> foo.abc // // Truncate the suffix to three chars: if (suffix_len > 3) suffix_len = 3; // If needed, overwrite 1-3 characters. if (strlen(sufsep) > 4 - suffix_len) src_len = sufsep - src_name + 4 - suffix_len; } } } #endif char *dest_name = xmalloc(src_len + suffix_len + 1); memcpy(dest_name, src_name, src_len); memcpy(dest_name + src_len, suffix, suffix_len); dest_name[src_len + suffix_len] = '\0'; return dest_name; }