📄 tools.c
字号:
xstrerror()); return NULL; } else { if ((h = gethostbyname(host)) != NULL) { /* DNS lookup successful */ /* use the official name from DNS lookup */ strcpy(host, h->h_name); } present = 1; } } return host;}const char *uniqueHostname(void){ return Config.uniqueHostname ? Config.uniqueHostname : getMyHostname();}voidsafeunlink(const char *s, int quiet){#if USE_ASYNC_IO aioUnlink(s, quiet ? NULL : safeunlinkComplete, quiet ? NULL : xstrdup(s));#else Counter.syscalls.disk.unlinks++; if (unlink(s) < 0 && !quiet) debug(50, 1) ("safeunlink: Couldn't delete %s: %s\n", s, xstrerror());#endif}#if USE_ASYNC_IOstatic voidsafeunlinkComplete(int fd, void *data, int retcode, int errcode){ char *s = data; if (retcode < 0) { errno = errcode; debug(50, 1) ("safeunlink: Couldn't delete %s. %s\n", s, xstrerror()); errno = 0; } xfree(s);}#endif/* leave a privilegied section. (Give up any privilegies) * Routines that need privilegies can rap themselves in enter_suid() * and leave_suid() * To give upp all posibilites to gain privilegies use no_suid() */voidleave_suid(void){ struct passwd *pwd = NULL; struct group *grp = NULL; debug(21, 3) ("leave_suid: PID %d called\n", getpid()); if (geteuid() != 0) return; /* Started as a root, check suid option */ if (Config.effectiveUser == NULL) return; if ((pwd = getpwnam(Config.effectiveUser)) == NULL) return; if (Config.effectiveGroup && (grp = getgrnam(Config.effectiveGroup))) { if (setgid(grp->gr_gid) < 0) debug(50, 1) ("leave_suid: setgid: %s\n", xstrerror()); } else { if (setgid(pwd->pw_gid) < 0) debug(50, 1) ("leave_suid: setgid: %s\n", xstrerror()); } debug(21, 3) ("leave_suid: PID %d giving up root, becoming '%s'\n", getpid(), pwd->pw_name);#if HAVE_SETRESUID if (setresuid(pwd->pw_uid, pwd->pw_uid, 0) < 0) debug(50, 1) ("leave_suid: setresuid: %s\n", xstrerror());#elif HAVE_SETEUID if (seteuid(pwd->pw_uid) < 0) debug(50, 1) ("leave_suid: seteuid: %s\n", xstrerror());#else if (setuid(pwd->pw_uid) < 0) debug(50, 1) ("leave_suid: setuid: %s\n", xstrerror());#endif}/* Enter a privilegied section */voidenter_suid(void){ debug(21, 3) ("enter_suid: PID %d taking root priveleges\n", getpid());#if HAVE_SETRESUID setresuid(-1, 0, -1);#else setuid(0);#endif}/* Give up the posibility to gain privilegies. * this should be used before starting a sub process */voidno_suid(void){ uid_t uid; leave_suid(); uid = geteuid(); debug(21, 3) ("leave_suid: PID %d giving up root priveleges forever\n", getpid());#if HAVE_SETRESUID if (setresuid(uid, uid, uid) < 0) debug(50, 1) ("no_suid: setresuid: %s\n", xstrerror());#else setuid(0); if (setuid(uid) < 0) debug(50, 1) ("no_suid: setuid: %s\n", xstrerror());#endif}voidwritePidFile(void){ int fd; const char *f = NULL; mode_t old_umask; char buf[32]; if ((f = Config.pidFilename) == NULL) return; if (!strcmp(Config.pidFilename, "none")) return; enter_suid(); old_umask = umask(022); fd = file_open(f, O_WRONLY | O_CREAT | O_TRUNC, NULL, NULL, NULL); umask(old_umask); leave_suid(); if (fd < 0) { debug(50, 0) ("%s: %s\n", f, xstrerror()); debug_trap("Could not write pid file"); return; } snprintf(buf, 32, "%d\n", (int) getpid()); write(fd, buf, strlen(buf)); file_close(fd);}pid_treadPidFile(void){ FILE *pid_fp = NULL; const char *f = Config.pidFilename; pid_t pid = -1; int i; if (f == NULL || !strcmp(Config.pidFilename, "none")) { fprintf(stderr, "%s: ERROR: No pid file name defined\n", appname); exit(1); } pid_fp = fopen(f, "r"); if (pid_fp != NULL) { pid = 0; if (fscanf(pid_fp, "%d", &i) == 1) pid = (pid_t) i; fclose(pid_fp); } else { if (errno != ENOENT) { fprintf(stderr, "%s: ERROR: Could not read pid file\n", appname); fprintf(stderr, "\t%s: %s\n", f, xstrerror()); exit(1); } } return pid;}voidsetMaxFD(void){#if HAVE_SETRLIMIT /* try to use as many file descriptors as possible */ /* System V uses RLIMIT_NOFILE and BSD uses RLIMIT_OFILE */ struct rlimit rl;#if defined(RLIMIT_NOFILE) if (getrlimit(RLIMIT_NOFILE, &rl) < 0) { debug(50, 0) ("setrlimit: RLIMIT_NOFILE: %s\n", xstrerror()); } else { rl.rlim_cur = Squid_MaxFD; if (rl.rlim_cur > rl.rlim_max) Squid_MaxFD = rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_NOFILE, &rl) < 0) { snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_NOFILE: %s", xstrerror()); fatal_dump(tmp_error_buf); } }#elif defined(RLIMIT_OFILE) if (getrlimit(RLIMIT_OFILE, &rl) < 0) { debug(50, 0) ("setrlimit: RLIMIT_NOFILE: %s\n", xstrerror()); } else { rl.rlim_cur = Squid_MaxFD; if (rl.rlim_cur > rl.rlim_max) Squid_MaxFD = rl.rlim_cur = rl.rlim_max; if (setrlimit(RLIMIT_OFILE, &rl) < 0) { snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_OFILE: %s", xstrerror()); fatal_dump(tmp_error_buf); } }#endif#else /* HAVE_SETRLIMIT */ debug(21, 1) ("setMaxFD: Cannot increase: setrlimit() not supported on this system\n");#endif /* HAVE_SETRLIMIT */#if HAVE_SETRLIMIT && defined(RLIMIT_DATA) if (getrlimit(RLIMIT_DATA, &rl) < 0) { debug(50, 0) ("getrlimit: RLIMIT_DATA: %s\n", xstrerror()); } else if (rl.rlim_max > rl.rlim_cur) { rl.rlim_cur = rl.rlim_max; /* set it to the max */ if (setrlimit(RLIMIT_DATA, &rl) < 0) { snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_DATA: %s", xstrerror()); fatal_dump(tmp_error_buf); } }#endif /* RLIMIT_DATA */#if HAVE_SETRLIMIT && defined(RLIMIT_VMEM) if (getrlimit(RLIMIT_VMEM, &rl) < 0) { debug(50, 0) ("getrlimit: RLIMIT_VMEM: %s\n", xstrerror()); } else if (rl.rlim_max > rl.rlim_cur) { rl.rlim_cur = rl.rlim_max; /* set it to the max */ if (setrlimit(RLIMIT_VMEM, &rl) < 0) { snprintf(tmp_error_buf, ERROR_BUF_SZ, "setrlimit: RLIMIT_VMEM: %s", xstrerror()); fatal_dump(tmp_error_buf); } }#endif /* RLIMIT_VMEM */}time_tgetCurrentTime(void){#if GETTIMEOFDAY_NO_TZP gettimeofday(¤t_time);#else gettimeofday(¤t_time, NULL);#endif current_dtime = (double) current_time.tv_sec + (double) current_time.tv_usec / 1000000.0; return squid_curtime = current_time.tv_sec;}intpercent(int a, int b){ return b ? ((int) (100.0 * a / b + 0.5)) : 0;}doubledpercent(double a, double b){ return b ? (100.0 * a / b) : 0.0;}voidsquid_signal(int sig, SIGHDLR * func, int flags){#if HAVE_SIGACTION struct sigaction sa; sa.sa_handler = func; sa.sa_flags = flags; sigemptyset(&sa.sa_mask); if (sigaction(sig, &sa, NULL) < 0) debug(50, 0) ("sigaction: sig=%d func=%p: %s\n", sig, func, xstrerror());#else signal(sig, func);#endif}struct in_addrinaddrFromHostent(const struct hostent *hp){ struct in_addr s; xmemcpy(&s.s_addr, hp->h_addr, sizeof(s.s_addr)); return s;}doubledoubleAverage(double cur, double new, int N, int max){ if (N > max) N = max; return (cur * (N - 1.0) + new) / N;}intintAverage(int cur, int new, int n, int max){ if (n > max) n = max; return (cur * (n - 1) + new) / n;}voidlogsFlush(void){ if (debug_log) fflush(debug_log); if (cache_useragent_log) fflush(cache_useragent_log);}char *checkNullString(char *p){ return p ? p : "(NULL)";}voiddlinkAdd(void *data, dlink_node * m, dlink_list * list){ m->data = data; m->prev = NULL; m->next = list->head; if (list->head) list->head->prev = m; list->head = m; if (list->tail == NULL) list->tail = m;}voiddlinkAddTail(void *data, dlink_node * m, dlink_list * list){ m->data = data; m->next = NULL; m->prev = list->tail; if (list->tail) list->tail->next = m; list->tail = m; if (list->head == NULL) list->head = m;}voiddlinkDelete(dlink_node * m, dlink_list * list){ if (m->next) m->next->prev = m->prev; if (m->prev) m->prev->next = m->next; if (m == list->head) list->head = m->next; if (m == list->tail) list->tail = m->prev;}voidkb_incr(kb_t * k, size_t v){ k->bytes += v; k->kb += (k->bytes >> 10); k->bytes &= 0x3FF;}voidgb_flush(gb_t * g){ g->gb += (g->bytes >> 30); g->bytes &= (1 << 30) - 1;}doublegb_to_double(const gb_t * g){ return ((double) g->gb) * ((double) (1 << 30)) + ((double) g->bytes);}const char *gb_to_str(const gb_t * g){ /* * it is often convenient to call gb_to_str several times for _one_ printf */#define max_cc_calls 5 typedef char GbBuf[32]; static GbBuf bufs[max_cc_calls]; static int call_id = 0; double value = gb_to_double(g); char *buf = bufs[call_id++]; if (call_id >= max_cc_calls) call_id = 0; /* select format */ if (value < 1e9) snprintf(buf, sizeof(GbBuf), "%.2f MB", value / 1e6); else if (value < 1e12) snprintf(buf, sizeof(GbBuf), "%.2f GB", value / 1e9); else snprintf(buf, sizeof(GbBuf), "%.2f TB", value / 1e12); return buf;}voiddebugObj(int section, int level, const char *label, void *obj, ObjPackMethod pm){ MemBuf mb; Packer p; assert(label && obj && pm); memBufDefInit(&mb); packerToMemInit(&p, &mb); (*pm) (obj, &p); debug(section, level) ("%s%s", label, mb.buf); packerClean(&p); memBufClean(&mb);}intstringHasWhitespace(const char *s){ return (strcspn(s, w_space) != strlen(s));}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -