security/nss/lib/dbm/src/dirent.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 #ifdef OS2
     3 #include <stdio.h>
     4 #include <stdlib.h>
     5 #include <string.h>
     6 #include <ctype.h>
     8 #include <dirent.h>
     9 #include <errno.h>
    11 /*#ifndef __EMX__ 
    12 #include <libx.h>
    13 #endif */
    15 #define INCL_DOSFILEMGR
    16 #define INCL_DOSERRORS
    17 #include <os2.h>
    19 #if OS2 >= 2
    20 # define FFBUF	FILEFINDBUF3
    21 # define Word	ULONG
    22   /*
    23    * LS20 recommends a request count of 100, but according to the
    24    * APAR text it does not lead to missing files, just to funny
    25    * numbers of returned entries.
    26    *
    27    * LS30 HPFS386 requires a count greater than 2, or some files
    28    * are missing (those starting with a character less that '.').
    29    *
    30    * Novell loses entries which overflow the buffer. In previous
    31    * versions of dirent2, this could have lead to missing files
    32    * when the average length of 100 directory entries was 40 bytes
    33    * or more (quite unlikely for files on a Novell server).
    34    *
    35    * Conclusion: Make sure that the entries all fit into the buffer
    36    * and that the buffer is large enough for more than 2 entries
    37    * (each entry is at most 300 bytes long). And ignore the LS20
    38    * effect.
    39    */
    40 # define Count	25
    41 # define BufSz	(25 * (sizeof(FILEFINDBUF3)+1))
    42 #else
    43 # define FFBUF	FILEFINDBUF
    44 # define Word	USHORT
    45 # define BufSz	1024
    46 # define Count	3
    47 #endif
    49 #if defined(__IBMC__) || defined(__IBMCPP__)
    50   #define error(rc) _doserrno = rc, errno = EOS2ERR
    51 #elif defined(MICROSOFT)
    52   #define error(rc) _doserrno = rc, errno = 255
    53 #else
    54   #define error(rc) errno = 255
    55 #endif
    57 struct _dirdescr {
    58 	HDIR		handle;		/* DosFindFirst handle */
    59 	char		fstype;		/* filesystem type */
    60 	Word		count;		/* valid entries in <ffbuf> */
    61 	long		number;		/* absolute number of next entry */
    62 	int		index;		/* relative number of next entry */
    63 	FFBUF *		next;		/* pointer to next entry */
    64 	char		name[MAXPATHLEN+3]; /* directory name */
    65 	unsigned	attrmask;	/* attribute mask for seekdir */
    66 	struct dirent	entry;		/* buffer for directory entry */
    67 	BYTE		ffbuf[BufSz];
    68 };
    70 /*
    71  * Return first char of filesystem type, or 0 if unknown.
    72  */
    73 static char
    74 getFSType(const char *path)
    75 {
    76 	static char cache[1+26];
    77 	char drive[3], info[512];
    78 	Word unit, infolen;
    79 	char r;
    81 	if (isalpha(path[0]) && path[1] == ':') {
    82 		unit = toupper(path[0]) - '@';
    83 		path += 2;
    84 	} else {
    85 		ULONG driveMap;
    86 #if OS2 >= 2
    87 		if (DosQueryCurrentDisk(&unit, &driveMap))
    88 #else
    89 		if (DosQCurDisk(&unit, &driveMap))
    90 #endif
    91 			return 0;
    92 	}
    94 	if ((path[0] == '\\' || path[0] == '/')
    95 	 && (path[1] == '\\' || path[1] == '/'))
    96 		return 0;
    98 	if (cache [unit])
    99 		return cache [unit];
   101 	drive[0] = '@' + unit;
   102 	drive[1] = ':';
   103 	drive[2] = '\0';
   104 	infolen = sizeof info;
   105 #if OS2 >= 2
   106 	if (DosQueryFSAttach(drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen))
   107 		return 0;
   108 	if (infolen >= sizeof(FSQBUFFER2)) {
   109 		FSQBUFFER2 *p = (FSQBUFFER2 *)info;
   110 		r = p->szFSDName[p->cbName];
   111 	} else
   112 #else
   113 	if (DosQFSAttach((PSZ)drive, 0, FSAIL_QUERYNAME, (PVOID)info, &infolen, 0))
   114 		return 0;
   115 	if (infolen >= 9) {
   116 		char *p = info + sizeof(USHORT);
   117 		p += sizeof(USHORT) + *(USHORT *)p + 1 + sizeof(USHORT);
   118 		r = *p;
   119 	} else
   120 #endif
   121 		r = 0;
   122 	return cache [unit] = r;
   123 }
   125 char *
   126 abs_path(const char *name, char *buffer, int len)
   127 {
   128 	char buf[4];
   129 	if (isalpha(name[0]) && name[1] == ':' && name[2] == '\0') {
   130 		buf[0] = name[0];
   131 		buf[1] = name[1];
   132 		buf[2] = '.';
   133 		buf[3] = '\0';
   134 		name = buf;
   135 	}
   136 #if OS2 >= 2
   137 	if (DosQueryPathInfo((PSZ)name, FIL_QUERYFULLNAME, buffer, len))
   138 #else
   139 	if (DosQPathInfo((PSZ)name, FIL_QUERYFULLNAME, (PBYTE)buffer, len, 0L))
   140 #endif
   141 		return NULL;
   142 	return buffer;
   143 }
   145 DIR *
   146 openxdir(const char *path, unsigned att_mask)
   147 {
   148 	DIR *dir;
   149 	char name[MAXPATHLEN+3];
   150 	Word rc;
   152 	dir = malloc(sizeof(DIR));
   153 	if (dir == NULL) {
   154 		errno = ENOMEM;
   155 		return NULL;
   156 	}
   158 	strncpy(name, path, MAXPATHLEN);
   159 	name[MAXPATHLEN] = '\0';
   160 	switch (name[strlen(name)-1]) {
   161 	default:
   162 		strcat(name, "\\");
   163 	case '\\':
   164 	case '/':
   165 	case ':':
   166 		;
   167 	}
   168 	strcat(name, ".");
   169 	if (!abs_path(name, dir->name, MAXPATHLEN+1))
   170 		strcpy(dir->name, name);
   171 	if (dir->name[strlen(dir->name)-1] == '\\')
   172 		strcat(dir->name, "*");
   173 	else
   174 		strcat(dir->name, "\\*");
   176 	dir->fstype = getFSType(dir->name);
   177 	dir->attrmask = att_mask | A_DIR;
   179 	dir->handle = HDIR_CREATE;
   180 	dir->count = 100;
   181 #if OS2 >= 2
   182 	rc = DosFindFirst(dir->name, &dir->handle, dir->attrmask,
   183 		dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
   184 #else
   185 	rc = DosFindFirst((PSZ)dir->name, &dir->handle, dir->attrmask,
   186 		(PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
   187 #endif
   188 	switch (rc) {
   189 	default:
   190 		free(dir);
   191 		error(rc);
   192 		return NULL;
   193 	case NO_ERROR:
   194 	case ERROR_NO_MORE_FILES:
   195 		;
   196 	}
   198 	dir->number = 0;
   199 	dir->index = 0;
   200 	dir->next = (FFBUF *)dir->ffbuf;
   202 	return (DIR *)dir;
   203 }
   205 DIR *
   206 opendir(const char *pathname)
   207 {
   208 	return openxdir(pathname, 0);
   209 }
   211 struct dirent *
   212 readdir(DIR *dir)
   213 {
   214 	static int dummy_ino = 2;
   216 	if (dir->index == dir->count) {
   217 		Word rc;
   218 		dir->count = 100;
   219 #if OS2 >= 2
   220 		rc = DosFindNext(dir->handle, dir->ffbuf,
   221 			sizeof dir->ffbuf, &dir->count);
   222 #else
   223 		rc = DosFindNext(dir->handle, (PFILEFINDBUF)dir->ffbuf,
   224 			sizeof dir->ffbuf, &dir->count);
   225 #endif
   226 		if (rc) {
   227 			error(rc);
   228 			return NULL;
   229 		}
   231 		dir->index = 0;
   232 		dir->next = (FFBUF *)dir->ffbuf;
   233 	}
   235 	if (dir->index == dir->count)
   236 		return NULL;
   238 	memcpy(dir->entry.d_name, dir->next->achName, dir->next->cchName);
   239 	dir->entry.d_name[dir->next->cchName] = '\0';
   240 	dir->entry.d_ino = dummy_ino++;
   241 	dir->entry.d_reclen = dir->next->cchName;
   242 	dir->entry.d_namlen = dir->next->cchName;
   243 	dir->entry.d_size = dir->next->cbFile;
   244 	dir->entry.d_attribute = dir->next->attrFile;
   245 	dir->entry.d_time = *(USHORT *)&dir->next->ftimeLastWrite;
   246 	dir->entry.d_date = *(USHORT *)&dir->next->fdateLastWrite;
   248 	switch (dir->fstype) {
   249 	case 'F': /* FAT */
   250 	case 'C': /* CDFS */
   251 		if (dir->next->attrFile & FILE_DIRECTORY)
   252 			strupr(dir->entry.d_name);
   253 		else
   254 			strlwr(dir->entry.d_name);
   255 	}
   257 #if OS2 >= 2
   258 	dir->next = (FFBUF *)((BYTE *)dir->next + dir->next->oNextEntryOffset);
   259 #else
   260 	dir->next = (FFBUF *)((BYTE *)dir->next->achName + dir->next->cchName + 1);
   261 #endif
   262 	++dir->number;
   263 	++dir->index;
   265 	return &dir->entry;
   266 }
   268 long
   269 telldir(DIR *dir)
   270 {
   271 	return dir->number;
   272 }
   274 void
   275 seekdir(DIR *dir, long off)
   276 {
   277 	if (dir->number > off) {
   278 		char name[MAXPATHLEN+2];
   279 		Word rc;
   281 		DosFindClose(dir->handle);
   283 		strcpy(name, dir->name);
   284 		strcat(name, "*");
   286 		dir->handle = HDIR_CREATE;
   287 		dir->count = 32767;
   288 #if OS2 >= 2
   289 		rc = DosFindFirst(name, &dir->handle, dir->attrmask,
   290 			dir->ffbuf, sizeof dir->ffbuf, &dir->count, FIL_STANDARD);
   291 #else
   292 		rc = DosFindFirst((PSZ)name, &dir->handle, dir->attrmask,
   293 			(PFILEFINDBUF)dir->ffbuf, sizeof dir->ffbuf, &dir->count, 0);
   294 #endif
   295 		switch (rc) {
   296 		default:
   297 			error(rc);
   298 			return;
   299 		case NO_ERROR:
   300 		case ERROR_NO_MORE_FILES:
   301 			;
   302 		}
   304 		dir->number = 0;
   305 		dir->index = 0;
   306 		dir->next = (FFBUF *)dir->ffbuf;
   307 	}
   309 	while (dir->number < off && readdir(dir))
   310 		;
   311 }
   313 void
   314 closedir(DIR *dir)
   315 {
   316 	DosFindClose(dir->handle);
   317 	free(dir);
   318 }
   320 /*****************************************************************************/
   322 #ifdef TEST
   324 main(int argc, char **argv)
   325 {
   326 	int i;
   327 	DIR *dir;
   328 	struct dirent *ep;
   330 	for (i = 1; i < argc; ++i) {
   331 		dir = opendir(argv[i]);
   332 		if (!dir)
   333 			continue;
   334 		while (ep = readdir(dir))
   335 			if (strchr("\\/:", argv[i] [strlen(argv[i]) - 1]))
   336 				printf("%s%s\n", argv[i], ep->d_name);
   337 			else
   338 				printf("%s/%s\n", argv[i], ep->d_name);
   339 		closedir(dir);
   340 	}
   342 	return 0;
   343 }
   345 #endif
   347 #endif /* OS2 */

mercurial