bool CFileHelpers::removeDir(const char *Dir)
{
	CFileHelpers* fh = CFileHelpers::getInstance();
	fh->clearDebugInfo();
	DIR *dir;
	struct dirent *entry;
	char path[PATH_MAX];

	dir = opendir(Dir);
	if (dir == NULL) {
		if (errno == ENOENT)
			return true;
		if (!fh->getConsoleQuiet())
			dprintf(DEBUG_NORMAL, "[CFileHelpers %s] remove directory %s: %s\n", __func__, Dir, strerror(errno));
		char buf[1024];
		memset(buf, '\0', sizeof(buf));
		snprintf(buf, sizeof(buf)-1, "remove directory %s: %s", Dir, strerror(errno));
		fh->setDebugInfo(buf, __path_file__, __func__, __LINE__);
		return false;
	}
	while ((entry = readdir(dir)) != NULL) {
		if (strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) {
			snprintf(path, (size_t) PATH_MAX, "%s/%s", Dir, entry->d_name);
			if (entry->d_type == DT_DIR)
				removeDir(path);
			else
				unlink(path);
		}
	}
	closedir(dir);
	rmdir(Dir);

	errno = 0;
	return true;
}
// returns:	 true - success.
//		 false - errno is set
bool CFileHelpers::createDir(string& Dir, mode_t mode)
{
	CFileHelpers* fh = CFileHelpers::getInstance();
	fh->clearDebugInfo();
	int res = 0;
	for(string::iterator iter = Dir.begin() ; iter != Dir.end();) {
		string::iterator newIter = find(iter, Dir.end(), '/' );
		string newPath = string( Dir.begin(), newIter );
		if(!newPath.empty() && !file_exists(newPath.c_str())) {
			res = mkdir( newPath.c_str(), mode);
			if (res == -1) {
				if (errno == EEXIST) {
					res = 0;
				} else {
					// We can assume that if an error
					// occured, following will fail too,
					// so break here.
					if (!fh->getConsoleQuiet())
						dprintf(DEBUG_NORMAL, "[CFileHelpers %s] creating directory %s: %s\n", __func__, newPath.c_str(), strerror(errno));
					char buf[1024];
					memset(buf, '\0', sizeof(buf));
					snprintf(buf, sizeof(buf)-1, "creating directory %s: %s", newPath.c_str(), strerror(errno));
					fh->setDebugInfo(buf, __path_file__, __func__, __LINE__);
					break;
				}
			}
		}
		iter = newIter;
		if(newIter != Dir.end())
			++ iter;
	}

	return (res == 0 ? true : false);
}
Example #3
0
int CLuaInstFileHelpers::FileHelpersCp(lua_State *L)
{
	CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
	if (!D) return 0;

	int numargs = lua_gettop(L) - 1;
	int min_numargs = 2;
	if (numargs < min_numargs) {
		printf("luascript cp: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
		lua_pushboolean(L, false);
		return 1;
	}

	if (!lua_isstring(L, 2) || !lua_isstring(L, 3)) {
		printf("%s: argument 1 or 2 is not a string.\n",__func__);
		lua_pushboolean(L, false);
		return 1;
	}
	const char *from = luaL_checkstring(L, 2);
	const char *to = luaL_checkstring(L, 3);

	const char *flags = "";
	if (numargs > min_numargs){
		if (!lua_isstring(L, 4)) {
			printf("%s: argument 3 is not a string.\n",__func__);
			lua_pushboolean(L, false);
			return 1;
		}
		flags = luaL_checkstring(L, 4);
	}
	bool ret = false;
	CFileHelpers fh;
	fh.setConsoleQuiet(true);
	ret = fh.cp(from, to, flags);
	if (ret == false) {
		helpersDebugInfo di;
		fh.readDebugInfo(&di);
		lua_Debug ar;
		lua_getstack(L, 1, &ar);
		lua_getinfo(L, "Sl", &ar);
		printf(">>> Lua script error [%s:%d] %s\n    (error from neutrino: [%s:%d])\n",
		       ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line);
	}

	lua_pushboolean(L, ret);
	return 1;
}
Example #4
0
int CLuaInstFileHelpers::FileHelpersMkdir(lua_State *L)
{
	CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
	if (!D) return 0;

	int numargs = lua_gettop(L) - 1;
	int min_numargs = 1;
	if (numargs < min_numargs) {
		printf("luascript mkdir: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
		lua_pushboolean(L, false);
		return 1;
	}
	if (!lua_isstring(L, 2)) {
		printf("%s: argument 1 is not a string.\n",__func__);
		lua_pushboolean(L, false);
		return 1;
	}
	const char *dir = luaL_checkstring(L, 2);

	mode_t mode = 0755;
	if (numargs > min_numargs) {
		int mode_i = luaL_checkint(L, 3);
		/* Hack for convert lua number to octal */
		std::string mode_s = itoa(mode_i, 10);
		mode = (mode_t)(strtol(mode_s.c_str(), (char **)NULL, 8) & 0x0FFF);
		//printf("\n##### [%s:%d] str: %s, okt: %o \n \n", __func__, __LINE__, mode_s.c_str(), (int)mode);
	}

	bool ret = false;
	CFileHelpers* fh = CFileHelpers::getInstance();
	fh->setConsoleQuiet(true);
	ret = fh->createDir(dir, mode);
	if (ret == false) {
		helpersDebugInfo di;
		fh->readDebugInfo(&di);
		lua_Debug ar;
		lua_getstack(L, 1, &ar);
		lua_getinfo(L, "Sl", &ar);
		printf(">>> Lua script error [%s:%d] %s\n    (error from neutrino: [%s:%d])\n",
		       ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line);
	}

	lua_pushboolean(L, ret);
	return 1;
}
Example #5
0
int CLuaInstFileHelpers::FileHelpersRmdir(lua_State *L)
{
	CLuaFileHelpers *D = FileHelpersCheckData(L, 1);
	if (!D) return 0;

	int numargs = lua_gettop(L) - 1;
	int min_numargs = 1;
	if (numargs < min_numargs) {
		printf("luascript rmdir: not enough arguments (%d, expected %d)\n", numargs, min_numargs);
		lua_pushboolean(L, false);
		return 1;
	}
	if (!lua_isstring(L, 2)) {
		printf("%s: argument 1 is not a string.\n",__func__);
		lua_pushboolean(L, false);
		return 1;
	}
	const char *dir = luaL_checkstring(L, 2);

	bool ret = false;
	CFileHelpers* fh = CFileHelpers::getInstance();
	fh->setConsoleQuiet(true);
	ret = fh->removeDir(dir);
	if (ret == false) {
		helpersDebugInfo di;
		fh->readDebugInfo(&di);
		lua_Debug ar;
		lua_getstack(L, 1, &ar);
		lua_getinfo(L, "Sl", &ar);
		printf(">>> Lua script error [%s:%d] %s\n    (error from neutrino: [%s:%d])\n",
		       ar.short_src, ar.currentline, di.msg.c_str(), di.file.c_str(), di.line);
	}

	lua_pushboolean(L, ret);
	return 1;
}
bool COPKGManager::checkSize(const string& pkg_name)
{
	string pkg_file = pkg_name;
	string plain_pkg = getBaseName(pkg_file);

	//exit check size if package already installed, because of auto remove of old stuff during installation
	if (isInstalled(plain_pkg))
		return true;

	/* this is pretty broken right now for several reasons:
	   * space in /tmp is limited (/tmp being ramfs usually, but wasted
	     by unpacking the archive and then untaring it instead of using a pipe
	   * the file is downloaded for this test, then discarded and later
	     downloaded again for installation
	   so until a better solution is found, simply disable it.  */
#if 0
	//get available root fs size
	//TODO: Check writability!
	struct statfs root_fs;
	statfs("/", &root_fs);
	u_int64_t free_size = root_fs.f_bfree*root_fs.f_bsize;

	/*
	 * To calculate the required size for installation here we make a quasi-dry run,
	 * it is a bit awkward, but relatively specific, other solutions are welcome.
	 * We create a temporary test directory and fill it with downloaded or user uploaded package file.
	 * Then we unpack the package and change into temporary testing directory.
	 * The required size results from the size of generated folders and subfolders.
	 * TODO: size of dependencies are not really considered
	*/
	CFileHelpers fh;

	//create test pkg dir
	string 	tmp_dest = OPKG_TEST_DIR;
		tmp_dest += "/package";
	fh.createDir(tmp_dest);

	//change into test dir
	chdir(OPKG_TEST_DIR);

	//copy package into test dir
	string  tmp_dest_file = OPKG_TEST_DIR;
		tmp_dest_file += "/" + plain_pkg;
	if(!access( pkg_file.c_str(), F_OK)) //use local package
		fh.copyFile(pkg_file.c_str(), tmp_dest_file.c_str(), 0644);
	else
		execCmd(pkg_types[OM_DOWNLOAD] + plain_pkg); //download package

	//unpack package into test dir
	string ar = "ar -x " + plain_pkg + char(0x2a);
	execCmd(ar);

	//untar package into test directory
	string 	untar_tar_cmd = "tar -xf ";
		untar_tar_cmd += OPKG_TEST_DIR;
		untar_tar_cmd += "/data.tar.gz -C " + tmp_dest;
	execCmd(untar_tar_cmd);

	//get new current required minimal size from dry run test dir
	u_int64_t req_size = fh.getDirSize(tmp_dest);

	//clean up
	fh.removeDir(OPKG_TEST_DIR);

	dprintf(DEBUG_INFO,  "[COPKGManager] [%s - %d] Package: %s [required size=%" PRId64 " (free size: %" PRId64 ")]\n", __func__, __LINE__, pkg_name.c_str(), req_size, free_size);
	if (free_size < req_size){
		//exit if required size too much
		dprintf(DEBUG_NORMAL,  "[COPKGManager] [%s - %d]  WARNING: size check freesize=%" PRId64 " (recommended: %" PRId64 ")\n", __func__, __LINE__, free_size, req_size);
		return false;
	}
#endif
	return true;
}
Example #7
0
bool cYTCache::download(MI_MOVIE_INFO *mi)
{
	std::string file = getName(mi);
	std::string xml = getName(mi, "xml");
	if (!access(file, R_OK) && !access(xml, R_OK)) {
		fprintf(stderr, "%s: %s already present and valid\n", __func__, file.c_str());
		return true;
	}

	FILE * fp = fopen(file.c_str(), "wb");
	if (!fp) {
		perror(file.c_str());
		return false;
	}

	CURL *curl = curl_easy_init();
	if (!curl) {
		fclose(fp);
		return false;
	}

	curl_easy_setopt(curl, CURLOPT_URL, mi->file.Url.c_str());
	curl_easy_setopt(curl, CURLOPT_FILE, fp);
	curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1);
	curl_easy_setopt(curl, CURLOPT_TIMEOUT, URL_TIMEOUT);
	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1);
	curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, cYTCache::curlProgress); 
	curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, this); 
	curl_easy_setopt(curl, CURLOPT_NOPROGRESS, (long)0); 
	curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);

	char cerror[CURL_ERROR_SIZE];
	curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, cerror);

	if(!g_settings.softupdate_proxyserver.empty()) {
		curl_easy_setopt(curl, CURLOPT_PROXY, g_settings.softupdate_proxyserver.c_str());
		if(!g_settings.softupdate_proxyusername.empty()) {
			std::string tmp = g_settings.softupdate_proxyusername + ":" + g_settings.softupdate_proxypassword;
			curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, tmp.c_str());
		}
	}

	dltotal = 0;
	dlnow = 0;
	dlstart = time(NULL);

	fprintf (stderr, "downloading %s to %s\n", mi->file.Url.c_str(), file.c_str());
	CURLcode res = curl_easy_perform(curl);
	curl_easy_cleanup(curl);

	fclose(fp);

	if (res) {
		fprintf (stderr, "downloading %s to %s failed: %s\n", mi->file.Url.c_str(), file.c_str(), cerror);
		unlink(file.c_str());
		return false;
	}
	CMovieInfo cMovieInfo;
	CFile File;
	File.Name = xml;
	cMovieInfo.saveMovieInfo(*mi, &File);
	std::string thumbnail_dst = getName(mi, "jpg");
	CFileHelpers fh;
	fh.copyFile(mi->tfile.c_str(), thumbnail_dst.c_str(), 0644);
	return true;
}
Example #8
0
CFSMounter::MountRes CFSMounter::mount(const std::string &ip, const std::string &dir, const std::string &local_dir,
				       const FSType fstype, const std::string &username, const std::string &password,
				       std::string options1, std::string options2)
{
	std::string cmd;
	pthread_mutex_init(&g_mut, NULL);
	pthread_cond_init(&g_cond, NULL);
	g_mntstatus=-1;

	FS_Support sup = fsSupported(fstype, true); /* keep modules if necessary */

	if (sup == CFSMounter::FS_UNSUPPORTED)
	{
		printf("[CFSMounter] FS type %d not supported\n", (int) fstype);
		return MRES_FS_NOT_SUPPORTED;
	}

	printf("[CFSMounter] Mount(%d) %s:%s -> %s\n", (int) fstype, ip.c_str(), dir.c_str(), local_dir.c_str());

	CFileHelpers fh;
	fh.createDir(local_dir.c_str(), 0755);
	
	if (isMounted(local_dir))
	{
		printf("[CFSMounter] FS mount error %s already mounted\n", local_dir.c_str());
		return MRES_FS_ALREADY_MOUNTED;
	}

	if(options1.empty())
	{
		options1 = options2;
		options2 = "";
	}
	
	if(options1.empty() && options2.empty())
	{
		if(fstype == NFS)
		{
			options1 = "ro,soft,udp";
			options2 = "nolock,rsize=8192,wsize=8192";
		}
		else if(fstype == CIFS)
		{
			options1 = "ro";
			options2 = "";
		}
		else if(fstype == LUFS)
		{
			options1 = "";
			options2 = "";
		}
	}
	
	if(fstype == NFS)
	{
		cmd = "mount -t nfs ";
		cmd += ip;
		cmd += ':';
		cmd += dir;
		cmd += ' ';
		cmd += local_dir;
		cmd += " -o ";
		cmd += options1;
	}
	else if(fstype == CIFS)
	{
		cmd = "mount -t cifs //";
		cmd += ip;
		cmd += '/';
		cmd += dir;
		cmd += ' ';
		cmd += local_dir;
		cmd += " -o username="******",password="******",iocharset=UTF8";
		//cmd += ",unc=//"; for whats needed?
		//cmd += ip;
		//cmd += '/';
		//cmd += dir;
		//cmd += ',';
		//cmd += options1;
	}
	else
	{
		cmd = "lufsd none ";
		cmd += local_dir;
		cmd += " -o fs=ftpfs,username="******",password="******",host=";
		cmd += ip;
		cmd += ",root=/";
		cmd += dir;
		cmd += ',';
		cmd += options1;
	}
	
	if (options2[0] !='\0')
	{
		cmd += ',';
		cmd += options2;
	}
	
	pthread_create(&g_mnt, 0, mount_thread, (void *) cmd.c_str());
	
	struct timespec timeout;
	int retcode;

	pthread_mutex_lock(&g_mut);
	timeout.tv_sec = time(NULL) + 5;
	timeout.tv_nsec = 0;
	retcode = pthread_cond_timedwait(&g_cond, &g_mut, &timeout);
	if (retcode == ETIMEDOUT) 
	{  // timeout occurred
		pthread_cancel(g_mnt);
	}
	pthread_mutex_unlock(&g_mut);
	pthread_join(g_mnt, NULL);
	if ( g_mntstatus != 0 )
	{
		printf("[CFSMounter] FS mount error: \"%s\"\n", cmd.c_str());
		return (retcode == ETIMEDOUT) ? MRES_TIMEOUT : MRES_UNKNOWN;
	}
	return MRES_OK;

}
bool CFlashTool::program( const std::string & filename, int globalProgressEndErase, int globalProgressEndFlash )
{
	int fd1;
	ssize_t filesize;
	int globalProgressBegin = 0;

	if(g_settings.epg_save)
		CNeutrinoApp::getInstance()->saveEpg(true);

	if(statusViewer)
		statusViewer->showLocalStatus(0);

	if (mtdDevice.empty()) {
		ErrorMessage = "mtd-device not set";
		return false;
	}

	char buf1[1024];
	memset(buf1, 0, sizeof(buf1));
	strncpy(buf1, filename.c_str(), sizeof(buf1)-1);
	char* dn = dirname(buf1);
	std::string flashfile;

	bool skipCopy = false;
#ifdef BOXMODEL_APOLLO
	if (strcmp(dn, "/tmp") != 0) {
		uint64_t btotal = 0, bused = 0;
		long bsize = 0;
		if (get_fs_usage("/tmp", btotal, bused, &bsize)) {
			uint64_t fileSize = (uint64_t)file_size(filename.c_str()) / 1024ULL;
			uint64_t backupMaxSize = (int)((btotal - bused) * bsize);
			uint64_t res = 10; // Reserved 10% of available space
			backupMaxSize = (backupMaxSize - ((backupMaxSize * res) / 100ULL)) / 1024ULL;
			if (backupMaxSize < fileSize)
				skipCopy = true;
		}
		else
			skipCopy = true;
	}
#endif

	if ((strcmp(dn, "/tmp") != 0) && !skipCopy) {
		memset(buf1, 0, sizeof(buf1));
		strncpy(buf1, filename.c_str(), sizeof(buf1)-1);
		flashfile = (std::string)"/tmp/" + basename(buf1);
		CFileHelpers fh;
		printf("##### [CFlashTool::program] copy flashfile to %s\n", flashfile.c_str());
		if(statusViewer)
			statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_COPY_IMAGE));
		fh.copyFile(filename.c_str(), flashfile.c_str(), 0644);
		sync();
		if(statusViewer)
			statusViewer->showGlobalStatus(statusViewer->getGlobalStatus()+5);
	}
	else
		flashfile = filename;

	// Unmount all NFS & CIFS volumes
	if (!skipCopy) {
		nfs_mounted_once = false;
		CFSMounter::umount();
	}

	if( (fd1 = open( flashfile.c_str(), O_RDONLY )) < 0 ) {
		ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENFILE);
		return false;
	}

	filesize = (ssize_t)lseek( fd1, 0, SEEK_END);
	lseek( fd1, 0, SEEK_SET);

	if(filesize==0) {
		ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_FILEIS0BYTES);
		close(fd1);
		return false;
	}

	if(statusViewer) {
		statusViewer->showLocalStatus(0);
		statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_ERASING)); // UTF-8
	}

	if(!erase(globalProgressEndErase)) {
		close(fd1);
		return false;
	}

	if(statusViewer) {
		if(globalProgressEndErase!=-1)
			statusViewer->showGlobalStatus(globalProgressEndErase);
		statusViewer->showLocalStatus(0);
		statusViewer->showStatusMessageUTF(g_Locale->getText(LOCALE_FLASHUPDATE_PROGRAMMINGFLASH)); // UTF-8
	}
#ifndef VFD_UPDATE
	CVFD::getInstance()->ShowText("Write Flash");
#endif

	if( (fd = open( mtdDevice.c_str(), O_WRONLY )) < 0 ) {
		ErrorMessage = g_Locale->getText(LOCALE_FLASHUPDATE_CANTOPENMTD);
		close(fd1);
		return false;
	}

	if(statusViewer)
		globalProgressBegin = statusViewer->getGlobalStatus();

	unsigned char buf[meminfo.writesize];
	unsigned mtdoffset = 0;
	unsigned fsize = filesize;
	printf("CFlashTool::program: file %s write size %d, erase size %d\n", flashfile.c_str(), meminfo.writesize, meminfo.erasesize);
	while(fsize > 0) {
		unsigned block = meminfo.writesize;
		if (block > fsize)
			block = fsize;

		unsigned res = read(fd1, buf, block);
		if (res != block) {
			printf("CFlashTool::program: read from %s failed: %d from %d\n", flashfile.c_str(), res, block);
		}
		if (isnand) {
			if (block < (unsigned) meminfo.writesize) {
				printf("CFlashTool::program: padding at %x\n", mtdoffset);
				memset(buf + res, 0, meminfo.writesize - res);
			}
			unsigned blockstart = mtdoffset & ~(meminfo.erasesize - 1);
			if (blockstart == mtdoffset) {
				while (mtdoffset < meminfo.size) {
					printf("CFlashTool::program: write block at %x\n", mtdoffset);
					loff_t offset = mtdoffset;
					int ret = ioctl(fd, MEMGETBADBLOCK, &offset);
					if (ret == 0)
						break;
					printf("CFlashTool::program: bad block at %x, skipping..\n", mtdoffset);
					mtdoffset += meminfo.erasesize;
					lseek(fd, mtdoffset, SEEK_SET);
					continue;
				}
				if (mtdoffset >= meminfo.size) {
					printf("CFlashTool::program: not enough space to write, left: %d\n", fsize);
					break;
				}
			}
		}
		write(fd, buf, meminfo.writesize);
		fsize -= block;
		mtdoffset += meminfo.writesize;
		int prog = int(100-(100./filesize*fsize));
		if(statusViewer) {
			statusViewer->showLocalStatus(prog);
			if(globalProgressEndFlash!=-1) {
				int globalProg = globalProgressBegin + int((globalProgressEndFlash-globalProgressBegin) * prog/100. );
				statusViewer->showGlobalStatus(globalProg);
			}
		}
		printf( "Writing %u Kbyte @ 0x%08X -- %2u %% complete.\n", block/1024, mtdoffset, prog);
	}

	if(statusViewer)
		statusViewer->showLocalStatus(100);

	close(fd1);
	close(fd);
	// FIXME error message
	if (fsize)
		return false;
	CVFD::getInstance()->ShowText("Flash OK.");
	return true;
}