Exemple #1
0
/*
 * Validate file access. Since we have no uid or gid, for now require
 * file to exist and be publicly readable/writable.
 * If we were invoked with arguments from inetd then the file must also
 * be in one of the given directory prefixes. Note also, full path name
 * must be given as we have no login directory.
 */
int validate_access( Client *cl, char *file ) {
	struct stat stbuf;

	/*
	 * Prevent tricksters from getting around the directory restrictions
	 */
	if (strstr(file, "/../")) {
		errstr = "\"..\" in path";
		return (EACCESS);
	}
	if (strstr(file, "../")) {
		errstr = "..\" in path";
		return (EACCESS);
	}
	if (stat(file, &stbuf) < 0) {
		if (errno == ENOENT) {
			if (read_dynamic_file( cl->sin.sin_addr.s_addr,
				(u_int32_t *) &(cl->fnum), (u_int32_t *) &(cl->maxb) )) {
				errno = 0;
				cl->dynam = 1;
				return 0;
			}
		}
		errstr = strerror(errno);
		return (errno == ENOENT ? ENOTFOUND : EACCESS);
	}
	if ((stbuf.st_mode & S_IFMT) != S_IFREG) {
		errstr = "not a regular file";
		return (ENOTFOUND);
	}
	if ((stbuf.st_mode & S_IROTH) == 0) {
		errstr = "not readable";
		return (EACCESS);
	}
	if ( read_static_file( file, (u_int32_t *) &(cl->fnum), (u_int32_t *) &(cl->maxb) ) != 0 ) {
		return( EACCESS );
	}
	return 0;
}
Exemple #2
0
int main(int argc, char* argv[]) {
  // Parse any command-line options.
  namespace po = boost::program_options;
  po::options_description desc("Allowed options");
  desc.add_options()
    ("help", "show help")
    ("debug-httpd", po::value<bool>(&mp3d_debug_httpd), "show httpd debug output")
    ("root", po::value<std::string>(&mp3d_music_root), "root of file system mp3 tree")
    ("port", po::value<int>(&mp3d_port), "httpd port number")
  ;
  po::variables_map args;
  po::store(po::parse_command_line(argc, argv, desc), args);
  po::notify(args);
  if (args.count("help")) {
    std::cout << desc << std::endl;
    return 1;
  }

  // Index all the mp3s.
  Paths paths;
  find_mp3_files(mp3d_music_root, paths);
  std::cerr << ".mp3 files found: " << paths.size() << std::endl;

  int old_percentage = -1;
  size_t id = 0;
  for (Paths::const_iterator it = paths.begin(); it != paths.end(); ++it) {
    Mp3Info mp3;
    mp3.filename = (*it).string();

    const ID3_Tag tag(mp3.filename.c_str());

    ID3_Tag::ConstIterator* it = tag.CreateIterator();
    for (size_t i = 0; i < tag.NumFrames(); ++i) {
      const ID3_Frame* frame = it->GetNext();
      if (frame != 0) {
        std::string* dst;
        switch (frame->GetID()) {
        case ID3FID_ALBUM: dst = &mp3.album; break;
        case ID3FID_LEADARTIST: dst = &mp3.artist; break;
        case ID3FID_TITLE: dst = &mp3.title; break;
        default: continue;
        }
        char* text = ID3_GetString(frame, ID3FN_TEXT);
        dst->assign(text);
        ID3_FreeString(text);
      }
    }
    
    // FIXME: maybe a hash, to enable bookmarks?
    mp3.id = id++;
    
    all_mp3s.push_back(mp3);
    
    // Show progress. Not really useful when we're not debugging.
    // FIXME: start the web server straight away, and say "Indexing..." there.
    const int new_percentage = (100*all_mp3s.size())/paths.size();
    if (new_percentage != old_percentage) {
      std::cout << "\rScanned: " << new_percentage << "%" << std::flush;
      old_percentage = new_percentage;
    }
  }
  std::cout << "\r.mp3 files scanned: " << all_mp3s.size() << std::endl;

  // Set up the static files we need to serve.
  read_static_file("/static/add.png",
                   "/usr/share/icons/gnome/16x16/actions/gtk-add.png");
  read_static_file("/static/play.png",
                   "/usr/share/icons/gnome/16x16/actions/gtk-media-play-ltr.png");
  read_static_file("/static/remove.png",
                   "/usr/share/icons/gnome/16x16/actions/gtk-remove.png");
  static_file_map["/static/site.css"] = make_css();
  
  // Start the mp3 player thread.
  boost::thread mp3_player_thread(mp3_play_loop);
  
  // Start the HTTP server.
  std::cerr << "Starting HTTP server on port " << mp3d_port << "..." << std::endl;
  const int mhd_flags = MHD_USE_SELECT_INTERNALLY;
  MHD_Daemon* daemon = MHD_start_daemon(mhd_flags, mp3d_port, 0, 0, &handle_request, 0, MHD_OPTION_END);
  if (daemon == 0) {
    fail("MHD_start_daemon failed!");
  }
  
  getchar(); // Wait for the user to hit enter.
  
  MHD_stop_daemon(daemon);
  //mp3_player_thread.join();
  return 0;
}