📄 misc.c
字号:
else { if (st.st_mode & (S_IRWXG|S_IRWXO)) msg (M_WARN, "WARNING: file '%s' is group or others accessible", filename); }#endif}/* * convert system() return into a success/failure value */boolsystem_ok (int stat){#ifdef WIN32 return stat == 0;#else return stat != -1 && WIFEXITED (stat) && WEXITSTATUS (stat) == 0;#endif}/* * did system() call execute the given command? */boolsystem_executed (int stat){#ifdef WIN32 return stat != -1;#else return stat != -1 && WEXITSTATUS (stat) != 127;#endif}/* * Print an error message based on the status code returned by system(). */const char *system_error_message (int stat, struct gc_arena *gc){ struct buffer out = alloc_buf_gc (512, gc);#ifdef WIN32 if (stat == -1) buf_printf (&out, "shell command did not execute -- "); buf_printf (&out, "system() returned error code %d", stat);#else if (stat == -1) buf_printf (&out, "shell command fork failed"); else if (!WIFEXITED (stat)) buf_printf (&out, "shell command did not exit normally"); else { const int cmd_ret = WEXITSTATUS (stat); if (!cmd_ret) buf_printf (&out, "shell command exited normally"); else if (cmd_ret == 127) buf_printf (&out, "could not execute shell command"); else buf_printf (&out, "shell command exited with error status: %d", cmd_ret); }#endif return (const char *)out.data;}/* * Run system(), exiting on error. */boolsystem_check (const char* command, const char* error_message, bool fatal){ struct gc_arena gc = gc_new (); const int stat = openvpn_system (command); int ret = false; if (system_ok (stat)) ret = true; else { if (error_message) msg ((fatal ? M_FATAL : M_WARN), "%s: %s", error_message, system_error_message (stat, &gc)); } gc_free (&gc); return ret;}/* * Initialize random number seed. random() is only used * when "weak" random numbers are acceptable. * OpenSSL routines are always used when cryptographically * strong random numbers are required. */voidinit_random_seed(void){#ifdef HAVE_GETTIMEOFDAY struct timeval tv; if (!gettimeofday (&tv, NULL)) { const unsigned int seed = (unsigned int) tv.tv_sec ^ tv.tv_usec; srandom (seed); }#else /* HAVE_GETTIMEOFDAY */ const time_t current = time (NULL); srandom ((unsigned int)current);#endif /* HAVE_GETTIMEOFDAY */}/* thread-safe strerror */const char *strerror_ts (int errnum, struct gc_arena *gc){#ifdef HAVE_STRERROR struct buffer out = alloc_buf_gc (256, gc); mutex_lock_static (L_STRERR); buf_printf (&out, "%s", openvpn_strerror (errnum, gc)); mutex_unlock_static (L_STRERR); return BSTR (&out);#else return "[error string unavailable]";#endif}/* * Set environmental variable (int or string). * * On Posix, we use putenv for portability, * and put up with its painful semantics * that require all the support code below. */#ifdef HAVE_PUTENVstruct env_item { char *string; struct env_item *next;};static struct env_item *global_env = NULL; /* GLOBAL */static boolenv_string_equal (const char *s1, const char *s2){ int c; ASSERT (s1); ASSERT (s2); while ((c = *s1++) == *s2++) { ASSERT (c); if (c == '=') return true; } return false;}static voidremove_env (char *str){ struct env_item *current, *prev; ASSERT (str); for (current = global_env, prev = NULL; current != NULL; current = current->next) { if (env_string_equal (current->string, str)) { if (prev) prev->next = current->next; else global_env = current->next; free (current->string); free (current); break; } prev = current; }}static voidadd_env (char *str){ struct env_item *item; ASSERT (str); ALLOC_OBJ (item, struct env_item); item->string = str; item->next = global_env; global_env = item;}static voidmanage_env (char *str){ remove_env (str); add_env (str);}#endifvoidsetenv_int (const char *name, int value){ char buf[64]; openvpn_snprintf (buf, sizeof(buf), "%d", value); setenv_str (name, buf);}voidsetenv_str (const char *name, const char *value){ ASSERT (name && strlen(name) > 1); if (!value) value = ""; msg (D_SETENV, "SETENV %s='%s'", name, value);#if defined(WIN32) { char buf[256]; strncpynt (buf, value, sizeof (buf)); safe_string (buf); if (!SetEnvironmentVariable (name, buf)) msg (M_WARN | M_ERRNO, "SetEnvironmentVariable failed, name='%s', value='%s'", name, buf); }#elif defined(HAVE_PUTENV) { const int len = strlen(name) + strlen(value) + 2; struct buffer out = alloc_buf (len); char *str = out.data; int status; buf_printf (&out, "%s=%s", name, value); safe_string (str); mutex_lock_static (L_PUTENV); status = putenv (str); mutex_unlock_static (L_PUTENV); if (status) msg (M_WARN | M_ERRNO, "putenv('%s') failed", str); manage_env (str); }#endif}voidsetenv_del (const char *name){ ASSERT (name);#if defined(WIN32) SetEnvironmentVariable (name, NULL);#elif defined(HAVE_PUTENV) setenv_str (name, NULL);#endif}/* make cp safe to be passed to system() or set as an environmental variable */voidsafe_string (char *cp){ int c; while ((c = *cp)) { if (isalnum (c) || c == '/' || c == '.' || c == '@' || c == '_' || c == '-' || c == '=') ; else *cp = '.'; ++cp; }}/* * taken from busybox networking/ifupdown.c */unsigned intcount_bits(unsigned int a){ unsigned int result; result = (a & 0x55) + ((a >> 1) & 0x55); result = (result & 0x33) + ((result >> 2) & 0x33); return((result & 0x0F) + ((result >> 4) & 0x0F));}intcount_netmask_bits(const char *dotted_quad){ unsigned int result, a, b, c, d; /* Found a netmask... Check if it is dotted quad */ if (sscanf(dotted_quad, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) return -1; result = count_bits(a); result += count_bits(b); result += count_bits(c); result += count_bits(d); return ((int)result);}/* * Go to sleep for n milliseconds. */voidsleep_milliseconds (unsigned int n){#ifdef WIN32 Sleep (n);#else struct timeval tv; tv.tv_sec = n / 1000; tv.tv_usec = (n % 1000) * 1000; select (0, NULL, NULL, NULL, &tv);#endif}/* return true if filename can be opened for read */booltest_file (const char *filename){ FILE *fp = fopen (filename, "r"); if (fp) { fclose (fp); return true; } else return false;}/* create a temporary filename in directory */const char *create_temp_filename (const char *directory, struct gc_arena *gc){ struct buffer fname = alloc_buf_gc (256, gc); buf_printf (&fname, "openvpn_%d_%d.tmp", (int) openvpn_thread_self (), (int) get_random ()); return gen_path (directory, BSTR (&fname), gc);}/* put a directory and filename together */const char *gen_path (const char *directory, const char *filename, struct gc_arena *gc){ struct buffer out = alloc_buf_gc (256, gc); char dirsep[2]; ASSERT (filename); dirsep[0] = OS_SPECIFIC_DIRSEP; dirsep[1] = '\0'; if (directory) { buf_printf (&out, "%s%s", directory, dirsep); } buf_printf (&out, "%s", filename); return BSTR (&out);}/* delete a file, return true if succeeded */booldelete_file (const char *filename){#if defined(WIN32) return (DeleteFile (filename) != 0);#elif defined(HAVE_UNLINK) return (unlink (filename) == 0);#else return false;#endif}/* * Return the next largest power of 2 * or u if u is a power of 2. */unsigned intadjust_power_of_2 (unsigned int u){ unsigned int ret = 1; while (ret < u) { ret <<= 1; ASSERT (ret > 0); } return ret;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -