Example #1
0
CFileSystem::CFileIter &CWinFileSystem::CWinFileIter::operator ++()
{
  int iRes = _findnexti64(m_hFind, &m_FindData);
  if (iRes)
    m_FindData.name[0] = 0;
  return *this;
}
Example #2
0
static bool ScanGameDirectory(const char *dir, bool recurse)
{
	guard(ScanGameDirectory);

	char Path[MAX_PACKAGE_PATH];
	bool res = true;
//	printf("Scan %s\n", dir);
#if _WIN32
	appSprintf(ARRAY_ARG(Path), "%s/*.*", dir);
	_finddatai64_t found;
	long hFind = _findfirsti64(Path, &found);
	if (hFind == -1) return true;
	do
	{
		if (found.name[0] == '.') continue;			// "." or ".."
		appSprintf(ARRAY_ARG(Path), "%s/%s", dir, found.name);
		// directory -> recurse
		if (found.attrib & _A_SUBDIR)
		{
			if (recurse)
				res = ScanGameDirectory(Path, recurse);
			else
				res = true;
		}
		else
			res = RegisterGameFile(Path);
	} while (res && _findnexti64(hFind, &found) != -1);
	_findclose(hFind);
#else
	DIR *find = opendir(dir);
	if (!find) return true;
	struct dirent *ent;
	while (/*res &&*/ (ent = readdir(find)))
	{
		if (ent->d_name[0] == '.') continue;			// "." or ".."
		appSprintf(ARRAY_ARG(Path), "%s/%s", dir, ent->d_name);
		// directory -> recurse
		// note: using 'stat64' here because 'stat' ignores large files
		struct stat64 buf;
		if (stat64(Path, &buf) < 0) continue;			// or break?
		if (S_ISDIR(buf.st_mode))
		{
			if (recurse)
				res = ScanGameDirectory(Path, recurse);
			else
				res = true;
		}
		else
			res = RegisterGameFile(Path);
	}
	closedir(find);
#endif
	return res;

	unguard;
}
Example #3
0
/**
 * Move all files from temp to destination directory if at end of group.
 * Called recursively to move each file individually.
 */
void move_files_individual(struct group_list_t *group, const char *local_temp,
                           char *local_dest)
{
    int emptydir;

    {
#ifdef WINDOWS
        intptr_t ffhandle;
        struct _finddatai64_t finfo;
        char dirglob[MAXPATHNAME];

        snprintf(dirglob, sizeof(dirglob), "%s%c*", local_temp, PATH_SEP);
        if ((ffhandle = _findfirsti64(dirglob, &finfo)) == -1) {
            gsyserror(group, "Failed to open directory %s", dirglob);
            return;
        }
        emptydir = 1;
        do {
            if (strcmp(finfo.name, ".") && strcmp(finfo.name, "..")) {
                emptydir = 0;
                move_file_individual(group, local_temp, local_dest, finfo.name);
            }
        } while (_findnexti64(ffhandle, &finfo) == 0);
        _findclose(ffhandle);
#else
        DIR *dir;
        struct dirent *de;

        if ((dir = opendir(local_temp)) == NULL) {
            gsyserror(group, "Failed to open directory %s", local_temp);
            return;
        }
        emptydir = 1;
        // errno needs to be set to 0 before calling readdir, otherwise
        // we'll report a false error when we exhaust the directory
        while ((errno = 0, de = readdir(dir)) != NULL) {
            if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
                emptydir = 0;
                move_file_individual(group, local_temp, local_dest, de->d_name);
            }
        }
        if (errno && (errno != ENOENT)) {
            gsyserror(group, "Failed to read directory %s", tempdir);
        }
        closedir(dir);
#endif
    }
    if (emptydir) {
        run_postreceive(group, local_dest);
    }
    if (rmdir(local_temp) == -1) {
        gsyserror(group, "Failed remove temp directory %s", local_temp);
    }
}
Example #4
0
void FileSyst::TransverseDirectory(std::string path, std::vector<directoryvector>& directory) {

	if ( path.empty() )
		return;
	struct _finddatai64_t data;
	std::string fname = path + "\\*.*";

	try {
		long h = _findfirsti64(fname.c_str(),&data);

		if(h >= 0) {
			directoryvector currentvector;
			directory.push_back(currentvector);

			//get iterator to the currentvector element
			unsigned int currentIndex = directory.size() -1;

			//Adds the current path to the current vector
			directory[currentIndex].path = path;

			do {
				if( (data.attrib & _A_SUBDIR) ) {
					// make sure we skip "." and "..".  Have to use strcmp here because
					// some file names can start with a dot, so just testing for the
					// first dot is not sufficient.
					if( strcmp(data.name,".") != 0 &&strcmp(data.name,"..") != 0) {
						// We found a sub-directory, so get the files in it too
						fname = path + "\\" + data.name;
						// recursion here!
						TransverseDirectory(fname, directory);
					}
				}
				else {
					// this is just a normal filename.  So just add it to our vector
					file newFile = CreateFile(data.name);
					directory[currentIndex].files.push_back(newFile);

				}
			} while( _findnexti64(h,&data) == 0);
			_findclose(h);
		}

	}  catch (std::exception& e){
		throw; }
}
Example #5
0
void App::scanForPK3()
{
	logstream() << "Scanning for pk3s...\n";
#ifdef WIN32
	_finddatai64_t fdata;
	base::String str(m_WorkingPath); str+="/*.pk3";
	intptr_t handle=_findfirsti64(str.cstr(),&fdata);

	if (handle!=-1) {
		do {
			logstream() << "Found " << fdata.name << "\n";
			PHYSFS_addToSearchPath(fdata.name,0);
		} while (_findnexti64(handle,&fdata)==0);
		_findclose(handle);
	}
#else // POSIX
#endif
}
Example #6
0
void FeaturesTable::TraverseDirectory(const std::string& path, std::string& pattern, bool subdirectories, std::vector<std::string>& fileNames) {
	struct _finddatai64_t data;
	std::string fname = path + "\\" + pattern;
	// start the finder -- on error _findfirsti64() will return -1, otherwise if no
	// error it returns a handle greater than -1.
	intptr_t h = _findfirsti64(fname.c_str(),&data);
	if(h >= 0) {
		do {
			if( (data.attrib & _A_SUBDIR) ) {
				if( subdirectories && strcmp(data.name,".") != 0 && strcmp(data.name,"..") != 0) {
					fname = path + "\\" + data.name;
					TraverseDirectory(fname,pattern,true, fileNames);
				}
			} else {
				fileNames.push_back(path + "\\" + data.name);
			}
		} while( _findnexti64(h,&data) == 0);

		_findclose(h);
	}
}
Example #7
0
/**
 * Move all files from temp to destination directory if at end of group
 */
void move_files(struct group_list_t *group)
{
    char temppath[MAXPATHNAME], destpath[MAXPATHNAME];
    char *filelist[10000];  // TODO: no magic number
    int len, filecount, i;

    if (!strcmp(tempdir, "") || (group->file_id != 0)) {
        return;
    }
    if (move_individual) {
        len = snprintf(temppath, sizeof(temppath), "%s%c_group_%08X",
                       tempdir, PATH_SEP, group->group_id);
        if ((len >= sizeof(temppath)) || (len == -1)) {
            glog0(group, "Max pathname length exceeded: %s%c_group_%08X",
                         tempdir, PATH_SEP, group->group_id);
        } else {
            move_files_individual(group, temppath, destdir[0]);
        }
        return;
    }

    {
#ifdef WINDOWS
        intptr_t ffhandle;
        struct _finddatai64_t finfo;
        char dirglob[MAXPATHNAME];

        snprintf(dirglob, sizeof(dirglob), "%s%c_group_%08X%c*", tempdir,
                 PATH_SEP, group->group_id, PATH_SEP);
        if ((ffhandle = _findfirsti64(dirglob, &finfo)) == -1) {
            gsyserror(group, "Failed to open directory %s", dirglob);
            return;
        }
        filecount = 0;
        do {
            len = snprintf(temppath, sizeof(temppath), "%s%c_group_%08X%c%s",
                           tempdir, PATH_SEP, group->group_id,
                           PATH_SEP, finfo.name);
            if ((len >= sizeof(temppath)) || (len == -1)) {
                glog0(group,"Max pathname length exceeded: %s%c_group_%08X%c%s",
                      tempdir, PATH_SEP, group->group_id, PATH_SEP, finfo.name);
                continue;
            }
            len = snprintf(destpath, sizeof(destpath), "%s%c%s",
                           destdir[0], PATH_SEP, finfo.name);
            if ((len >= sizeof(destpath)) || (len == -1)) {
                glog0(group, "Max pathname length exceeded: %s%c%s",
                             destdir[0], PATH_SEP, finfo.name);
                continue;
            }
            // do the move
            if (strcmp(finfo.name, ".") && strcmp(finfo.name, "..")) {
                clear_path(destpath, group);
                if (!MoveFile(temppath, destpath)) {
                    char errbuf[300];
                    FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL,
                            GetLastError(), 0, errbuf, sizeof(errbuf), NULL);
                    glog0(group, "error (%d): %s", GetLastError(), errbuf);
                }
                filelist[filecount] = strdup(destpath);
                if (filelist[filecount] == NULL) {
                    gsyserror(group, "strdup failed!");
                    exit(ERR_ALLOC);
                }
                filecount++;
            }
        } while (_findnexti64(ffhandle, &finfo) == 0);
        _findclose(ffhandle);
#else
        DIR *dir;
        struct dirent *de;
        char dirname[MAXPATHNAME];

        snprintf(dirname, sizeof(dirname), "%s%c_group_%08X", tempdir,
                 PATH_SEP, group->group_id);
        if ((dir = opendir(dirname)) == NULL) {
            gsyserror(group, "Failed to open directory %s", dirname);
            return;
        }
        filecount = 0;
        // errno needs to be set to 0 before calling readdir, otherwise
        // we'll report a false error when we exhaust the directory
        while ((errno = 0, de = readdir(dir)) != NULL) {
            len = snprintf(temppath, sizeof(temppath), "%s%c%s", dirname,
                           PATH_SEP, de->d_name);
            if ((len >= sizeof(temppath)) || (len == -1)) {
                glog0(group, "Max pathname length exceeded: %s%c%s", dirname,
                             PATH_SEP, de->d_name);
                continue;
            }
            len = snprintf(destpath, sizeof(destpath), "%s%c%s", destdir[0],
                           PATH_SEP, de->d_name);
            if ((len >= sizeof(destpath)) || (len == -1)) {
                glog0(group, "Max pathname length exceeded: %s%c%s", destdir[0],
                             PATH_SEP, de->d_name);
                continue;
            }
            if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
                clear_path(destpath, group);
                if (rename(temppath, destpath) == -1) {
                    gsyserror(group, "Couldn't move file");
                }
                filelist[filecount] = strdup(destpath);
                if (filelist[filecount] == NULL) {
                    gsyserror(group, "strdup failed!");
                    exit(ERR_ALLOC);
                }
                filecount++;
            }
        }
        if (errno && (errno != ENOENT)) {
            gsyserror(group, "Failed to read directory %s", dirname);
        }
        closedir(dir);
#endif
    }
    run_postreceive_multi(group, filelist, filecount);
    for (i = 0; i < filecount; i++) {
        free(filelist[i]);
    }
    snprintf(temppath, sizeof(temppath), "%s%c_group_%08X", tempdir,
             PATH_SEP, group->group_id);
    if (rmdir(temppath) == -1) {
        gsyserror(group, "Failed remove temp directory %s", temppath);
    }
}
Example #8
0
/**
 * Removes a full path from disk
 */
void clear_path(const char *path, int listidx)
{
    stat_struct statbuf;
    char filename[MAXPATHNAME];
    int len;

    if (lstat_func(path, &statbuf) == -1) {
        if (errno != ENOENT) {
            syserror(group_list[listidx].group_id, group_list[listidx].file_id,
                     "Error getting file status for %s", path);
        }
        return;
    }
    if (!S_ISDIR(statbuf.st_mode)) {
        unlink(path);
    } else {
#ifdef WINDOWS
        intptr_t ffhandle;
        struct _finddatai64_t finfo;
        char dirglob[MAXPATHNAME];

        snprintf(dirglob, sizeof(dirglob), "%s%c*", path,
                 PATH_SEP, group_list[listidx].group_id, PATH_SEP);
        if ((ffhandle = _findfirsti64(dirglob, &finfo)) == -1) {
            syserror(group_list[listidx].group_id, group_list[listidx].file_id,
                     "Failed to open directory %s", path);
            return;
        }
        do {
            len = snprintf(filename, sizeof(filename), "%s%c%s", path,
                           PATH_SEP, finfo.name);
            if ((len >= sizeof(filename)) || (len == -1)) {
                log0(group_list[listidx].group_id, group_list[listidx].file_id,
                        "Max pathname length exceeded: %s%c%s",
                        filename, PATH_SEP, finfo.name);
                continue;
            }
            if (strcmp(finfo.name, ".") && strcmp(finfo.name, "..")) {
                clear_path(filename, listidx);
            }
        } while (_findnexti64(ffhandle, &finfo) == 0);
        _findclose(ffhandle);
#else
        DIR *dir;
        struct dirent *de;

        if ((dir = opendir(path)) == NULL) {
            syserror(group_list[listidx].group_id, group_list[listidx].file_id,
                     "Failed to open directory %s", path);
            return;
        }
        // errno needs to be set to 0 before calling readdir, otherwise
        // we'll report a false error when we exhaust the directory
        while ((errno = 0, de = readdir(dir)) != NULL) {
            len = snprintf(filename, sizeof(filename), "%s%c%s", path, PATH_SEP,
                           de->d_name);
            if ((len >= sizeof(filename)) || (len == -1)) {
                log0(group_list[listidx].group_id, group_list[listidx].file_id,
                        "Max pathname length exceeded: %s%c%s", path,
                        PATH_SEP, de->d_name);
                continue;
            }
            if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
                clear_path(filename, listidx);
            }
        }
        if (errno && (errno != ENOENT)) {
            syserror(group_list[listidx].group_id, group_list[listidx].file_id,
                     "Failed to read directory %s", path);
        }
        closedir(dir);
#endif
        if (rmdir(path) == -1) {
            syserror(group_list[listidx].group_id, group_list[listidx].file_id,
                     "Failed remove directory %s", path);
        }
    }
}
Example #9
0
/**
 * Performs the send for a particular file/directory.  If a directory is
 * specified, get the list of files and call recursively for each.
 * Returns 0 if a file was sent and none received it, 1 otherwise
 */
int send_file(const char *basedir, const char *filename,
              const char *n_destfname, uint32_t group_id)
{
    static uint16_t file_id = 1;
    struct finfo_t finfo;
    stat_struct statbuf;
    char path[MAXPATHNAME], destpath[MAXPATHNAME];
    int len, rval, fd, emptydir;

    log(0, 0, "----- %s -----", filename);
    len = snprintf(path, sizeof(path), "%s%c%s", basedir, PATH_SEP, filename);
    if ((len >= sizeof(path)) || (len == -1)) {
        log(0, 0, "Max pathname length exceeded: %s%c%s",
                   basedir, PATH_SEP, filename);
        return 1;
    }
    if (follow_links) {
        rval = stat_func(path, &statbuf);
    } else {
        rval = lstat_func(path, &statbuf);
    }
    if (rval == -1) {
        syserror(0, 0, "Error getting file status for %s", filename);
        return 1;
    }
    if (file_excluded(filename)) {
        log(0, 0, "Skipping %s", filename);
        return 1;
    }
    rval = 1;
    if (S_ISREG(statbuf.st_mode)) {
        if ((fd = open(path, OPENREAD, 0)) == -1) {
            syserror(0, 0, "Error reading file %s", filename);
            return 1;
        }
        close(fd);
        memset(&finfo, 0, sizeof(struct finfo_t));
        finfo.ftype = FTYPE_REG;
        finfo.basedir = basedir;
        finfo.filename = filename;
        finfo.destfname = n_destfname;
        finfo.group_id = group_id;
        finfo.file_id = file_id++;
        if (file_id == 0) {
            file_id = 1;
        }
        finfo.size = statbuf.st_size;
        finfo.blocks = (int32_t)((finfo.size / blocksize) +
                (finfo.size % blocksize ? 1 :0));
        finfo.sections = (finfo.blocks / (blocksize * 8)) +
                (finfo.blocks % (blocksize * 8) ? 1 : 0);
        finfo.naklist = calloc(finfo.blocks, 1);
        finfo.deststate = calloc(destcount ? destcount : MAXDEST,
                sizeof(struct deststate_t));
        if ((finfo.naklist == NULL) || (finfo.deststate == NULL)) {
            syserror(0, 0, "calloc failed!");
            exit(1);
        }
        finfo.partial = 1;
        rval = announce_phase(&finfo);
        if (rval) {
            rval = transfer_phase(&finfo);
        }
        free(finfo.deststate);
        free(finfo.naklist);
#ifndef WINDOWS
    } else if (S_ISLNK(statbuf.st_mode)) {
        char linkname[MAXPATHNAME];

        memset(linkname, 0, sizeof(linkname));
        if (readlink(path, linkname, sizeof(linkname)-1) == -1) {
            syserror(0, 0, "Failed to read symbolic link %s", path);
            return 1;
        }
        // Both the file name and the link have to fit into a fileinfo_h.name
        if (strlen(linkname) + strlen(filename) + 2 > MAXPATHNAME) {
            log(0, 0, "Combined file name %s and link %s too long",
                      filename, linkname);
            return 1;
        }
        memset(&finfo, 0, sizeof(struct finfo_t));
        finfo.ftype = FTYPE_LINK;
        finfo.basedir = basedir;
        finfo.filename = filename;
        finfo.destfname = n_destfname;
        finfo.linkname = linkname;
        finfo.group_id = group_id;
        finfo.file_id = file_id++;
        if (file_id == 0) {
            file_id = 1;
        }
        finfo.deststate = calloc(destcount ? destcount : MAXDEST,
                sizeof(struct deststate_t));
        if (finfo.deststate == NULL) {
            syserror(0, 0, "calloc failed!");
            exit(1);
        }
        finfo.partial = 1;
        rval = announce_phase(&finfo);
        if (rval) {
            rval = transfer_phase(&finfo);
        }
#endif
    } else if (S_ISDIR(statbuf.st_mode)) {
        // read directory and do recursive send
#ifdef WINDOWS
        intptr_t ffhandle;
        struct _finddatai64_t ffinfo;
        char dirglob[MAXPATHNAME];

        snprintf(dirglob, sizeof(dirglob), "%s%c%s%c*", basedir, PATH_SEP,
                                                        filename, PATH_SEP);
        if ((ffhandle = _findfirsti64(dirglob, &ffinfo)) == -1) {
            syserror(0, 0, "Failed to open directory %s%c%s", basedir, PATH_SEP,
                                                              filename);
            return 1;
        }
        emptydir = 1;
        do {
            len = snprintf(path, sizeof(path), "%s/%s", filename, ffinfo.name);
            if ((len >= sizeof(path)) || (len == -1)) {
                log(0, 0, "Max pathname length exceeded: %s/%s",
                           filename, ffinfo.name);
                continue;
            }
            len = snprintf(destpath, sizeof(destpath), "%s/%s",
                           n_destfname, ffinfo.name);
            if ((len >= sizeof(destpath)) || (len == -1)) {
                log(0, 0, "Max pathname length exceeded: %s/%s",
                           n_destfname, ffinfo.name);
                continue;
            }
            if (strcmp(ffinfo.name, ".") && strcmp(ffinfo.name, "..")) {
                emptydir = 0;
                if (!send_file(basedir, path, destpath, group_id)) {
                    rval = 0;
                    break;
                }
            }
        } while (_findnexti64(ffhandle, &ffinfo) == 0);
        _findclose(ffhandle);
#else
        DIR *dir;
        struct dirent *de;
        char dirname[MAXPATHNAME];

        snprintf(dirname, sizeof(dirname), "%s%c%s", basedir,PATH_SEP,filename);
        if ((dir = opendir(dirname)) == NULL) {
            syserror(0, 0, "Failed to open directory %s", dirname);
            return 1;
        }
        // errno needs to be set to 0 before calling readdir, otherwise
        // we'll report a false error when we exhaust the directory
        emptydir = 1;
        while ((errno = 0, de = readdir(dir)) != NULL) {
            len = snprintf(path, sizeof(path), "%s/%s", filename, de->d_name);
            if ((len >= sizeof(path)) || (len == -1)) {
                log(0, 0, "Max pathname length exceeded: %s/%s",
                           filename, de->d_name);
                continue;
            }
            len = snprintf(destpath, sizeof(destpath), "%s/%s",
                           n_destfname, de->d_name);
            if ((len >= sizeof(destpath)) || (len == -1)) {
                log(0, 0, "Max pathname length exceeded: %s/%s",
                           n_destfname, de->d_name);
                continue;
            }
            if (strcmp(de->d_name, ".") && strcmp(de->d_name, "..")) {
                emptydir = 0;
                if (!send_file(basedir, path, destpath, group_id)) {
                    rval = 0;
                    break;
                }
            }
        }
        if (errno && (errno != ENOENT)) {
            syserror(0, 0, "Failed to read directory %s", filename);
        }
        closedir(dir);
#endif
        if (emptydir) {
            memset(&finfo, 0, sizeof(struct finfo_t));
            finfo.ftype = FTYPE_DIR;
            finfo.basedir = basedir;
            finfo.filename = filename;
            finfo.destfname = n_destfname;
            finfo.group_id = group_id;
            finfo.file_id = file_id++;
            if (file_id == 0) {
                file_id = 1;
            }
            finfo.deststate = calloc(destcount ? destcount : MAXDEST,
                    sizeof(struct deststate_t));
            if (finfo.deststate == NULL) {
                syserror(0, 0, "calloc failed!");
                exit(1);
            }
            finfo.partial = 1;
            rval = announce_phase(&finfo);
            if (rval) {
                rval = transfer_phase(&finfo);
            }
        }
    } else {
        log(0, 0, "Skipping special file %s", filename);
    }
    return rval;
}