Exemplo n.º 1
0
void Indexer::index_directory(const unicode &dir_path) {
    /*
     *  Recursively indexes the files in a directory
     */

    for(auto file: kfs::path::list_dir(dir_path.encode())) {
        auto full_path = kfs::path::join(dir_path.encode(), file);

        if(kfs::path::is_dir(full_path)) {
            index_directory(full_path);
        } else {
            index_file(full_path);
        }
    }
}
Exemplo n.º 2
0
int get_cachedir_file(request * req, struct stat *statbuf)
{

    char pathname_with_index[MAX_PATH_LENGTH];
    int data_fd;
    time_t real_dir_mtime;

    real_dir_mtime = statbuf->st_mtime;
    sprintf(pathname_with_index, "%s/dir.%d.%ld",
            cachedir, (int) statbuf->st_dev, statbuf->st_ino);
    data_fd = open(pathname_with_index, O_RDONLY);

    if (data_fd != -1) {        /* index cache */

        fstat(data_fd, statbuf);
        if (statbuf->st_mtime > real_dir_mtime) {
            statbuf->st_mtime = real_dir_mtime; /* lie */
            strcpy(req->request_uri, directory_index); /* for mimetype */
            return data_fd;
        }
        close(data_fd);
        unlink(pathname_with_index); /* cache is stale, delete it */
    }
    if (index_directory(req, pathname_with_index) == -1)
        return -1;

    data_fd = open(pathname_with_index, O_RDONLY); /* Last chance */
    if (data_fd != -1) {
        strcpy(req->request_uri, directory_index); /* for mimetype */
        fstat(data_fd, statbuf);
        statbuf->st_mtime = real_dir_mtime; /* lie */
        return data_fd;
    }

    boa_perror(req, "re-opening dircache");
    return -1;                  /* Nothing worked. */

}
Exemplo n.º 3
0
int get_cachedir_file(request * req, struct stat *statbuf)
{

    char pathname_with_index[MAX_PATH_LENGTH];
    int data_fd;
    time_t real_dir_mtime;

    real_dir_mtime = statbuf->st_mtime;
    sprintf(pathname_with_index, "%s/dir.%d.%ld",
            cachedir, (int) statbuf->st_dev, statbuf->st_ino);
    data_fd = open(pathname_with_index, O_RDONLY);

    if (data_fd != -1) {        

        fstat(data_fd, statbuf);
        if (statbuf->st_mtime > real_dir_mtime) {
            statbuf->st_mtime = real_dir_mtime; 
            strcpy(req->request_uri, directory_index); 
            return data_fd;
        }
        close(data_fd);
        unlink(pathname_with_index); 
    }
    if (index_directory(req, pathname_with_index) == -1)
        return -1;

    data_fd = open(pathname_with_index, O_RDONLY); 
    if (data_fd != -1) {
        strcpy(req->request_uri, directory_index); 
        fstat(data_fd, statbuf);
        statbuf->st_mtime = real_dir_mtime; 
        return data_fd;
    }

    boa_perror(req, "re-opening dircache");
    return -1;                  

}
Exemplo n.º 4
0
Arquivo: get.c Projeto: gpg/boa
int process_get(request * req)
{
    off_t bytes_written;
    volatile off_t bytes_to_write;

    if (req->method == M_HEAD) {
        return complete_response(req);
    }

    bytes_to_write = (req->ranges->stop - req->ranges->start) + 1;

    if (bytes_to_write > system_bufsize)
        bytes_to_write = system_bufsize;

    if (setjmp(env) == 0) {
        handle_sigbus = 1;
        bytes_written = write(req->fd, req->data_mem + req->ranges->start,
                              bytes_to_write);
        handle_sigbus = 0;
        /* OK, SIGBUS **after** this point is very bad! */
    } else {
        /* sigbus! */
        req->status = DEAD;
        log_error_doc(req);
        fprintf(stderr, "%sGot SIGBUS in write(2)!\n",
                get_commonlog_time());
        /* sending an error here is inappropriate
         * if we are here, the file is mmapped, and thus,
         * a content-length has been sent. If we send fewer bytes
         * the client knows there has been a problem.
         * We run the risk of accidentally sending the right number
         * of bytes (or a few too many) and the client
         * won't be the wiser.
         */
        return 0;
    }

    if (bytes_written < 0) {
        if (errno == EWOULDBLOCK || errno == EAGAIN)
            return -1;
        /* request blocked at the pipe level, but keep going */
        else {
#ifdef QUIET_DISCONNECT
            if (errno != EPIPE) {
#else
            if (1) {
#endif
                log_error_doc(req);
                /* Can generate lots of log entries, */
                perror("write");
                /* OK to disable if your logs get too big */
            }
            req->status = DEAD;
            return 0;
        }
    }

    req->bytes_written += bytes_written;
    req->ranges->start += bytes_written;

    if ((req->ranges->stop + 1 - req->ranges->start) == 0) {
        return complete_response(req);
    }

    return 1;               /* more to do */
}

/*
 * Name: get_dir
 * Description: Called from process_get if the request is a directory.
 * statbuf must describe directory on input, since we may need its
 *   device, inode, and mtime.
 * statbuf is updated, since we may need to check mtimes of a cache.
 * returns:
 *  -1 error
 *  0  cgi (either gunzip or auto-generated)
 *  >0  file descriptor of file
 */

int get_dir(request * req, struct stat *statbuf)
{

    char pathname_with_index[MAX_PATH_LENGTH];
    int data_fd;

    if (directory_index) {      /* look for index.html first?? */
        unsigned int l1, l2;

        l1 = strlen(req->pathname);
        l2 = strlen(directory_index);
#ifdef GUNZIP
        if (l1 + l2 + 3 + 1 > sizeof(pathname_with_index)) { /* for .gz */
#else
        if (l1 + l2 + 1 > sizeof(pathname_with_index)) {
#endif

            errno = ENOMEM;
            boa_perror(req, "pathname_with_index not large enough for pathname + index");
            return -1;
        }
        memcpy(pathname_with_index, req->pathname, l1); /* doesn't copy NUL */
        memcpy(pathname_with_index + l1, directory_index, l2 + 1); /* does */

        data_fd = open(pathname_with_index, O_RDONLY|O_LARGEFILE);

        if (data_fd != -1) {    /* user's index file */
            /* We have to assume that directory_index will fit, because
             * if it doesn't, well, that's a huge configuration problem.
             * this is only the 'index.html' pathname for mime type
             */
            memcpy(req->request_uri, directory_index, l2 + 1); /* for mimetype */
            fstat(data_fd, statbuf);
            return data_fd;
        }
        if (errno == EACCES) {
            send_r_forbidden(req);
            return -1;
        } else if (errno != ENOENT) {
            /* if there is an error *other* than EACCES or ENOENT */
            send_r_not_found(req);
            return -1;
        }
#ifdef GUNZIP
        /* if we are here, trying index.html didn't work
         * try index.html.gz
         */
        strcat(pathname_with_index, ".gz");
        data_fd = open(pathname_with_index, O_RDONLY|O_LARGEFILE);
        if (data_fd != -1) {    /* user's index file */
            close(data_fd);

            req->response_status = R_REQUEST_OK;
            SQUASH_KA(req);
            if (req->pathname)
                free(req->pathname);
            req->pathname = strdup(pathname_with_index);
            if (!req->pathname) {
                boa_perror(req, "strdup of pathname_with_index for .gz files " __FILE__ ":" STR(__LINE__));
                return 0;
            }
            if (req->http_version != HTTP09) {
                req_write(req, http_ver_string(req->http_version));
                req_write(req, " 200 OK-GUNZIP" CRLF);
                print_http_headers(req);
                print_last_modified(req);
                req_write(req, "Content-Type: ");
                req_write(req, get_mime_type(directory_index));
                req_write(req, CRLF CRLF);
                req_flush(req);
            }
            if (req->method == M_HEAD)
                return 0;
            return init_cgi(req);
        }
#endif
    }

    /* only here if index.html, index.html.gz don't exist */
    if (dirmaker != NULL) {     /* don't look for index.html... maybe automake? */
        req->response_status = R_REQUEST_OK;
        SQUASH_KA(req);

        /* the indexer should take care of all headers */
        if (req->http_version != HTTP09) {
            req_write(req, http_ver_string(req->http_version));
            req_write(req, " 200 OK" CRLF);
            print_http_headers(req);
            print_last_modified(req);
            req_write(req, "Content-Type: text/html" CRLF CRLF);
            req_flush(req);
        }
        if (req->method == M_HEAD)
            return 0;

        return init_cgi(req);
        /* in this case, 0 means success */
    } else if (cachedir) {
        return get_cachedir_file(req, statbuf);
    } else {                    /* neither index.html nor autogenerate are allowed */
        send_r_forbidden(req);
        return -1;              /* nothing worked */
    }
}

static int get_cachedir_file(request * req, struct stat *statbuf)
{

    char pathname_with_index[MAX_PATH_LENGTH];
    int data_fd;
    time_t real_dir_mtime;

    real_dir_mtime = statbuf->st_mtime;
    /* the sizeof() doesn't need a -1 because snprintf will
     * include the NUL when calculating if the size is enough
     */
    snprintf(pathname_with_index, sizeof(pathname_with_index),
             "%s/dir.%d." PRINTF_OFF_T_ARG, cachedir,
             (int) statbuf->st_dev, statbuf->st_ino);
    data_fd = open(pathname_with_index, O_RDONLY|O_LARGEFILE);

    if (data_fd != -1) {        /* index cache */

        fstat(data_fd, statbuf);
        if (statbuf->st_mtime > real_dir_mtime) {
            statbuf->st_mtime = real_dir_mtime; /* lie */
            strcpy(req->request_uri, directory_index); /* for mimetype */
            return data_fd;
        }
        close(data_fd);
        unlink(pathname_with_index); /* cache is stale, delete it */
    }
    if (index_directory(req, pathname_with_index) == -1)
        return -1;

    data_fd = open(pathname_with_index, O_RDONLY|O_LARGEFILE); /* Last chance */
    if (data_fd != -1) {
        strcpy(req->request_uri, directory_index); /* for mimetype */
        fstat(data_fd, statbuf);
        statbuf->st_mtime = real_dir_mtime; /* lie */
        return data_fd;
    }

    boa_perror(req, "re-opening dircache");
    return -1;                  /* Nothing worked. */

}
Exemplo n.º 5
0
void send_file(per_request *reqInfo, struct stat *fi, char allow_options) 
{
    FILE *f;
#ifdef BLACKOUT_CODE
    int isblack = FALSE;
#endif /* BLACKOUT_CODE */    

    if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
	sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
	die(reqInfo,SC_NOT_IMPLEMENTED,error_msg);
    }
    set_content_type(reqInfo,reqInfo->filename);

    if((allow_options & OPT_INCLUDES) && (!reqInfo->outh_content_encoding[0])) {
#ifdef XBITHACK
        if((fi->st_mode & S_IXUSR) ||
           (!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE))) {
#else
	if(!strcmp(reqInfo->outh_content_type,INCLUDES_MAGIC_TYPE)) {
#endif /* XBITHACK */
	    reqInfo->bytes_sent = 0;
	    send_parsed_file(reqInfo, allow_options & OPT_INCNOEXEC);
	    log_transaction(reqInfo);
	    return;
	}
    }
    if (reqInfo->path_info[0]) {
	strcat(reqInfo->filename,reqInfo->path_info);
	strcat(reqInfo->url,reqInfo->path_info);
	sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
	log_reason(reqInfo, error_msg, reqInfo->filename);
	die(reqInfo,SC_NOT_FOUND,reqInfo->url);
    }
	
    if(!(f=FOpen(reqInfo->filename,"r"))) {
      if (errno == EACCES) {
	log_reason(reqInfo,"(1) file permissions deny server access",
		   reqInfo->filename);
	/* we've already established that it exists */
	die(reqInfo,SC_FORBIDDEN,reqInfo->url); 
      } else {
	/* We know an error occured, of an unexpected variety. 
	 * This could be due to no more file descriptors.  We have this
	 * child exit after this stage so that errors of state are 
	 * swept under the carpet.
	 */
	standalone = 0;
	sprintf(error_msg,"File Open error, errno=%d",errno);
	log_reason(reqInfo,error_msg,reqInfo->filename);
	die(reqInfo,SC_SERVER_ERROR,error_msg);
      }
    }
    reqInfo->bytes_sent = 0;

#ifdef BLACKOUT_CODE
    if (!strcmp(reqInfo->outh_content_type,BLACKOUT_MAGIC_TYPE)) {
      isblack = TRUE;
      strcpy(reqInfo->outh_content_type,"text/html");
    }
#endif /* BLACKOUT_CODE */

    if(reqInfo->http_version != P_HTTP_0_9) {
      /* No length dependent headers since black is parsed */
#ifdef BLACKOUT_CODE
      if (isblack == FALSE) { 
#endif /* BLACKOUT_CODE */
#ifdef CONTENT_MD5
	reqInfo->outh_content_md5 = (unsigned char *)md5digest(f);
#endif /* CONTENT_MD5 */
	set_content_length(reqInfo,fi->st_size);
	if (set_last_modified(reqInfo,fi->st_mtime)) {
	    FClose(f);
	    return;
	}
      }
      if (reqInfo->http_version != P_HTTP_0_9) {
           send_http_header(reqInfo);
      }
#ifdef BLACKOUT_CODE
    }
#endif /* BLACKOUT_CODE */

    if(reqInfo->method != M_HEAD) {
#ifdef BLACKOUT_CODE
      if (isblack == TRUE)
	send_fp_black(reqInfo,f,NULL);
       else
#endif /* BLACKOUT_CODE */
	send_fp(reqInfo,f,NULL);
    }
    log_transaction(reqInfo);
    FClose(f);
}


void send_dir(per_request *reqInfo,struct stat *finfo, char allow_options) {
  char *name_ptr, *end_ptr;
  char *ifile, *temp_name;

  ifile = newString(HUGE_STRING_LEN,STR_TMP);
  temp_name = newString(HUGE_STRING_LEN,STR_TMP);

/* Path Alias (pa) array should now have the trailing slash */
  /*  if (pa[0] != '/') { */
  if ((reqInfo->filename[strlen(reqInfo->filename) - 1] != '/') && 
      (reqInfo->path_info[0] != '/')) {
    strcpy_dir(ifile,reqInfo->url);
    construct_url(temp_name,reqInfo->hostInfo,ifile);
    escape_url(temp_name);
    die(reqInfo,SC_REDIRECT_PERM,temp_name);
  }

  /* Don't allow PATH_INFO to directory indexes as a compromise for 
     error messages for files which don't exist */

  if ((reqInfo->path_info[0] != '\0') || (strlen(reqInfo->path_info) > 1)) {
        strcat(reqInfo->filename,reqInfo->path_info);
        strcat(reqInfo->url,reqInfo->path_info);
        sprintf(error_msg,"No file matching URL: %s",reqInfo->url);
        log_reason(reqInfo, error_msg, reqInfo->filename);
	freeString(temp_name);
	freeString(ifile);
        die(reqInfo,SC_NOT_FOUND,reqInfo->url);
  }
    
  strncpy(temp_name, reqInfo->hostInfo->index_names, HUGE_STRING_LEN-1);
  end_ptr = name_ptr = temp_name;

  while (*name_ptr) {
    
    while (*name_ptr && isspace (*name_ptr)) ++name_ptr;
    end_ptr = name_ptr;
    if (strchr(end_ptr, ' ') ) {
      end_ptr = strchr(name_ptr, ' ');
      *end_ptr = '\0';
      end_ptr++;
    } else
      end_ptr += strlen(end_ptr);
    make_full_path(reqInfo->filename,name_ptr,ifile);
    if(stat(ifile,finfo) == -1) {
      if(! *end_ptr && (allow_options & OPT_INDEXES)) {
        if (reqInfo->path_info[0]) {
          strcat(reqInfo->filename,reqInfo->path_info);
	  strcat(reqInfo->url,reqInfo->path_info);
	  log_reason(reqInfo,"file does not exist",reqInfo->filename);
	  freeString(ifile);
	  freeString(temp_name);
	  die(reqInfo,SC_NOT_FOUND,reqInfo->url);
	}
	if ((reqInfo->method != M_GET) && (reqInfo->method != M_HEAD)) {
	  sprintf(error_msg,"%s to non-script",methods[reqInfo->method]);
	  freeString(ifile);
	  freeString(temp_name);
	  die(reqInfo,SC_NOT_IMPLEMENTED,error_msg);
	}	
	index_directory(reqInfo);
	freeString(ifile);
	freeString(temp_name);
	return;
      } else if (! *end_ptr) {
	log_reason(reqInfo,"(2) file permissions deny server access",
		   reqInfo->filename);
	freeString(ifile);
	freeString(temp_name);
	die(reqInfo,SC_FORBIDDEN,reqInfo->url);
      }
    } else {
      strcpy(reqInfo->filename,ifile);
      probe_content_type(reqInfo,reqInfo->filename);
      if(!strcmp(reqInfo->outh_content_type,CGI_MAGIC_TYPE))
	send_cgi(reqInfo,finfo,allow_options);
      else
	send_file(reqInfo,finfo,allow_options);
      freeString(ifile);
      freeString(temp_name);
      return;
    }
    name_ptr = end_ptr;
  }	 
}