📄 click-install.cc
字号:
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-2005 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->vstr); break; case ROUTER_OPT: case EXPRESSION_OPT: router_file: if (router_file) { errh->error("router configuration specified twice"); goto bad_option; } router_file = clp->vstr; file_is_expr = (opt == EXPRESSION_OPT); break; case Clp_NotOption: if (!click_maybe_define(clp->vstr, errh)) goto router_file; 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:# if HAVE_LINUXMODULE_2_6 errh->warning("'%s' ignored on 2.6 kernels", Clp_CurOptionName(clp));# else output_map = !clp->negated;# endif break; case GREEDY_OPT: greedy = !clp->negated; break; case UID_OPT: { const char *colon = find(clp->vstr, clp->vstr + strlen(clp->vstr), ':'); if (colon > clp->vstr) { String s(clp->vstr, colon); if (!cp_integer(s, &uid)) { errno = 0; struct passwd *pwd = getpwnam(s.c_str()); if (!pwd && errno) errh->error("username lookup: %s", strerror(errno)); else if (!pwd) errh->error("no such user '%s'", s.c_str()); else uid = pwd->pw_uid; } } if (*colon && colon[1]) { clp->vstr = colon + 1; goto gid; } break; } gid: case GID_OPT: { if (!cp_integer(clp->vstr, &gid)) { errno = 0; struct group *grp = getgrnam(clp->vstr); if (!grp && errno) errh->error("group lookup: %s", strerror(errno)); else if (!grp) errh->error("no such group '%s'", clp->vstr); else gid = grp->gr_gid; } break; } case CPU_OPT: cpu = clp->val.i; 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, true); if (!r || errh->nerrors() > 0) exit(1); // pathnames of important Click files String clickfs_packages = clickfs_prefix + String("/packages"); // 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 // 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.c_str()); 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.c_str()); // install it in the kernel#if FOR_LINUXMODULE String options; if (threads > 1) options += "threads=" + String(threads); if (greedy) options += " greedy=1"; if (!accessible) options += " accessible=0"; if (uid != 0) options += " uid=" + String(uid); if (gid != 0) options += " gid=" + String(gid); if (cpu != -1) options += " cpu=" + String(cpu); install_module(click_o, options, errh);#elif FOR_BSDMODULE install_module(click_o, String(), errh);#endif#if FOR_BSDMODULE || FOR_LINUXMODULE // make clickfs_prefix directory if required if (access(clickfs_dir.c_str(), F_OK) < 0 && errno == ENOENT) { if (mkdir(clickfs_dir.c_str(), 0777) < 0) errh->fatal("cannot make directory %s: %s", clickfs_dir.c_str(), strerror(errno)); } // mount Click file system if (verbose) errh->message("Mounting Click module at %s", clickfs_dir.c_str());# if FOR_BSDMODULE int mount_retval = mount("click", clickfs_dir.c_str(), 0, 0);# else int mount_retval = mount("none", clickfs_dir.c_str(), "click", 0, 0);# endif if (mount_retval < 0 && (verbose || errno != EBUSY)) errh->error("cannot mount %s: %s", clickfs_dir.c_str(), 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 || greedy || !accessible || uid != 0 || gid != 0 || cpu != -1) errh->warning("Click module already installed, some options ignored");#endif } // check for new-style directory layout if (adjust_clickfs_prefix()) clickfs_packages = clickfs_prefix + String("/packages"); String clickfs_config = clickfs_prefix + String("/config"); String clickfs_hotconfig = clickfs_prefix + String("/hotconfig"); String clickfs_errors = clickfs_prefix + String("/errors"); String clickfs_priority = clickfs_prefix + String("/priority"); // find current packages HashTable<String, int> active_modules(-1); HashTable<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.c_str()); int fd = open(config_place.c_str(), 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.c_str(), strerror(errno)); } int retval = close(fd); if (retval < 0 && errno == EINVAL) exit_status = 2; else if (retval < 0) errh->error("%s: %s", config_place.c_str(), strerror(errno)); } // report errors { char buf[1024]; int fd = open(clickfs_errors.c_str(), O_RDONLY | O_NONBLOCK); if (fd < 0) errh->warning("%s: %s", clickfs_errors.c_str(), 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) ignore_result(fwrite(buf, 1, got, stderr)); else if (got == 0) break; else if (errno != EINTR && errno != EAGAIN) { errh->error("%s: %s", clickfs_errors.c_str(), 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 + -