Linux Audio

Check our new training course

Embedded Linux training

Mar 10-20, 2025, special US time zones
Register
Loading...
v6.2
  1// SPDX-License-Identifier: GPL-2.0
  2/*
  3 *  linux/fs/hpfs/name.c
  4 *
  5 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  6 *
  7 *  operations with filenames
  8 */
  9
 10#include "hpfs_fn.h"
 11
 12static inline int not_allowed_char(unsigned char c)
 13{
 14	return c<' ' || c=='"' || c=='*' || c=='/' || c==':' || c=='<' ||
 15	      c=='>' || c=='?' || c=='\\' || c=='|';
 16}
 17
 18static inline int no_dos_char(unsigned char c)
 19{	/* Characters that are allowed in HPFS but not in DOS */
 20	return c=='+' || c==',' || c==';' || c=='=' || c=='[' || c==']';
 21}
 22
 23static inline unsigned char upcase(unsigned char *dir, unsigned char a)
 24{
 25	if (a<128 || a==255) return a>='a' && a<='z' ? a - 0x20 : a;
 26	if (!dir) return a;
 27	return dir[a-128];
 28}
 29
 30unsigned char hpfs_upcase(unsigned char *dir, unsigned char a)
 31{
 32	return upcase(dir, a);
 33}
 34
 35static inline unsigned char locase(unsigned char *dir, unsigned char a)
 36{
 37	if (a<128 || a==255) return a>='A' && a<='Z' ? a + 0x20 : a;
 38	if (!dir) return a;
 39	return dir[a];
 40}
 41
 42int hpfs_chk_name(const unsigned char *name, unsigned *len)
 43{
 44	int i;
 45	if (*len > 254) return -ENAMETOOLONG;
 46	hpfs_adjust_length(name, len);
 47	if (!*len) return -EINVAL;
 48	for (i = 0; i < *len; i++) if (not_allowed_char(name[i])) return -EINVAL;
 49	if (*len == 1) if (name[0] == '.') return -EINVAL;
 50	if (*len == 2) if (name[0] == '.' && name[1] == '.') return -EINVAL;
 51	return 0;
 52}
 53
 54unsigned char *hpfs_translate_name(struct super_block *s, unsigned char *from,
 55			  unsigned len, int lc, int lng)
 56{
 57	unsigned char *to;
 58	int i;
 59	if (hpfs_sb(s)->sb_chk >= 2) if (hpfs_is_name_long(from, len) != lng) {
 60		pr_err("Long name flag mismatch - name ");
 61		for (i = 0; i < len; i++)
 62			pr_cont("%c", from[i]);
 63		pr_cont(" misidentified as %s.\n", lng ? "short" : "long");
 64		pr_err("It's nothing serious. It could happen because of bug in OS/2.\nSet checks=normal to disable this message.\n");
 65	}
 66	if (!lc) return from;
 67	if (!(to = kmalloc(len, GFP_KERNEL))) {
 68		pr_err("can't allocate memory for name conversion buffer\n");
 69		return from;
 70	}
 71	for (i = 0; i < len; i++) to[i] = locase(hpfs_sb(s)->sb_cp_table,from[i]);
 72	return to;
 73}
 74
 75int hpfs_compare_names(struct super_block *s,
 76		       const unsigned char *n1, unsigned l1,
 77		       const unsigned char *n2, unsigned l2, int last)
 78{
 79	unsigned l = l1 < l2 ? l1 : l2;
 80	unsigned i;
 81	if (last) return -1;
 82	for (i = 0; i < l; i++) {
 83		unsigned char c1 = upcase(hpfs_sb(s)->sb_cp_table,n1[i]);
 84		unsigned char c2 = upcase(hpfs_sb(s)->sb_cp_table,n2[i]);
 85		if (c1 < c2) return -1;
 86		if (c1 > c2) return 1;
 87	}
 88	if (l1 < l2) return -1;
 89	if (l1 > l2) return 1;
 90	return 0;
 91}
 92
 93int hpfs_is_name_long(const unsigned char *name, unsigned len)
 94{
 95	int i,j;
 96	for (i = 0; i < len && name[i] != '.'; i++)
 97		if (no_dos_char(name[i])) return 1;
 98	if (!i || i > 8) return 1;
 99	if (i == len) return 0;
100	for (j = i + 1; j < len; j++)
101		if (name[j] == '.' || no_dos_char(name[i])) return 1;
102	return j - i > 4;
103}
104
105/* OS/2 clears dots and spaces at the end of file name, so we have to */
106
107void hpfs_adjust_length(const unsigned char *name, unsigned *len)
108{
109	if (!*len) return;
110	if (*len == 1 && name[0] == '.') return;
111	if (*len == 2 && name[0] == '.' && name[1] == '.') return;
112	while (*len && (name[*len - 1] == '.' || name[*len - 1] == ' '))
113		(*len)--;
114}
v4.6
 
  1/*
  2 *  linux/fs/hpfs/name.c
  3 *
  4 *  Mikulas Patocka (mikulas@artax.karlin.mff.cuni.cz), 1998-1999
  5 *
  6 *  operations with filenames
  7 */
  8
  9#include "hpfs_fn.h"
 10
 11static inline int not_allowed_char(unsigned char c)
 12{
 13	return c<' ' || c=='"' || c=='*' || c=='/' || c==':' || c=='<' ||
 14	      c=='>' || c=='?' || c=='\\' || c=='|';
 15}
 16
 17static inline int no_dos_char(unsigned char c)
 18{	/* Characters that are allowed in HPFS but not in DOS */
 19	return c=='+' || c==',' || c==';' || c=='=' || c=='[' || c==']';
 20}
 21
 22static inline unsigned char upcase(unsigned char *dir, unsigned char a)
 23{
 24	if (a<128 || a==255) return a>='a' && a<='z' ? a - 0x20 : a;
 25	if (!dir) return a;
 26	return dir[a-128];
 27}
 28
 29unsigned char hpfs_upcase(unsigned char *dir, unsigned char a)
 30{
 31	return upcase(dir, a);
 32}
 33
 34static inline unsigned char locase(unsigned char *dir, unsigned char a)
 35{
 36	if (a<128 || a==255) return a>='A' && a<='Z' ? a + 0x20 : a;
 37	if (!dir) return a;
 38	return dir[a];
 39}
 40
 41int hpfs_chk_name(const unsigned char *name, unsigned *len)
 42{
 43	int i;
 44	if (*len > 254) return -ENAMETOOLONG;
 45	hpfs_adjust_length(name, len);
 46	if (!*len) return -EINVAL;
 47	for (i = 0; i < *len; i++) if (not_allowed_char(name[i])) return -EINVAL;
 48	if (*len == 1) if (name[0] == '.') return -EINVAL;
 49	if (*len == 2) if (name[0] == '.' && name[1] == '.') return -EINVAL;
 50	return 0;
 51}
 52
 53unsigned char *hpfs_translate_name(struct super_block *s, unsigned char *from,
 54			  unsigned len, int lc, int lng)
 55{
 56	unsigned char *to;
 57	int i;
 58	if (hpfs_sb(s)->sb_chk >= 2) if (hpfs_is_name_long(from, len) != lng) {
 59		pr_err("Long name flag mismatch - name ");
 60		for (i = 0; i < len; i++)
 61			pr_cont("%c", from[i]);
 62		pr_cont(" misidentified as %s.\n", lng ? "short" : "long");
 63		pr_err("It's nothing serious. It could happen because of bug in OS/2.\nSet checks=normal to disable this message.\n");
 64	}
 65	if (!lc) return from;
 66	if (!(to = kmalloc(len, GFP_KERNEL))) {
 67		pr_err("can't allocate memory for name conversion buffer\n");
 68		return from;
 69	}
 70	for (i = 0; i < len; i++) to[i] = locase(hpfs_sb(s)->sb_cp_table,from[i]);
 71	return to;
 72}
 73
 74int hpfs_compare_names(struct super_block *s,
 75		       const unsigned char *n1, unsigned l1,
 76		       const unsigned char *n2, unsigned l2, int last)
 77{
 78	unsigned l = l1 < l2 ? l1 : l2;
 79	unsigned i;
 80	if (last) return -1;
 81	for (i = 0; i < l; i++) {
 82		unsigned char c1 = upcase(hpfs_sb(s)->sb_cp_table,n1[i]);
 83		unsigned char c2 = upcase(hpfs_sb(s)->sb_cp_table,n2[i]);
 84		if (c1 < c2) return -1;
 85		if (c1 > c2) return 1;
 86	}
 87	if (l1 < l2) return -1;
 88	if (l1 > l2) return 1;
 89	return 0;
 90}
 91
 92int hpfs_is_name_long(const unsigned char *name, unsigned len)
 93{
 94	int i,j;
 95	for (i = 0; i < len && name[i] != '.'; i++)
 96		if (no_dos_char(name[i])) return 1;
 97	if (!i || i > 8) return 1;
 98	if (i == len) return 0;
 99	for (j = i + 1; j < len; j++)
100		if (name[j] == '.' || no_dos_char(name[i])) return 1;
101	return j - i > 4;
102}
103
104/* OS/2 clears dots and spaces at the end of file name, so we have to */
105
106void hpfs_adjust_length(const unsigned char *name, unsigned *len)
107{
108	if (!*len) return;
109	if (*len == 1 && name[0] == '.') return;
110	if (*len == 2 && name[0] == '.' && name[1] == '.') return;
111	while (*len && (name[*len - 1] == '.' || name[*len - 1] == ' '))
112		(*len)--;
113}