📄 click-install.cc
字号:
packages.insert(req, 1); active_modules.insert(filename, 1); } else { // package already loaded; note in 'active_modules' that we still need // it String filename = req + OBJSUFFIX; if (active_modules[filename] < 0) filename = req + ".o"; if (active_modules[filename] == 0) active_modules.insert(filename, 1); } }}intmain(int argc, char **argv){ click_static_initialize(); CLICK_DEFAULT_PROVIDES; ErrorHandler *nop_errh = ErrorHandler::default_handler(); ErrorHandler *errh = new PrefixErrorHandler(nop_errh, "click-install: "); // read command line arguments Clp_Parser *clp = Clp_NewParser(argc, argv, sizeof(options) / sizeof(options[0]), options); Clp_SetOptionChar(clp, '+', Clp_ShortNegated); program_name = Clp_ProgramName(clp); const char *router_file = 0; bool file_is_expr = false; bool uninstall = false; bool hotswap = false; int priority = -100;#if FOR_LINUXMODULE bool accessible = true; int threads = 1; output_map = false;#endif while (1) { int opt = Clp_Next(clp); switch (opt) { case HELP_OPT: usage(); exit(0); break; case VERSION_OPT: printf("click-install (Click) %s\n", CLICK_VERSION); printf("Click packages in %s, binaries in %s\n", CLICK_LIBDIR, CLICK_BINDIR); printf("Copyright (c) 1999-2000 Massachusetts Institute of Technology\n\Copyright (c) 2000 Mazu Networks, Inc.\n\Copyright (c) 2002 International Computer Science Institute\n\This is free software; see the source for copying conditions.\n\There is NO warranty, not even for merchantability or fitness for a\n\particular purpose.\n"); exit(0); break; case CLICKPATH_OPT: set_clickpath(clp->arg); break; case ROUTER_OPT: case EXPRESSION_OPT: case Clp_NotOption: if (router_file) { errh->error("router configuration specified twice"); goto bad_option; } router_file = clp->arg; file_is_expr = (opt == EXPRESSION_OPT); break;#if FOR_LINUXMODULE case THREADS_OPT: threads = clp->val.u; if (threads < 1) { errh->error("must have at least one thread"); goto bad_option; } break; case PRIVATE_OPT: accessible = clp->negated; break; case PRIORITY_OPT: priority = clp->val.i; break; case MAP_OPT: output_map = !clp->negated; break;#endif case UNINSTALL_OPT: uninstall = !clp->negated; break; case HOTSWAP_OPT: hotswap = !clp->negated; break; case VERBOSE_OPT: verbose = !clp->negated; break; bad_option: case Clp_BadOption: short_usage(); exit(1); break; case Clp_Done: goto done; } } done: // check options if (hotswap && uninstall) errh->warning("'--hotswap' and '--uninstall' are mutually exclusive"); RouterT *r = read_router(router_file, file_is_expr, nop_errh); if (r) r->flatten(nop_errh); if (!r || errh->nerrors() > 0) exit(1); // pathnames of important Click files String clickfs_config = clickfs_prefix + String("/config"); String clickfs_hotconfig = clickfs_prefix + String("/hotconfig"); String clickfs_errors = clickfs_prefix + String("/errors"); String clickfs_packages = clickfs_prefix + String("/packages"); String clickfs_priority = clickfs_prefix + String("/priority"); // uninstall Click if requested if (uninstall) unload_click(errh); // install Click module if required if (access(clickfs_packages.c_str(), F_OK) < 0) {#if FOR_LINUXMODULE && HAVE_CLICKFS // find and install proclikefs.o StringMap modules(-1); if (read_active_modules(modules, errh) && modules["proclikefs"] < 0) {# if HAVE_LINUXMODULE_2_6 String proclikefs_o = clickpath_find_file("proclikefs.ko", "lib", CLICK_LIBDIR, errh);# else String proclikefs_o = clickpath_find_file("proclikefs.o", "lib", CLICK_LIBDIR, errh);# endif if (verbose) errh->message("Installing proclikefs (%s)", proclikefs_o.cc()); install_module(proclikefs_o, String(), errh); }#endif // find loadable module #if FOR_BSDMODULE || (FOR_LINUXMODULE && HAVE_LINUXMODULE_2_6) String click_o = clickpath_find_file("click.ko", "lib", CLICK_LIBDIR, errh);#elif FOR_LINUXMODULE String click_o = clickpath_find_file("click.o", "lib", CLICK_LIBDIR, errh);#endif if (verbose) errh->message("Installing Click module (%s)", click_o.cc()); // install it in the kernel#if FOR_LINUXMODULE String options; if (threads > 1) options += "threads=" + String(threads); if (!accessible) options += " accessible=0"; install_module(click_o, options, errh);#elif FOR_BSDMODULE install_module(click_o, String(), errh);#endif#if FOR_BSDMODULE || (FOR_LINUXMODULE && HAVE_CLICKFS) // make clickfs_prefix directory if required if (access(clickfs_prefix, F_OK) < 0 && errno == ENOENT) { if (mkdir(clickfs_prefix, 0777) < 0) errh->fatal("cannot make directory %s: %s", clickfs_prefix, strerror(errno)); } // mount Click file system if (verbose) errh->message("Mounting Click module at %s", clickfs_prefix);# if FOR_BSDMODULE int mount_retval = mount("click", clickfs_prefix, 0, 0);# else int mount_retval = mount("none", clickfs_prefix, "click", 0, 0);# endif if (mount_retval < 0 && (verbose || errno != EBUSY)) errh->error("cannot mount %s: %s", clickfs_prefix, strerror(errno));#endif // check that all is well if (access(clickfs_packages.c_str(), F_OK) < 0) errh->fatal("cannot install Click module"); } else {#if FOR_LINUXMODULE if (threads > 1) errh->warning("Click module already installed, '--threads' ignored");#endif } // find current packages HashMap<String, int> active_modules(-1); HashMap<String, int> packages(-1); read_active_modules(active_modules, errh); read_package_file(clickfs_packages, packages, errh); // install required packages install_required_packages(r, packages, active_modules, errh); // set priority if (priority > -100) { FILE *f = fopen(clickfs_priority.c_str(), "w"); if (!f) errh->fatal("%s: %s", clickfs_priority.c_str(), strerror(errno)); fprintf(f, "%d\n", priority); fclose(f); } // write flattened configuration to CLICKFS/config int exit_status = 0; { String config_place = (hotswap ? clickfs_hotconfig : clickfs_config); if (verbose) errh->message("Writing configuration to %s", config_place.cc()); int fd = open(config_place.cc(), O_WRONLY | O_TRUNC); if (fd < 0) errh->fatal("cannot install configuration: %s", strerror(errno)); // XXX include packages? String config = r->configuration_string(); int pos = 0; while (pos < config.length()) { ssize_t written = write(fd, config.data() + pos, config.length() - pos); if (written >= 0) pos += written; else if (errno != EAGAIN && errno != EINTR) errh->fatal("%s: %s", config_place.cc(), strerror(errno)); } int retval = close(fd); if (retval < 0 && errno == EINVAL) exit_status = 2; else if (retval < 0) errh->error("%s: %s", config_place.cc(), strerror(errno)); } // report errors { char buf[1024]; int fd = open(clickfs_errors.cc(), O_RDONLY | O_NONBLOCK); if (fd < 0) errh->warning("%s: %s", clickfs_errors.cc(), strerror(errno)); else { if (verbose) errh->message("Waiting for errors"); while (1) { struct timeval wait; wait.tv_sec = 0; wait.tv_usec = 50000; (void) select(0, 0, 0, 0, &wait); ssize_t got = read(fd, buf, 1024); if (got > 0) fwrite(buf, 1, got, stderr); else if (got == 0) break; else if (errno != EINTR && errno != EAGAIN) { errh->error("%s: %s", clickfs_errors.cc(), strerror(errno)); break; } } close(fd); } } // remove unused packages remove_unneeded_packages(active_modules, packages, errh); if (verbose) errh->message("Done"); exit(exit_status);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -