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);
}
Beispiel #2
0
/*
 * 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;
}
Beispiel #3
0
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;
   }
}
Beispiel #5
0
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;
}