#include "xmh.h"
#include <X11/Xos.h>
#ifndef X_NOT_POSIX
#include <dirent.h>
#else
#ifdef SYSV
#include <dirent.h>
#else
#ifdef USG
#include <dirent.h>
#else
#include <sys/dir.h>
#ifndef dirent
#define dirent direct
#endif
#endif
#endif
#endif
#include <stdlib.h>
#if defined(SYSV) && (defined(i386) || defined(MOTOROLA))
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#define CHUNKSIZE 1024
int ftruncate_emu(
int fd,
off_t length,
char *name)
{
char tmp_file[15];
int new_fid, bytes_left, i;
unsigned char buffer[CHUNKSIZE];
struct stat stat_val;
sprintf(tmp_file, ".xmhtmp%d~", getpid());
(void) unlink(tmp_file);
new_fid = open(tmp_file, O_RDWR | O_CREAT);
lseek(fd, (off_t)0, 0);
for (i = 0; i < length / CHUNKSIZE; i++) {
if (read(fd, buffer, CHUNKSIZE) != CHUNKSIZE) {
(void)fprintf(stderr, "xmh: read error in ftruncate emulation\n");
return -1;
}
else if (write(new_fid, buffer, CHUNKSIZE) != CHUNKSIZE) {
(void)fprintf(stderr, "xmh: write error in ftruncate emulation\n");
return -1;
}
}
bytes_left = length % CHUNKSIZE;
if (read(fd, buffer, bytes_left) != bytes_left) {
(void)fprintf(stderr, "xmh: read error in ftruncate() emulation\n");
return -1;
}
else if (write(new_fid, buffer, bytes_left) != bytes_left) {
(void)fprintf(stderr, "xmh: write error in ftruncate() emulation\n");
return -1;
}
(void) fstat(fd, &stat_val);
(void) chmod(tmp_file, stat_val.st_mode);
myclose(new_fid);
myclose(fd);
(void) unlink(name);
(void) rename(tmp_file, name);
return 0;
}
#endif
typedef struct dirent ENTRY;
#define INITIAL_SIZE 20
static int StrCmp(char **a, char **b)
{
return strcmp(*a, *b);
}
int
ScanDir(
char *Name,
char ***List,
int (*Selector)(char *))
{
register char **names;
register ENTRY *E;
register DIR *Dp;
register int i;
register int size;
size = INITIAL_SIZE;
if (!(names = (char **)malloc(size * sizeof(char *))) ||
!(Dp = opendir(Name)))
return(-1);
for (i = 0; (E = readdir(Dp)); )
if (!Selector || (*Selector)(E->d_name)) {
if (++i >= size) {
size <<= 1;
names = (char**)realloc((char *)names, size * sizeof(char*));
if (!names) {
closedir(Dp);
return(-1);
}
}
if (!(names[i - 1] = (char *)malloc(strlen(E->d_name) + 1))) {
closedir(Dp);
return(-1);
}
(void)strcpy(names[i - 1], E->d_name);
}
names[i] = (char *)0;
*List = names;
closedir(Dp);
if (i)
qsort((char *)names, i, sizeof(char *), (int (*)())StrCmp);
return(i);
}