"Fossies" - the Fresh Open Source Software Archive

Member "links-1.03/main.c" (23 Nov 2011, 9172 Bytes) of archive /linux/www/links-1.03.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "main.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8_vs_1.03.

    1 #include "links.h"
    2 
    3 int retval = RET_OK;
    4 
    5 void unhandle_basic_signals(struct terminal *);
    6 
    7 void sig_terminate(struct terminal *t)
    8 {
    9     unhandle_basic_signals(t);
   10     terminate = 1;
   11     retval = RET_SIGNAL;
   12 }
   13 
   14 void sig_intr(struct terminal *t)
   15 {
   16     if (!t) {
   17         unhandle_basic_signals(t);
   18         terminate = 1;
   19     } else {
   20         unhandle_basic_signals(t);
   21         exit_prog(t, NULL, NULL);
   22     }
   23 }
   24 
   25 void sig_ctrl_c(struct terminal *t)
   26 {
   27     if (!is_blocked()) kbd_ctrl_c();
   28 }
   29 
   30 void sig_ign(void *x)
   31 {
   32 }
   33 
   34 int fg_poll_timer = -1;
   35 void poll_fg(void *t);
   36 
   37 void sig_tstp(struct terminal *t)
   38 {
   39 #if defined(SIGSTOP) && !defined(NO_CTRL_Z)
   40 #if defined(SIGCONT) && defined(SIGTTOU) && defined(HAVE_GETPID)
   41     pid_t pid = getpid();
   42     pid_t newpid;
   43 #endif
   44     block_itrm(1);
   45 #if defined(SIGCONT) && defined(SIGTTOU)
   46     if (!(newpid = fork())) {
   47         while (1) {
   48             sleep(1);
   49             kill(pid, SIGCONT);
   50         }
   51     }
   52 #endif
   53     raise(SIGSTOP);
   54 #if defined(SIGCONT) && defined(SIGTTOU)
   55     if (newpid != -1) kill(newpid, SIGKILL);
   56 #endif
   57 #endif
   58     if (fg_poll_timer != -1) kill_timer(fg_poll_timer);
   59     fg_poll_timer = install_timer(FG_POLL_TIME, poll_fg, t);
   60 }
   61 
   62 void poll_fg(void *t)
   63 {
   64     int r;
   65     fg_poll_timer = -1;
   66     r = unblock_itrm(1);
   67     if (r == -1) {
   68         fg_poll_timer = install_timer(FG_POLL_TIME, poll_fg, t);
   69     }
   70     if (r == -2) {
   71         /* This will unblock externally spawned viewer, if it exists */
   72 #ifdef SIGCONT
   73         kill(0, SIGCONT);
   74 #endif
   75     }
   76 }
   77 
   78 void sig_cont(struct terminal *t)
   79 {
   80     unblock_itrm(1);
   81 }
   82 
   83 void handle_basic_signals(struct terminal *term)
   84 {
   85     install_signal_handler(SIGHUP, (void (*)(void *))sig_intr, term, 0);
   86     install_signal_handler(SIGINT, (void (*)(void *))sig_ctrl_c, term, 0);
   87     /*install_signal_handler(SIGTERM, (void (*)(void *))sig_terminate, term, 0);*/
   88 #ifdef SIGTSTP
   89     install_signal_handler(SIGTSTP, (void (*)(void *))sig_tstp, term, 0);
   90 #endif
   91 #ifdef SIGTTIN
   92     install_signal_handler(SIGTTIN, (void (*)(void *))sig_tstp, term, 0);
   93 #endif
   94 #ifdef SIGTTOU
   95     install_signal_handler(SIGTTOU, (void (*)(void *))sig_ign, term, 0);
   96 #endif
   97 #ifdef SIGCONT
   98     install_signal_handler(SIGCONT, (void (*)(void *))sig_cont, term, 0);
   99 #endif
  100 }
  101 
  102 
  103 void unhandle_terminal_signals(struct terminal *term)
  104 {
  105     install_signal_handler(SIGHUP, NULL, NULL, 0);
  106     install_signal_handler(SIGINT, NULL, NULL, 0);
  107 #ifdef SIGTSTP
  108     install_signal_handler(SIGTSTP, NULL, NULL, 0);
  109 #endif
  110 #ifdef SIGTTIN
  111     install_signal_handler(SIGTTIN, NULL, NULL, 0);
  112 #endif
  113 #ifdef SIGTTOU
  114     install_signal_handler(SIGTTOU, NULL, NULL, 0);
  115 #endif
  116 #ifdef SIGCONT
  117     install_signal_handler(SIGCONT, NULL, NULL, 0);
  118 #endif
  119     if (fg_poll_timer != -1) kill_timer(fg_poll_timer), fg_poll_timer = -1;
  120 }
  121 
  122 void unhandle_basic_signals(struct terminal *term)
  123 {
  124     install_signal_handler(SIGHUP, NULL, NULL, 0);
  125     install_signal_handler(SIGINT, NULL, NULL, 0);
  126     /*install_signal_handler(SIGTERM, NULL, NULL, 0);*/
  127 #ifdef SIGTSTP
  128     install_signal_handler(SIGTSTP, NULL, NULL, 0);
  129 #endif
  130 #ifdef SIGTTIN
  131     install_signal_handler(SIGTTIN, NULL, NULL, 0);
  132 #endif
  133 #ifdef SIGTTOU
  134     install_signal_handler(SIGTTOU, NULL, NULL, 0);
  135 #endif
  136 #ifdef SIGCONT
  137     install_signal_handler(SIGCONT, NULL, NULL, 0);
  138 #endif
  139     if (fg_poll_timer != -1) kill_timer(fg_poll_timer), fg_poll_timer = -1;
  140 }
  141 
  142 int terminal_pipe[2];
  143 
  144 int attach_terminal(int in, int out, int ctl, void *info, int len)
  145 {
  146     struct terminal *term;
  147     fcntl(terminal_pipe[0], F_SETFL, O_NONBLOCK);
  148     fcntl(terminal_pipe[1], F_SETFL, O_NONBLOCK);
  149     handle_trm(in, out, out, terminal_pipe[1], ctl, info, len);
  150     mem_free(info);
  151     if ((term = init_term(terminal_pipe[0], out, win_func))) {
  152         handle_basic_signals(term); /* OK, this is race condition, but it must be so; GPM installs it's own buggy TSTP handler */
  153         return terminal_pipe[1];
  154     }
  155     close(terminal_pipe[0]);
  156     close(terminal_pipe[1]);
  157     return -1;
  158 }
  159 
  160 struct status dump_stat;
  161 off_t dump_pos;
  162 
  163 int dump_red_count = 0;
  164 
  165 void end_dump(struct status *stat, void *p)
  166 {
  167     struct cache_entry *ce = stat->ce;
  168     int oh = get_output_handle();
  169     if (oh == -1) return;
  170     if (ce && ce->redirect && dump_red_count++ < MAX_REDIRECTS) {
  171         unsigned char *u, *p;
  172         if (stat->state >= 0) change_connection(stat, NULL, PRI_CANCEL);
  173         u = join_urls(ce->url, ce->redirect);
  174         if (!http_bugs.bug_302_redirect) if (!ce->redirect_get && (p = strchr(ce->url, POST_CHAR))) add_to_strn(&u, p);
  175         load_url(u, stat, PRI_MAIN, 0);
  176         mem_free(u);
  177         return;
  178     }
  179     if (stat->state >= 0 && stat->state < S_TRANS) return;
  180     if (stat->state >= S_TRANS && dmp != D_SOURCE) return;
  181     if (dmp == D_SOURCE) {
  182         if (ce) {
  183             struct fragment *frag;
  184             nextfrag:
  185             foreach(frag, ce->frag) if (frag->offset <= dump_pos && frag->offset + frag->length > dump_pos) {
  186                 int l = frag->length - (dump_pos - frag->offset);
  187                 int w = hard_write(oh, frag->data + dump_pos - frag->offset, l);
  188                 if (w != l) {
  189                     detach_connection(stat, dump_pos);
  190                     if (w < 0) fprintf(stderr, "Error writing to stdout: %s.\n", strerror(errno));
  191                     else fprintf(stderr, "Can't write to stdout.\n");
  192                     retval = RET_ERROR;
  193                     goto terminate;
  194                 }
  195                 dump_pos += w;
  196                 detach_connection(stat, dump_pos);
  197                 goto nextfrag;
  198             }
  199         }
  200         if (stat->state >= 0) return;
  201     } else if (ce) {
  202         struct document_options o;
  203         struct view_state *vs;
  204         struct f_data_c fd;
  205         vs = mem_alloc(sizeof(struct view_state) + strlen(stat->ce->url) + 1);
  206         memset(&o, 0, sizeof(struct document_options));
  207         memset(vs, 0, sizeof(struct view_state));
  208         memset(&fd, 0, sizeof(struct f_data_c));
  209         o.xp = 0;
  210         o.yp = 1;
  211         o.xw = screen_width;
  212         o.yw = 25;
  213         o.col = 0;
  214         o.cp = dump_codepage == -1 ? 0 : dump_codepage;
  215         ds2do(&dds, &o);
  216         o.plain = 0;
  217         o.frames = 0;
  218         memcpy(&o.default_fg, &default_fg, sizeof(struct rgb));
  219         memcpy(&o.default_bg, &default_bg, sizeof(struct rgb));
  220         memcpy(&o.default_link, &default_link, sizeof(struct rgb));
  221         memcpy(&o.default_vlink, &default_vlink, sizeof(struct rgb));
  222         o.framename = "";
  223         init_vs(vs, stat->ce->url);
  224         cached_format_html(vs, &fd, &o);
  225         dump_to_file(fd.f_data, oh);
  226         detach_formatted(&fd);
  227         destroy_vs(vs);
  228         mem_free(vs);
  229 
  230     }
  231     if (stat->state != S_OK) {
  232         unsigned char *m = get_err_msg(stat->state);
  233         fprintf(stderr, "%s\n", get_english_translation(m));
  234         retval = RET_ERROR;
  235         goto terminate;
  236     }
  237     terminate:
  238     terminate = 1;
  239 }
  240 
  241 int g_argc;
  242 unsigned char **g_argv;
  243 
  244 unsigned char *path_to_exe;
  245 
  246 int init_b = 0;
  247 
  248 void init()
  249 {
  250     int uh;
  251     void *info;
  252     int len;
  253     unsigned char *u;
  254     init_trans();
  255     set_sigcld();
  256     init_home();
  257     init_cache();
  258     init_keymaps();
  259 
  260 /* OS/2 has some stupid bug and the pipe must be created before socket :-/ */
  261     if (c_pipe(terminal_pipe)) {
  262         error("ERROR: can't create pipe for internal communication");
  263         retval = RET_FATAL;
  264         goto ttt;
  265     }
  266     if (!(u = parse_options(g_argc - 1, g_argv + 1))) {
  267         retval = RET_SYNTAX;
  268         goto ttt;
  269     }
  270     if (!dmp) {
  271         init_os_terminal();
  272     }
  273     if (!no_connect && (uh = bind_to_af_unix()) != -1) {
  274         close(terminal_pipe[0]);
  275         close(terminal_pipe[1]);
  276         if (!(info = create_session_info(base_session, u, &len))) {
  277             retval = RET_FATAL;
  278             goto ttt;
  279         }
  280         handle_trm(get_input_handle(), get_output_handle(), uh, uh, get_ctl_handle(), info, len);
  281         handle_basic_signals(NULL); /* OK, this is race condition, but it must be so; GPM installs it's own buggy TSTP handler */
  282         mem_free(info);
  283         return;
  284     }
  285     if ((dds.assume_cp = get_cp_index("ISO-8859-1")) == -1) dds.assume_cp = 0;
  286     load_config();
  287     init_b = 1;
  288     read_bookmarks();
  289     load_url_history();
  290     init_cookies();
  291     u = parse_options(g_argc - 1, g_argv + 1);
  292     if (!u) {
  293         ttt:
  294         terminate = 1;
  295         return;
  296     }
  297     if (!dmp) {
  298         if (!((info = create_session_info(base_session, u, &len)) && attach_terminal(get_input_handle(), get_output_handle(), get_ctl_handle(), info, len) != -1)) {
  299             retval = RET_FATAL;
  300             terminate = 1;
  301         }
  302     } else {
  303         unsigned char *uu, *wd;
  304         close(terminal_pipe[0]);
  305         close(terminal_pipe[1]);
  306         if (!*u) {
  307             fprintf(stderr, "URL expected after %s\n.", dmp == D_DUMP ? "-dump" : "-source");
  308             retval = RET_SYNTAX;
  309             goto ttt;
  310         }
  311         dump_stat.end = end_dump;
  312         dump_pos = 0;
  313         if (!(uu = translate_url(u, wd = get_cwd()))) uu = stracpy(u);
  314         if (load_url(uu, &dump_stat, PRI_MAIN, 0)) {
  315             retval = RET_FATAL;
  316             goto ttt;
  317         }
  318         mem_free(uu);
  319         if (wd) mem_free(wd);
  320     }
  321 }
  322 
  323 void terminate_all_subsystems()
  324 {
  325     af_unix_close();
  326     destroy_all_sessions();
  327     check_bottom_halves();
  328     abort_all_downloads();
  329     check_bottom_halves();
  330     destroy_all_terminals();
  331     check_bottom_halves();
  332     free_all_itrms();
  333     abort_all_connections();
  334 #ifdef HAVE_SSL
  335     ssl_finish();
  336 #endif
  337     shrink_memory(1);
  338     if (init_b) save_url_history();
  339     free_history_lists();
  340     free_term_specs();
  341     free_types();
  342     if (init_b) finalize_bookmarks();
  343     free_keymaps();
  344     free_conv_table();
  345     free_blacklist();
  346     if (init_b) cleanup_cookies();
  347     check_bottom_halves();
  348     end_config();
  349     free_strerror_buf();
  350     shutdown_trans();
  351     terminate_osdep();
  352     if (fg_poll_timer != -1) kill_timer(fg_poll_timer), fg_poll_timer = -1;
  353 }
  354 
  355 int main(int argc, char *argv[])
  356 {
  357     g_argc = argc;
  358     g_argv = (unsigned char **)argv;
  359 
  360     init_os();
  361 
  362     get_path_to_exe();
  363 
  364     select_loop(init);
  365     terminate_all_subsystems();
  366 
  367     check_memory_leaks();
  368     return retval;
  369 }
  370 
  371 void shrink_memory(int u)
  372 {
  373     shrink_dns_cache(u);
  374     shrink_format_cache(u);
  375     garbage_collection(u);
  376     delete_unused_format_cache_entries();
  377 }