⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 name.c

📁 一款功能很强的光盘镜象制作工具
💻 C
字号:
/* @(#)name.c	1.24 02/05/03 joerg */#ifndef lintstatic	char sccsid[] =	"@(#)name.c	1.24 02/05/03 joerg";#endif/* * File name.c - map full Unix file names to unique 8.3 names that * would be valid on DOS. *   Written by Eric Youngdale (1993).   Almost totally rewritten by J. Schilling (2000).   Copyright 1993 Yggdrasil Computing, Incorporated   Copyright (c) 1999,2000 J. Schilling   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2, or (at your option)   any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */#include <mconfig.h>#include "mkisofs.h"#include <ctype.h>#include <standard.h>#include <schily.h>void	iso9660_check		__PR((struct iso_directory_record *idr,	struct directory_entry *ndr));int	iso9660_file_length	__PR((const char *name,			                struct directory_entry *sresult,			                int dirflag));voidiso9660_check(idr, ndr)	struct iso_directory_record *idr;	struct directory_entry *ndr;{	int	nlen;	char	schar;	char	*p;	char	*np;	nlen = idr->name_len[0];	schar = idr->name[nlen];	if (nlen == 1 && (idr->name[0] == '\0' || idr->name[0] == '\001'))		return;	idr->name[nlen] = '\0';		/* Make it null terminated */	if ((p = strrchr(idr->name, ';')) != NULL) {		*p = '\0';		/* Strip off old version # */	}	iso9660_file_length(idr->name, ndr,				(idr->flags[0] & ISO_DIRECTORY) != 0);	if ((np = strrchr(ndr->isorec.name, ';')) != NULL) {		*np = '\0';		/* Strip off new version # */	}	if (strcmp(idr->name, ndr->isorec.name)) {		if (p)			*p = ';';	/* Restore old version # */		if (np)			*np = ';';	/* Restore new version # */		errmsgno(EX_BAD,			"Old session has illegal name '%.*s' length %d\n",			idr->name_len[0],			idr->name,			idr->name_len[0]);		errmsgno(EX_BAD,			"New session will use    name '%s'\n",			ndr->isorec.name);	}	if (p)		*p = ';';		/* Restore old version # */	if (np)		*np = ';';		/* Restore new version # */	idr->name[nlen] = schar;	/* Restore old iso record*/}/* * Function:	iso9660_file_length * * Purpose:	Map file name to 8.3 format, return length *		of result. * * Arguments:	name	file name we need to map. *		sresult	directory entry structure to contain mapped name. *		dirflag	flag indicating whether this is a directory or not. * * Note:	name being const * is a bug introduced by Eric but hard to *		fix without going through the whole source. */intiso9660_file_length(name, sresult, dirflag)	const char	*name;			/* Not really const !!! */	struct directory_entry *sresult;	int		dirflag;{	char		c;	char		*cp;	int		before_dot = 8;	int		after_dot = 3;	int		chars_after_dot = 0;	int		chars_before_dot = 0;	int		current_length = 0;	int		extra = 0;	int		ignore = 0;	char		*last_dot;	const char	*pnt;	int		priority = 32767;	char		*result;	int		ochars_after_dot;	int		ochars_before_dot;	int		seen_dot = 0;	int		seen_semic = 0;	int		tildes = 0;	result = sresult->isorec.name;	if (sresult->priority)		priority = sresult->priority;	/*	 * For the '.' entry, generate the correct record, and return 1 for	 * the length.	 */	if (strcmp(name, ".") == 0) {		*result = 0;		return 1;	}	/*	 * For the '..' entry, generate the correct record, and return 1	 * for the length.	 */	if (strcmp(name, "..") == 0) {		*result++ = 1;		*result++ = 0;		return 1;	}	/*	 * Now scan the directory one character at a time, and figure out	 * what to do.	 */	pnt = name;	/*	 * Find the '.' that we intend to use for the extension.	 * Usually this is the last dot, but if we have . followed by nothing	 * or a ~, we would consider this to be unsatisfactory, and we keep	 * searching.	 */	last_dot = strrchr(pnt, '.');	if ((last_dot != NULL) &&	    ((last_dot[1] == '~') || (last_dot[1] == '\0'))) {		cp = last_dot;		*cp = '\0';		last_dot = strrchr(pnt, '.');		*cp = '.';		/*		 * If we found no better '.' back up to the last match.		 */		if (last_dot == NULL)			last_dot = cp;	}	if (last_dot != NULL) {		ochars_after_dot = strlen(last_dot);	/* dot counts */		ochars_before_dot = last_dot - pnt;	} else {		ochars_before_dot = 128;		ochars_after_dot = 0;	}	/*	 * If we have full names, the names we generate will not work	 * on a DOS machine, since they are not guaranteed to be 8.3.	 * Nonetheless, in many cases this is a useful option.  We	 * still only allow one '.' character in the name, however.	 */	if (full_iso9660_filenames || iso9660_level > 1) {		before_dot = iso9660_namelen;		after_dot = before_dot - 1;		if (!dirflag) {			if (ochars_after_dot > ((iso9660_namelen/2)+1)) {				/*				 * The minimum number of characters before				 * the dot is 3 to allow renaming.				 * Let us allow to have 15 characters after				 * dot to give more rational filenames.				 */				before_dot = iso9660_namelen/2;				after_dot = ochars_after_dot;			} else {				before_dot -= ochars_after_dot;/* dot counts */				after_dot = ochars_after_dot;			}		}	}	while (*pnt) {#ifdef VMS		if (strcmp(pnt, ".DIR;1") == 0) {			break;		}#endif#ifdef		Eric_code_does_not_work		/*		 * XXX If we make this code active we get corrupted direcrory		 * XXX trees with infinite loops.		 */		/*		 * This character indicates a Unix style of backup file		 * generated by some editors.  Lower the priority of the file.		 */		if (iso_translate && *pnt == '#') {			priority = 1;			pnt++;			continue;		}		/*		 * This character indicates a Unix style of backup file		 * generated by some editors.  Lower the priority of the file.		 */		if (iso_translate && *pnt == '~') {			priority = 1;			tildes++;			pnt++;			continue;		}#endif		/*		 * This might come up if we had some joker already try and put		 * iso9660 version numbers into the file names.  This would be		 * a silly thing to do on a Unix box, but we check for it		 * anyways.  If we see this, then we don't have to add our own		 * version number at the end. UNLESS the ';' is part of the		 * filename and no valid version number is following.		 */		if (use_fileversion && *pnt == ';' && seen_dot) {			/*			 * Check if a valid version number follows.			 * The maximum valid version number is 32767.			 */			for (c = 1, cp = (char *)&pnt[1]; c < 6 && *cp; c++,cp++) {				if (*cp < '0' || *cp > '9')					break;			}			if (c <= 6 && *cp == '\0' && atoi(&pnt[1]) <= 32767)				seen_semic++;		}		/*		 * If we have a name with multiple '.' characters, we ignore		 * everything after we have gotten the extension.		 */		if (ignore) {			pnt++;			continue;		}		if (current_length >= iso9660_namelen) {#ifdef	nono			/*			 * Does not work as we may truncate before the dot.			 */			error("Truncating '%s' to '%.*s'.\n",				name,				current_length, sresult->isorec.name);			ignore++;#endif			pnt++;			continue;		}		/* Spin past any iso9660 version number we might have. */		if (seen_semic) {			if (seen_semic == 1) {				seen_semic++;				*result++ = ';';			}			if (*pnt >= '0' && *pnt <= '9') {				*result++ = *pnt;			}			extra++;			pnt++;			continue;		}		if (*pnt == '.') {			if (!allow_multidot) {				if (strcmp(pnt, ".tar.gz") == 0)					pnt = last_dot = ".tgz";				if (strcmp(pnt, ".ps.gz") == 0)					pnt = last_dot = ".psz";			}			if (!chars_before_dot && !allow_leading_dots) {				/*				 * DOS can't read files with dot first				 */				chars_before_dot++;				*result++ = '_'; /* Substitute underscore */			} else if (pnt == last_dot) {				if (seen_dot) {					ignore++;					continue;				}				*result++ = '.';				seen_dot++;			} else if (allow_multidot) {				if (chars_before_dot < before_dot) {					chars_before_dot++;					*result++ = '.';				}			} else {				/*				 * If this isn't the dot that we use				 * for the extension, then change the				 * character into a '_' instead.				 */				if (chars_before_dot < before_dot) {					chars_before_dot++;					*result++ = '_';				}			}		} else {			if ((seen_dot && (chars_after_dot < after_dot) &&						++chars_after_dot)			    || (!seen_dot && (chars_before_dot < before_dot) &&			    ++chars_before_dot)) {				c = *pnt;				if (c & 0x80) {					c = '_';				} else if (!allow_lowercase) {					c = islower((unsigned char)c) ?						toupper((unsigned char)c) : c;				}				if (gbk4dos_filenames) {				        /*				         * Here we allow gbk4dos standard name.				         */					*result++ = *pnt;				} else				if (relaxed_filenames) {					/*					 * Here we allow a more relaxed syntax.					 */					*result++ = c;				} else switch (c) {					/*					 * Dos style filenames.					 * We really restrict the names here.					 */				default:					*result++ = c;					break;				/*				 * Descriptions of DOS's 'Parse Filename'				 * (function 29H) describes V1 and V2.0+				 * separator and terminator characters. These				 * characters in a DOS name make the file				 * visible but un-manipulable (all useful				 * operations error off.				 */				/* separators */				case '+':				case '=':				case '%': /* not legal DOS					   filename */				case ':':				case ';': /* already handled */				case '.': /* already handled */				case ',': /* already handled */				case '\t':				case ' ':				/* V1 only separators */				case '/':				case '"':				case '[':				case ']':				/* terminators */				case '>':				case '<':				case '|':				/*				 * Other characters that are not valid ISO-9660				 * characters.				 */				case '!':/*				case '#':*/				case '$':				case '&':				case '\'':				case '(':				case ')':				case '*':/*				case '-':*/				case '?':				case '@':				case '\\':				case '^':				case '`':				case '{':				case '}':/*				case '~':*/				/*				 * All characters below 32 (space) are not				 * allowed too.				 */				case 1: case 2: case 3: case 4:				case 5: case 6: case 7: case 8:				/* case 9: */				case 10: case 11: case 12:				case 13: case 14: case 15:				case 16: case 17: case 18:				case 19: case 20: case 21:				case 22: case 23: case 24:				case 25: case 26: case 27:				case 28: case 29: case 30:				case 31:					/*					 * Hmm - what to do here? Skip? Win95					 * looks like it substitutes '_'					 */					*result++ = '_';					break;				case '#':				case '-':				case '~':					/*					 * Check if we should allow these					 * illegal characters used by					 * Microsoft.					 */					if (iso_translate)						*result++ = '_';					else						*result++ = c;					break;				}	/* switch (*pnt) */			} else {	/* if (chars_{after,before}_dot) ... */				pnt++;				continue;			}		}	/* else *pnt == '.' */		current_length++;		pnt++;	}	/* while (*pnt) */	/*	 * OK, that wraps up the scan of the name.  Now tidy up a few other	 * things.	 * Look for emacs style of numbered backups, like foo.c.~3~.  If we	 * see this, convert the version number into the priority number.	 * In case of name conflicts, this is what would end up being used as	 * the 'extension'.	 */	if (tildes == 2) {		int             prio1 = 0;		pnt = name;		while (*pnt && *pnt != '~') {			pnt++;		}		if (*pnt) {			pnt++;		}		while (*pnt && *pnt != '~') {			prio1 = 10 * prio1 + *pnt - '0';			pnt++;		}		priority = prio1;	}	/*	 * If this is not a directory, force a '.' in case we haven't seen one,	 * and add a version number if we haven't seen one of those either.	 */	if (!dirflag) {		if (!seen_dot && !omit_period) {			if (chars_before_dot >= (iso9660_namelen-1)) {				chars_before_dot--;				result--;			}			*result++ = '.';			extra++;		}		if (!omit_version_number && !seen_semic) {			*result++ = ';';			*result++ = '1';			extra += 2;		}	}	*result++ = 0;	sresult->priority = priority;/*#define	DEBBUG*/#ifdef	DEBBUG	error("NAME: '%s'\n", sresult->isorec.name);	error("chars_before_dot %d chars_after_dot %d seen_dot %d extra %d\n",		chars_before_dot, chars_after_dot, seen_dot, extra);#endif	return (chars_before_dot + chars_after_dot + seen_dot + extra);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -