⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 downloads.cc

📁 基于minigui的浏览器. 这是最新版本.
💻 CC
📖 第 1 页 / 共 2 页
字号:
   }   curr_bytesize = new_sz;   if (curr_bytesize > 1024 * 1024)      snprintf(buf, 64, "%.1fMB", (float)curr_bytesize / (1024*1024));   else      snprintf(buf, 64, "%.0fKB", (float)curr_bytesize / 1024);   prGot->copy_label(buf);   prGot->redraw();   if (total_bytesize == -1) {      prBar->showtext(false);      prBar->move(1);   } else {      prBar->showtext(true);      double pos = 100.0 * (double)curr_bytesize / total_bytesize;      prBar->position(pos);   }}static void read_log_cb(int fd_in, void *data){   DLItem *dl_item = (DLItem *)data;   int BufLen = 4096;   char Buf[BufLen];   ssize_t st;   int ret = -1;   do {      st = read(fd_in, Buf, BufLen);      if (st < 0) {         if (errno == EAGAIN) {            ret = 1;            break;         }         perror("read, ");         break;      } else if (st == 0) {         close(fd_in);         remove_fd(fd_in, 1);         dl_item->log_done(1);         ret = 0;         break;      } else {         dl_item->log_text_add(Buf, st);      }   } while (1);}void DLItem::father_init(){   close(LogPipe[1]);   add_fd(LogPipe[0], 1, read_log_cb, this); // Read   // Start the timer after the child is running.   // (this makes a big difference with wget)   //init_time = time(NULL);}/* * Our wget exited, let's check its status and update the panel. */void DLItem::child_finished(int status){   wget_status(status);   if (status == 0) {      prButton->label("Done");      prButton->tooltip("Close this information panel");   } else {      prButton->label("Close");      prButton->tooltip("Close this information panel");      status_msg("ABORTED");      if (curr_bytesize == 0) {         // Update the title         prTitle->label(shortname);         prTitle->redraw();      }   }   prButton->activate();   prButton->redraw();   MSG("wget status %d\n", status);}/* * Convert seconds into human readable [hour]:[min]:[sec] string. */void secs2timestr(int et, char *str){   int eh, em, es;   eh = et / 3600; em = (et % 3600) / 60; es = et % 60;   if (eh == 0) {      if (em == 0)         snprintf(str, 8, "%ds", es);      else         snprintf(str, 8, "%dm%ds", em, es);   } else {      snprintf(str, 8, "%dh%dm", eh, em);   }}/* * Update Got, Rate, ~Rate and ETA */void DLItem::update(){   struct stat ss;   time_t curr_time;   float csec, tsec, rate, _rate = 0;   char str[64];   int et;   if (updates_done())      return;   /* Update curr_size */   if (stat(fullname, &ss) == -1) {      MSG("stat, %s\n", strerror(errno));      return;   }   update_size((int)ss.st_size);   /* Get current time */   time(&curr_time);   csec = (float) (curr_time - init_time);   /* Rate */   if (csec >= 2) {      tsec = (float) (curr_time - twosec_time);      rate = ((float)(curr_bytesize-twosec_bytesize) / 1024) / tsec;      snprintf(str, 64, (rate < 100) ? "%.1fK/s" : "%.0fK/s", rate);      prRate->copy_label(str);      prRate->redraw();   }   /* ~Rate */   if (csec >= 1) {      _rate = ((float)(curr_bytesize-init_bytesize) / 1024) / csec;      snprintf(str, 64, (_rate < 100) ? "%.1fK/s" : "%.0fK/s", _rate);      pr_Rate->copy_label(str);      pr_Rate->redraw();   }   /* ETA */   if (fork_done()) {      updates_done(1); // Last update      prETAt->label("Time");      prETAt->tooltip("Download Time");      prETAt->redraw();      secs2timestr((int)csec, str);      prETA->copy_label(str);      if (total_bytesize == -1) {         update_prSize(curr_bytesize);         if (wget_status() == 0)            status_msg("Done");      }   } else {      if (_rate > 0 && total_bytesize > 0 && curr_bytesize > 0) {         et = (int)((total_bytesize-curr_bytesize) / (_rate * 1024));         secs2timestr(et, str);         prETA->copy_label(str);      }   }   prETA->redraw();   /* Update one and two secs ago times and bytesizes */   twosec_time = onesec_time;   onesec_time = curr_time;   twosec_bytesize = onesec_bytesize;   onesec_bytesize = curr_bytesize;}// SIGCHLD -------------------------------------------------------------------/*! SIGCHLD handler */void raw_sigchld(int){             caught_sigchld = 1;}/*! Establish SIGCHLD handler */void est_sigchld(void){   struct sigaction sigact;   sigset_t set;   (void) sigemptyset(&set);   sigact.sa_handler = raw_sigchld;   sigact.sa_mask = set;   sigact.sa_flags = SA_NOCLDSTOP;   if (sigaction(SIGCHLD, &sigact, NULL) == -1) {      perror("sigaction");      exit(1);   }}/* * Timeout function to check wget's exit status. */void cleanup_cb(void *data){   DLItemList *list = (DLItemList *)data;   sigprocmask(SIG_BLOCK, &mask_sigchld, NULL);   if (caught_sigchld) {      /* Handle SIGCHLD */      int i, status;      for (i = 0; i < list->num(); ++i) {         if (!list->get(i)->fork_done() &&             waitpid(list->get(i)->pid(), &status, WNOHANG) > 0) {            list->get(i)->child_finished(status);            list->get(i)->fork_done(1);         }      }      caught_sigchld = 0;   }   sigprocmask(SIG_UNBLOCK, &mask_sigchld, NULL);   repeat_timeout(1.0,cleanup_cb,data);}/* * Timeout function to update the widget indicators, * also remove widgets marked "done". */void update_cb(void *data){   static int cb_used = 0;   DLItemList *list = (DLItemList *)data;   /* Update the widgets and remove the ones marked as done */   for (int i = 0; i < list->num(); ++i) {      if (!list->get(i)->widget_done()) {         list->get(i)->update();      } else if (list->get(i)->fork_done()) {         // widget_done and fork_done avoid a race condition.         dl_win->del(i); --i;      }      cb_used = 1;   }   if (cb_used && list->num() == 0)      exit(0);   repeat_timeout(1.0,update_cb,data);}// DLWin ---------------------------------------------------------------------/* * Read a single line from a socket and store it in a GString. */static ssize_t readline(int socket, GString ** msg){   ssize_t st;   gchar buf[16384], *aux;   /* can't use fread() */   do      st = read(socket, buf, 16384);   while (st < 0 && errno == EINTR);   if (st == -1)      MSG("readline, %s\n", strerror(errno));   if (st > 0) {      aux = g_strndup(buf, (guint)st);      g_string_assign(*msg, aux);      g_free(aux);   } else {      g_string_assign(*msg, "");   }   return st;}/* * Make a new name and place it in 'dl_dest'. */static void make_new_name(gchar **dl_dest, const gchar *url){   GString *gstr = g_string_new(*dl_dest);   gint idx = gstr->len;   if (gstr->str[idx - 1] != '/'){      g_string_append_c(gstr, '/');      ++idx;   }   /* Use a mangled url as name */   g_string_append(gstr, url);   for (   ; idx < gstr->len; ++idx)      if (!isalnum(gstr->str[idx]))         gstr->str[idx] = '_';   /* free memory */   g_free(*dl_dest);   *dl_dest = gstr->str;   g_string_free(gstr, FALSE);}/* * Callback function for the request socket. * Read the request, parse and start a new download. */static void read_req_cb(int req_fd, void *){   GString *tag;   struct sockaddr_un clnt_addr;   int new_socket;   socklen_t csz;   struct stat sb;   char *cmd = NULL, *url = NULL, *dl_dest = NULL;   DLAction action = DL_ABORT; /* compiler happiness */   /* Initialize the value-result parameter */   csz = sizeof(struct sockaddr_un);   /* accept the request */   do {      new_socket = accept(req_fd, (struct sockaddr *) &clnt_addr, &csz);   } while (new_socket == -1 && errno == EINTR);   if (new_socket == -1) {      MSG("accept, %s fd=%d\n", strerror(errno), req_fd);      return;   }   //sigprocmask(SIG_BLOCK, &blockSC, NULL);   tag = g_string_new(NULL);   readline(new_socket, &tag);   close(new_socket);   _MSG("Received tag={%s}\n", tag->str);   if ((cmd = a_Dpip_get_attr(tag->str, (size_t)tag->len, "cmd")) == NULL) {      MSG("Failed to parse 'cmd' in %s\n", tag->str);      goto end;   }   if (strcmp(cmd, "DpiBye") == 0) {      MSG("got DpiBye, ignoring...\n");      goto end;   }   if (strcmp(cmd, "download") != 0) {      MSG("unknown command: '%s'. Aborting.\n", cmd);      goto end;   }   if (!(url = a_Dpip_get_attr(tag->str,(size_t)tag->len, "url"))){      MSG("Failed to parse 'url' in %s\n", tag->str);      goto end;   }   if (!(dl_dest = a_Dpip_get_attr(tag->str,(size_t)tag->len,"destination"))){      MSG("Failed to parse 'destination' in %s\n", tag->str);      goto end;   }   /* 'dl_dest' may be a directory */   if (stat(dl_dest, &sb) == 0 && S_ISDIR(sb.st_mode))      make_new_name(&dl_dest, url);   action = dl_win->check_filename(&dl_dest);   if (action != DL_ABORT) {      // Start the whole thing whithin FLTK.      dl_win->add(dl_dest, url, action);   } else if (dl_win->num() == 0) {      exit(0);   }end:   g_free(cmd);   g_free(url);   g_free(dl_dest);   g_string_free(tag, TRUE);}/* * Callback for close window request (WM or EscapeKey press) */static void dlwin_esc_cb(Widget *, void *){   char *msg = "There are running downloads.\n"               "ABORT them and EXIT anyway?";   if (dl_win && dl_win->num_running() > 0) {      int ch = fltk::choice(msg, "Yes", "*No", "Cancel");      if (ch != 0)         return;   }   /* abort each download properly */   dl_win->abort_all();}/* * Add a new download request to the main window and * fork a child to do the job. */void DLWin::add(const char *full_filename, const char *url, DLAction action){   DLItem *dl_item = new DLItem(full_filename, url, action);   mDList->add(dl_item);   //mPG->add(*dl_item->get_widget());   mPG->insert(*dl_item->get_widget(), 0);   _MSG("Child index = %d\n", mPG->find(dl_item->get_widget()));   // Start the child process   pid_t f_pid = fork();   if (f_pid == 0) {      /* child */      dl_item->child_init();      _exit(EXIT_FAILURE);   } else if (f_pid < 0) {      perror("fork, ");      exit(1);   } else {         /* father */      dl_win->show();      dl_item->pid(f_pid);      dl_item->father_init();   }}/* * Decide what to do whe the filename already exists. * (renaming takes place here when necessary) */DLAction DLWin::check_filename(char **p_fullname){   struct stat ss;   char *msg;   int ch;   DLAction ret = DL_ABORT;   if (stat(*p_fullname, &ss) == -1)      return DL_NEWFILE;   msg = g_strdup_printf(            "The file:\n  %s (%d Bytes)\nalready exists. What do we do?",            *p_fullname, (int)ss.st_size);   ch = fltk::choice(msg, "Rename", "Continue", "Abort");   g_free(msg);   MSG("Choice %d\n", ch);   if (ch == 0) {      const char *p;      p = fltk::file_chooser("Enter a new name:", NULL, *p_fullname);      if (p) {         g_free(*p_fullname);         *p_fullname = g_strdup(p);         ret = check_filename(p_fullname);      }   } else if (ch == 1) {      ret = DL_CONTINUE;   }   return ret;}/* * Add a new download request to the main window and * fork a child to do the job. */void DLWin::del(int n_item){   DLItem *dl_item = mDList->get(n_item);   // Remove the widget from the scroll group   mPG->remove(dl_item->get_widget());   // Resize the scroll group   mPG->resize(mWin->w(), 1);   mDList->del(n_item);   delete(dl_item);}/* * Return number of entries */int DLWin::num(){   return mDList->num();}/* * Return number of running downloads */int DLWin::num_running(){   int i, nr;   for (i = nr = 0; i < mDList->num(); ++i)      if (!mDList->get(i)->fork_done())         ++nr;   return nr;}/* * Set a callback function for the request socket */void DLWin::listen(int req_fd){   add_fd(req_fd, 1, read_req_cb, NULL); // Read}/* * Abort each download properly, and let the main cycle exit */void DLWin::abort_all(){   for (int i = 0; i < mDList->num(); ++i)      mDList->get(i)->abort_dl();}/* * Create the main window and an empty list of requests. */DLWin::DLWin(int ww, int wh) {   // Init an empty list for the download requests   mDList = new DLItemList();   // Create the empty main window   mWin = new Window(ww, wh, "Downloads:");   mWin->begin();    mScroll = new ScrollGroup(0,0,ww,wh);    mScroll->begin();     mPG = new PackedGroup(0,0,ww,wh);     mPG->end();     //mPG->spacing(10);    mScroll->end();   mWin->resizable(mWin);   mWin->end();   mWin->callback(dlwin_esc_cb, NULL);   mWin->show();   // Set SIGCHLD handlers   sigemptyset(&mask_sigchld);   sigaddset(&mask_sigchld, SIGCHLD);   est_sigchld();   // Set the cleanup timeout   add_timeout(1.0, cleanup_cb, mDList);   // Set the update timeout   add_timeout(1.0, update_cb, mDList);}// ---------------------------------------------------------------------------//int main(int argc, char **argv)int main(){   int ww = 420, wh = 85;   lock();   // Create the download window   dl_win = new DLWin(ww, wh);   // Start listening to the request socket   dl_win->listen(STDIN_FILENO);   MSG("started...\n");   return run();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -