void httpGetAbsolutePath(HttpConnection *connection, const char_t *relative, char_t *absolute, size_t maxLen) { //Copy the root directory strcpy(absolute, connection->settings->rootDirectory); //Append the specified path pathCombine(absolute, relative, maxLen); //Clean the resulting path pathCanonicalize(absolute); }
/* * Like JSEnumerateOp, but enum provides contextual information as follows: * * JSENUMERATE_INIT: allocate private enum struct in state_p, return number * of elements in *id_p * JSENUMERATE_NEXT: return next property id in *id_p, and if no new property * free state_p and set to JSVAL_NULL * JSENUMERATE_DESTROY : destroy state_p * * Note that in a for ... in loop, this will be called first on the object, * then on its prototype. * */ static JSBool importer_new_enumerate(JSContext *context, JS::HandleObject object, JSIterateOp enum_op, JS::MutableHandleValue statep, JS::MutableHandleId idp) { ImporterIterator *iter; switch (enum_op) { case JSENUMERATE_INIT_ALL: case JSENUMERATE_INIT: { Importer *priv; JSObject *search_path; jsval search_path_val; uint32_t search_path_len; uint32_t i; jsid search_path_name; statep.set(JSVAL_NULL); idp.set(INT_TO_JSID(0)); priv = priv_from_js(context, object); if (!priv) /* we are enumerating the prototype properties */ return JS_TRUE; search_path_name = gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH); if (!gjs_object_require_property(context, object, "importer", search_path_name, &search_path_val)) return JS_FALSE; if (!search_path_val.isObject()) { gjs_throw(context, "searchPath property on importer is not an object"); return JS_FALSE; } search_path = JSVAL_TO_OBJECT(search_path_val); if (!JS_IsArrayObject(context, search_path)) { gjs_throw(context, "searchPath property on importer is not an array"); return JS_FALSE; } if (!JS_GetArrayLength(context, search_path, &search_path_len)) { gjs_throw(context, "searchPath array has no length"); return JS_FALSE; } iter = importer_iterator_new(); for (i = 0; i < search_path_len; ++i) { std::string dirname; std::string init_path; const char *filename; jsval elem; std::vector<std::string> dir; elem = JSVAL_VOID; if (!JS_GetElement(context, search_path, i, &elem)) { /* this means there was an exception, while elem == JSVAL_VOID * means no element found */ importer_iterator_free(iter); return JS_FALSE; } if (JSVAL_IS_VOID(elem)) continue; if (!JSVAL_IS_STRING(elem)) { gjs_throw(context, "importer searchPath contains non-string"); importer_iterator_free(iter); return JS_FALSE; } if (!gjs_string_to_utf8(context, elem, dirname)) { importer_iterator_free(iter); return JS_FALSE; /* Error message already set */ } init_path = pathCombine(dirname, MODULE_INIT_FILENAME); load_module_elements(context, object, iter, init_path); dir = enumerateFilesInDirectory(dirname); if (dir.size() == 0) { continue; } for(auto filename : dir) { std::string full_path; /* skip hidden files and directories (.svn, .git, ...) */ if (filename[0] == '.') continue; /* skip module init file */ if (filename == MODULE_INIT_FILENAME) continue; full_path = pathCombine(dirname, filename); if (is_directory(full_path)) { iter->elements.push_back(filename); } else { if (filename.rfind(MODULE_SUFFIX) != std::string::npos || filename.rfind(JS_SUFFIX) != std::string::npos) { iter->elements.push_back(filename.substr(0, filename.size()-3)); } } } } statep.set(PRIVATE_TO_JSVAL(iter)); idp.set(INT_TO_JSID(iter->elements.size())); break; } case JSENUMERATE_NEXT: { jsval element_val; if (JSVAL_IS_NULL(statep)) /* Iterating prototype */ return JS_TRUE; iter = (ImporterIterator*) JSVAL_TO_PRIVATE(statep); if (iter->index < iter->elements.size()) { if (!gjs_string_from_utf8(context, iter->elements.at(iter->index++), &element_val)) return JS_FALSE; jsid id; if (!JS_ValueToId(context, element_val, &id)) return JS_FALSE; idp.set(id); break; } /* else fall through to destroying the iterator */ } case JSENUMERATE_DESTROY: { if (!JSVAL_IS_NULL(statep)) { iter = (ImporterIterator*) JSVAL_TO_PRIVATE(statep); importer_iterator_free(iter); statep.set(JSVAL_NULL); } } } return JS_TRUE; }
static JSBool do_import(JSContext *context, JSObject *obj, Importer *priv, std::string &name) { std::string filename; std::string full_path; std::string dirname; jsval search_path_val; JSObject *search_path; JSObject *module_obj = NULL; uint32_t search_path_len; uint32_t i; JSBool result; std::vector<std::string> directories; jsid search_path_name; bool exists; search_path_name = gjs_context_get_const_string(context, GJS_STRING_SEARCH_PATH); if (!gjs_object_require_property(context, obj, "importer", search_path_name, &search_path_val)) { return JS_FALSE; } if (!search_path_val.isObject()) { gjs_throw(context, "searchPath property on importer is not an object"); return JS_FALSE; } search_path = JSVAL_TO_OBJECT(search_path_val); if (!JS_IsArrayObject(context, search_path)) { gjs_throw(context, "searchPath property on importer is not an array"); return JS_FALSE; } if (!JS_GetArrayLength(context, search_path, &search_path_len)) { gjs_throw(context, "searchPath array has no length"); return JS_FALSE; } result = JS_FALSE; filename = std::string(name) + ".js"; /* First try importing an internal module like byteArray */ if (priv->is_root && gjs_is_registered_native_module(context, obj, name) && import_native_file(context, obj, name)) { gjs_debug(GJS_DEBUG_IMPORTER, "successfully imported module '%s'", name); result = JS_TRUE; goto out; } for (i = 0; i < search_path_len; ++i) { jsval elem; elem = JSVAL_VOID; if (!JS_GetElement(context, search_path, i, &elem)) { /* this means there was an exception, while elem == JSVAL_VOID * means no element found */ goto out; } if (JSVAL_IS_VOID(elem)) continue; if (!JSVAL_IS_STRING(elem)) { gjs_throw(context, "importer searchPath contains non-string"); goto out; } if (!gjs_string_to_utf8(context, elem, dirname)) goto out; /* Error message already set */ /* Ignore empty path elements */ if (dirname[0] == '\0') continue; /* Try importing __init__.js and loading the symbol from it */ full_path = pathCombine(dirname, MODULE_INIT_FILENAME); module_obj = load_module_init(context, obj, full_path); if (module_obj != NULL) { jsval obj_val; if (JS_GetProperty(context, module_obj, name.c_str(), &obj_val)) { if (!JSVAL_IS_VOID(obj_val) && JS_DefineProperty(context, obj, name.c_str(), obj_val, NULL, NULL, GJS_MODULE_PROP_FLAGS & ~JSPROP_PERMANENT)) { result = JS_TRUE; goto out; } } } /* Second try importing a directory (a sub-importer) */ full_path = pathCombine(dirname, name); if (is_directory(full_path)) { std::cout << "Adding directory '" << full_path << "' to child importer '" << name << "'\n", directories.push_back(full_path); } /* If we just added to directories, we know we don't need to * check for a file. If we added to directories on an earlier * iteration, we want to ignore any files later in the * path. So, always skip the rest of the loop block if we have * directories. */ if (directories.size() > 0) { continue; } /* Third, if it's not a directory, try importing a file */ full_path = pathCombine(dirname, filename); std::cout << "full path: " << full_path << "\n"; exists = is_regular(full_path); if (!exists) { std::cout << "JS import '" << name << "' not found in " << dirname << "\n"; continue; } if (import_file_on_module (context, obj, name, full_path)) { std::cout << "successfully imported module '" << name << "'\n"; result = JS_TRUE; } /* Don't keep searching path if we fail to load the file for * reasons other than it doesn't exist... i.e. broken files * block searching for nonbroken ones */ goto out; } if (directories.size() > 0) { /* NULL-terminate the char** */ if (import_directory(context, obj, name, directories)) { std::cout << "successfully imported directory '" << name << "'\n"; result = JS_TRUE; } } out: if (!result && !JS_IsExceptionPending(context)) { /* If no exception occurred, the problem is just that we got to the * end of the path. Be sure an exception is set. */ gjs_throw(context, "No JS module '%s' found in search path", name.c_str()); } return result; }
void ftpServerSendData(FtpServerContext *context, FtpClientConnection *connection) { error_t error; size_t n; //Any data waiting for transmission? if(connection->bufferLength > 0) { //Send more data error = socketSend(connection->dataSocket, connection->buffer + connection->bufferPos, connection->bufferLength, &n, 0); //Failed to send data? if(error != NO_ERROR && error != ERROR_TIMEOUT) { //Close the data connection ftpServerCloseDataConnection(connection); //Release previously allocated resources if(connection->file != NULL) { fsCloseFile(connection->file); connection->file = NULL; } if(connection->dir != NULL) { fsCloseDir(connection->dir); connection->dir = NULL; } //Back to idle state connection->controlState = FTP_CONTROL_STATE_IDLE; //Transfer status strcpy(connection->response, "451 Transfer aborted\r\n"); //Debug message TRACE_DEBUG("FTP server: %s", connection->response); //Number of bytes in the response buffer connection->responseLength = strlen(connection->response); connection->responsePos = 0; //Exit immediately return; } //Advance data pointer connection->bufferPos += n; //Number of bytes still available in the buffer connection->bufferLength -= n; } //Empty transmission buffer? if(connection->bufferLength == 0) { //File transfer in progress? if(connection->controlState == FTP_CONTROL_STATE_RETR) { //Read more data error = fsReadFile(connection->file, connection->buffer, FTP_SERVER_BUFFER_SIZE, &n); //End of stream? if(error) { //Close file fsCloseFile(connection->file); connection->file = NULL; //Wait for all the data to be transmitted and acknowledged connection->dataState = FTP_DATA_STATE_WAIT_ACK; //Exit immediately return; } } //Directory listing in progress? else if(connection->controlState == FTP_CONTROL_STATE_LIST) { uint_t perm; time_t currentTime; time_t modified; char_t *path; FsDirEntry dirEntry; //Read a new entry in the directory error = fsReadDir(connection->dir, &dirEntry); //End of stream? if(error) { //Close directory fsCloseDir(connection->dir); connection->dir = NULL; //Wait for all the data to be transmitted and acknowledged connection->dataState = FTP_DATA_STATE_WAIT_ACK; //Exit immediately return; } //Point to the scratch buffer path = connection->buffer; //Get the pathname of the directory being listed strcpy(path, connection->path); //Retrieve the full pathname pathCombine(path, dirEntry.name, FTP_SERVER_MAX_PATH_LEN); pathCanonicalize(path); //Get permissions for the specified file perm = ftpServerGetFilePermissions(context, connection, path); //Enforce access rights if(perm & FTP_FILE_PERM_LIST) { //Format links, owner, group and size fields n = sprintf(connection->buffer, "---------- 1 owner group %10" PRIu32, dirEntry.size); //Check whether the current entry is a directory if(dirEntry.attributes & FS_FILE_ATTR_DIRECTORY) connection->buffer[0] = 'd'; //Read access? if(perm & FTP_FILE_PERM_READ) { connection->buffer[1] = 'r'; connection->buffer[4] = 'r'; connection->buffer[7] = 'r'; } //Write access if(perm & FTP_FILE_PERM_WRITE) { connection->buffer[2] = 'w'; connection->buffer[5] = 'w'; connection->buffer[8] = 'w'; } //Get current time currentTime = getCurrentUnixTime(); //Get modification time modified = convertDateToUnixTime(&dirEntry.modified); //Check whether the modification time is within the previous 180 days if(currentTime > modified && currentTime < (modified + FTP_SERVER_180_DAYS)) { //The format of the date/time field is Mmm dd hh:mm n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %02" PRIu8 ":%02" PRIu8, months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day, dirEntry.modified.hours, dirEntry.modified.minutes); } else { //The format of the date/time field is Mmm dd yyyy n += sprintf(connection->buffer + n, " %s %02" PRIu8 " %04" PRIu16, months[MIN(dirEntry.modified.month, 12)], dirEntry.modified.day, dirEntry.modified.year); } //Append filename n += sprintf(connection->buffer + n, " %s\r\n", dirEntry.name); //Debug message TRACE_DEBUG("FTP server: %s", connection->buffer); } else { //Insufficient access rights n = 0; } } //Invalid state? else { //The FTP server has encountered a critical error ftpServerCloseConnection(context, connection); //Exit immediately return; } //Number of bytes in the buffer connection->bufferPos = 0; connection->bufferLength = n; } }
int listdir(const char *path, int uid, int mtm, int vol, int count) { struct dirent *entry; DIR *dp; char actualpath [PATH_MAX+1]; realpath(path, actualpath); dp = opendir(actualpath); if (dp == NULL) { // perror("opendir"); return -1; } char newpath [PATH_MAX+1]; char linkres [PATH_MAX+1]; struct stat sb; struct passwd * userInfo; struct group * grpInfo; struct tm * tmInfo; char * tmStr; while((entry = readdir(dp))) { newpath[0] = '\0'; linkres[0] ='\0'; char * name = entry->d_name; pathCombine(actualpath,name,newpath); lstat(newpath,&sb); time_t now = time(0); int A = (mtm == 0); int B = (now - sb.st_mtime) > abs(mtm); int C = (mtm > 0); // Modify Time logic is A + !(B xor C) if (!(strcmp(name,"..") == 0) && !(strcmp(name,".") == 0) && ((sb.st_uid == uid) || (uid == -1)) && (A || (B == C))) { printf("%lld/%lld %d ",sb.st_dev,sb.st_ino,sb.st_nlink); statPerms(sb); printf(" "); userInfo = getpwuid(sb.st_uid); if (userInfo) { printf(userInfo->pw_name); printf(" "); } else { printf("%d ",sb.st_uid); } grpInfo = getgrgid(sb.st_gid); printf(grpInfo->gr_name); if ((sb.st_mode & S_IFBLK) || (sb.st_mode & S_IFCHR)) { printf(" BLK/CHR "); // print raw device number } else { printf(" %d ",sb.st_size); } tmInfo = localtime(&sb.st_mtime); tmStr = asctime(tmInfo); tmStr[24] = 0; printf(tmStr); printf(" "); printf(newpath); if (S_ISLNK(sb.st_mode)) { printf(" -> "); readlink(newpath,linkres,PATH_MAX+1); char * respath = realpath(linkres,NULL); printf(respath); } printf("\n"); } if (entry->d_type == DT_DIR && !(strcmp(name,"..") == 0) && !(strcmp(name,".") == 0) ) { count++; if (count == 1024) { printf("Maximum depth reached"); return -1; } if ((inodeConflict(sb.st_ino, newpath, inode_list, inode_list_count) == 0) && ((vol == 0) || (vol == sb.st_dev))) { listdir(newpath,uid,mtm,vol,count); inode_list_count++; } else if (vol != sb.st_dev) { printf("Not crossing mount point at"); printf(actualpath); printf("\n"); } else { printf("Hit conflict: "); printf(newpath); printf(", "); printf(dir_list[inode_list_count-1]); printf("\n"); } } } closedir(dp); return 0; }