static void BuildFileList0(const TCHAR *config_dir, bool warn_duplicates) { WIN32_FIND_DATA find_obj; HANDLE find_handle; TCHAR find_string[MAX_PATH]; TCHAR subdir_table[MAX_CONFIG_SUBDIRS][MAX_PATH]; TCHAR fullpath[MAX_PATH]; int subdirs = 0; int i; _sntprintf_0(find_string, _T("%s\\*"), config_dir); find_handle = FindFirstFile(find_string, &find_obj); if (find_handle == INVALID_HANDLE_VALUE) return; /* Loop over each config file in main config dir */ do { if (o.num_configs >= MAX_CONFIGS) { ShowLocalizedMsg(IDS_ERR_MANY_CONFIGS, MAX_CONFIGS); break; } match_t match_type = match(&find_obj, o.ext_string); if (match_type == match_file) { _sntprintf_0(fullpath, _T("%s\\%s"), config_dir, find_obj.cFileName); if (ConfigAlreadyExists(find_obj.cFileName)) { if (warn_duplicates) ShowLocalizedMsg(IDS_ERR_CONFIG_EXIST, find_obj.cFileName); continue; } if (CheckReadAccess (fullpath)) AddConfigFileToList(o.num_configs++, find_obj.cFileName, config_dir); } else if (match_type == match_dir) { if (_tcsncmp(find_obj.cFileName, _T("."), _tcslen(find_obj.cFileName)) != 0 && _tcsncmp(find_obj.cFileName, _T(".."), _tcslen(find_obj.cFileName)) != 0 && subdirs < MAX_CONFIG_SUBDIRS) { /* Add dir to dir_table */ _sntprintf_0(subdir_table[subdirs], _T("%s\\%s"), config_dir, find_obj.cFileName); subdirs++; } } } while (FindNextFile(find_handle, &find_obj)); FindClose(find_handle); /* Loop over each config file in every subdir */ for (i = 0; i < subdirs; ++i) { _sntprintf_0(find_string, _T("%s\\*"), subdir_table[i]); find_handle = FindFirstFile (find_string, &find_obj); if (find_handle == INVALID_HANDLE_VALUE) continue; do { if (o.num_configs >= MAX_CONFIGS) { ShowLocalizedMsg(IDS_ERR_MANY_CONFIGS, MAX_CONFIGS); FindClose(find_handle); return; } /* does file have the correct type and extension? */ if (match(&find_obj, o.ext_string) != match_file) continue; if (ConfigAlreadyExists(find_obj.cFileName)) { if (warn_duplicates) ShowLocalizedMsg(IDS_ERR_CONFIG_EXIST, find_obj.cFileName); continue; } AddConfigFileToList(o.num_configs++, find_obj.cFileName, subdir_table[i]); } while (FindNextFile(find_handle, &find_obj)); FindClose(find_handle); } }
/* * write specified amount of bytes from buffer to given desc/offset * return amount of read bytes or negative error code if call failed */ int32_t ZVMWriteHandle(struct NaClApp *nap, int ch, const char *buffer, int32_t size, int64_t offset) { struct ChannelDesc *channel; int64_t tail; const char *sys_buffer; int32_t retcode = ERR_CODE; assert(nap != NULL); assert(nap->system_manifest != NULL); assert(nap->system_manifest->channels != NULL); /* check the channel number */ if(ch < 0 || ch >= nap->system_manifest->channels_count) return -EINVAL; channel = &nap->system_manifest->channels[ch]; /* check buffer and convert address */ if(CheckReadAccess(nap, buffer, size) == ERR_CODE) return -EINVAL; sys_buffer = (char*)NaClUserToSys(nap, (uintptr_t) buffer); /* prevent writing to the not writable channel */ if(CHANNEL_WRITEABLE(channel) == 0) return -EBADF; /* ignore user offset for sequential access write */ if(CHANNEL_SEQ_WRITEABLE(channel)) offset = channel->putpos; /* check arguments sanity */ if(size == 0) return 0; /* success. user has read 0 bytes */ if(size < 0) return -EFAULT; if(offset < 0) return -EINVAL; /* check limits */ if(channel->counters[PutsLimit] >= channel->limits[PutsLimit]) return -EDQUOT; tail = channel->limits[PutSizeLimit] - channel->counters[PutSizeLimit]; if(offset >= channel->limits[PutSizeLimit] && !CHANNEL_READABLE(channel)) return -EINVAL; if(offset >= channel->size + tail) return -EINVAL; if(size > tail) size = tail; if(size < 1) return -EDQUOT; ZLOGS(LOG_DEBUG, "channel %s, buffer=0x%lx, size=%d, offset=%ld", channel->alias, (intptr_t)buffer, size, offset); /* write data and update position */ switch(channel->source) { case ChannelRegular: retcode = pwrite(channel->handle, sys_buffer, (size_t)size, (off_t)offset); if(retcode == -1) retcode = -errno; break; case ChannelCharacter: case ChannelFIFO: case ChannelSocket: retcode = fwrite(sys_buffer, 1, (size_t)size, (FILE*)channel->socket); if(retcode == -1) retcode = -errno; break; case ChannelTCP: retcode = SendMessage(channel, sys_buffer, size); if(retcode == -1) retcode = -EIO; break; default: /* design error */ ZLOGFAIL(1, EFAULT, "invalid channel source"); break; } /* update the channel counter, size, position and tag */ ++channel->counters[PutsLimit]; if(retcode > 0) { channel->counters[PutSizeLimit] += retcode; UpdateChannelTag(channel, (const char*)sys_buffer, retcode); channel->putpos = offset + retcode; channel->size = channel->type == SGetRPut ? MAX(channel->size, channel->putpos) : channel->putpos; channel->getpos = channel->putpos; } return retcode; }