⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.c

📁 ReactOS是一些高手根据Windows XP的内核编写出的类XP。内核实现机理和API函数调用几乎相同。甚至可以兼容XP的程序。喜欢研究系统内核的人可以看一看。
💻 C
📖 第 1 页 / 共 2 页
字号:
    while (*s && *s != '\n' && (t - tmp_line) < sizeof (tmp_line)-1 && s < top)
	*t++ = *s++;
    *t = 0;
    return tmp_line;
}

/* FIXME: I should write a faster version of this (Aho-Corasick stuff) */
char * _icase_search (char *text, char *data, int *lng)
{
    char *d = text;
    char *e = data;
    int dlng = 0;

    if (lng)
	*lng = 0;
    for (;*e; e++) {
	while (*(e+1) == '\b' && *(e+2)) {
	    e += 2;
	    dlng += 2;
	}
	if (toupper((unsigned char) *d) == toupper((unsigned char) *e))
	    d++;
	else {
	    e -= d - text;
	    d = text;
	    dlng = 0;
	}
	if (!*d) {
	    if (lng)
		*lng = strlen (text) + dlng;
	    return e+1;
	}
    }
    return 0;
}

/* The basename routine */
char *x_basename (char *s)
{
    char  *where;
    return ((where = strrchr (s, PATH_SEP)))? where + 1 : s;
}

char *get_full_name (char *dir, char *file)
{
    int i;
    char *d = malloc (strlen (dir) + strlen (file) + 2);

    strcpy (d, dir);
    i = strlen (dir);
    if (dir [i - 1] != PATH_SEP || dir [i] != 0)
	strcat (d, PATH_SEP_STR);
    file = x_basename (file);
    strcat (d, file);
    return d;
}

void my_putenv (char *name, char *data)
{
    char *full;

    full = xmalloc (strlen (name) + strlen (data) + 2, "util, my_putenv");
    sprintf (full, "%s=%s", name, data);
    putenv (full);
    /* WARNING: NEVER FREE THE full VARIABLE!!!!!!!!!!!!!!!!!!!!!!!! */
    /* It is used by putenv. Freeing it will corrupt the environment */
}

#if 0
static void my_putenv_expand (char *name, char macro_code)
{
    char *data;

    data = expand_format (macro_code);
    my_putenv (name, data);
    free (data);
}

/* Puts some status information in to the environment so that
   processes to be executed can access it. */
static void prepare_environment (void)
{
    my_putenv_expand ("MC_CURRENT_DIR", 'd');
    my_putenv_expand ("MC_OTHER_DIR", 'D');
    my_putenv_expand ("MC_CURRENT_FILE", 'f');
    my_putenv_expand ("MC_OTHER_FILE", 'F');
    my_putenv_expand ("MC_CURRENT_TAGGED", 't');
    my_putenv_expand ("MC_OTHER_TAGGED", 'T');
    /* MC_CONTROL_FILE has been added to environment on startup */
}
#endif

char *unix_error_string (int error_num)
{
    static char buffer [256];
    char *error_msg;

#ifdef HAVE_STRERROR
    error_msg = strerror (error_num);
#else
    extern int sys_nerr;
    extern char *sys_errlist [];
    if ((0 <= error_num) && (error_num < sys_nerr))
	error_msg = sys_errlist[error_num];
    else
	error_msg = "strange errno";
#endif
    sprintf (buffer, "%s (%d)", error_msg, error_num);
    return buffer;
}

char *copy_strings (const char *first,...)
{
    va_list ap;
    int len;
    char *data, *result;

    if (!first)
	return 0;

    len = strlen (first);
    va_start (ap, first);

    while ((data = va_arg (ap, char *))!=0)
	len += strlen (data);

    len++;

    result = xmalloc (len, "copy_strings");
    va_end (ap);
    va_start (ap, first);
    strcpy (result, first);
    while ((data = va_arg (ap, char *)) != 0)
	strcat (result, data);
    va_end (ap);

    return result;
}

long blocks2kilos (int blocks, int bsize)
{
    if (bsize > 1024){
	return blocks * (bsize / 1024);
    } else if (bsize < 1024){
	return blocks / (1024 /bsize);
    } else
	return blocks;
}

void init_my_statfs (void)
{
#ifndef NO_INFOMOUNT
    mount_list = read_filesystem_list (1, 1);
#endif
}

char *skip_separators (char *s)
{
    for (;*s; s++)
	if (*s != ' ' && *s != '\t' && *s != ',')
	    break;
    return s;
}

char *skip_numbers (char *s)
{
    for (;*s; s++)
	if (!isdigit (*s))
	    break;
    return s;
}

/* Remove all control sequences from the argument string.  We define
 * "control sequence", in a sort of pidgin BNF, as follows:
 *
 * control-seq = Esc non-'['
 *	       | Esc '[' (0 or more digits or ';' or '?') (any other char)
 *
 * This scheme works for all the terminals described in my termcap /
 * terminfo databases, except the Hewlett-Packard 70092 and some Wyse
 * terminals.  If I hear from a single person who uses such a terminal
 * with MC, I'll be glad to add support for it.  (Dugan)
 */

char *strip_ctrl_codes (char *s)
{
    int i;  /* Current length of the string's correct (stripped) prefix */
    int j;  /* Number of control characters we have skipped so far */

    if (!s)
	return 0;

    for (i = 0, j = 0; s [i+j]; ++i)
	if (s [i+j] != ESC_CHAR){
	    if (j)
		s [i] = s [i+j];
	} else {
	    ++j;
	    if (s [i+j++] == '[')
		while (strchr ("0123456789;?", s [i+j++]))
		    /* Skip the control sequence's arguments */ ;
	    --i;
	}
    s[i] = 0;
    return s;
}

#ifndef HAVE_STRCASECMP
/* At least one version of HP/UX lacks this */
/* Assumes ASCII encoding */
int strcasecmp (const char *s, const char *d)
{
    register signed int result;

    while (1){
	if (result = (0x20 | *s) - (0x20 | *d))
	    break;
	if (!*s)
	    return 0;
	s++;
	d++;
    }
    return result;
}
#endif /* HAVE_STRCASECMP */

/* getwd is better than getcwd, the later uses a popen ("pwd"); */
char *get_current_wd (char *buffer, int size)
{
    char *p;

#ifdef HAVE_GETWD
    p = (char *) getwd (buffer);
#else
    p = getcwd (buffer, size);
#endif
    return p;
}

#define CHECK(x) if (x == -1) return 0;

long get_small_endian_long (int fd)
{
    unsigned char a, b, c, d;

    /* It needs to be read one byte at the time to avoid endianess
       portability problems */
    CHECK (mc_read (fd, &a, 1));
    CHECK (mc_read (fd, &b, 1));
    CHECK (mc_read (fd, &c, 1));
    CHECK (mc_read (fd, &d, 1));
    return (d << 24) | (c << 16) | (b << 8) | a;
}

/* This function returns 0 if the file is not in gunzip format  */
/* or how much memory must be allocated to load the gziped file */
/* Warning: this function moves the current file pointer */
long int is_gunzipable (int fd, int *type)
{
    unsigned char magic [4];

    *type = ISGUNZIPABLE_GUNZIP;

    /* Read the magic signature */
    CHECK (mc_read (fd, &magic [0], 1));
    CHECK (mc_read (fd, &magic [1], 1));
    CHECK (mc_read (fd, &magic [2], 1));
    CHECK (mc_read (fd, &magic [3], 1));

    /* GZIP_MAGIC and OLD_GZIP_MAGIC */
    if (magic [0] == 037 && (magic [1] == 0213 || magic [1] == 0236)){
	/* Read the uncompressed size of the file */
	mc_lseek (fd, -4, SEEK_END);
	return get_small_endian_long (fd);
    }

    /* PKZIP_MAGIC */
    if (magic [0] == 0120 && magic [1] == 0113 && magic [2] == 003 && magic [3] == 004){
	/* Read compression type */
	mc_lseek (fd, 8, SEEK_SET);
	CHECK (mc_read (fd, &magic [0], 1));
	CHECK (mc_read (fd, &magic [1], 1));

	/* Gzip can handle only deflated (8) or stored (0) files */
	if ((magic [0] != 8 && magic [0] != 0) || magic [1] != 0)
	     return 0;
        /* Read the uncompressed size of the first file in the archive */
	mc_lseek (fd, 22, SEEK_SET);
	return get_small_endian_long (fd);
    }

    /* PACK_MAGIC and LZH_MAGIC and compress magic */
    if (magic [0] == 037 && (magic [1] ==  036 || magic [1] == 0240 || magic [1] == 0235)){
	 /* In case the file is packed, sco lzhed or compress_magic, the */
	 /* program guesses that the uncompressed size is (at most) four */
	 /* times the length of the compressed size, if the compression  */
	 /* ratio is more than 4:1 the end of the file is not displayed  */
	 return 4*mc_lseek (fd, 0, SEEK_END);
    }

    /* BZIP and BZIP2 files */
    if ((magic[0] == 'B') && (magic[1] == 'Z') &&
	(magic [3] >= '1') && (magic [3] <= '9')){
            switch (magic[2]) {
                case '0':
                    *type = ISGUNZIPABLE_BZIP;
                    return 5*mc_lseek (fd, 0, SEEK_END);
                case 'h':
	            *type = ISGUNZIPABLE_BZIP2;
	            return 5*mc_lseek (fd, 0, SEEK_END);
            }
    }
    return 0;
}

char *
decompress_command (int type)
{
	switch (type){
	case ISGUNZIPABLE_GUNZIP:
		return "gzip -cdf";

	case ISGUNZIPABLE_BZIP:
		return "bzip -d";

	case ISGUNZIPABLE_BZIP2:
		return "bzip2 -dc";
	}
	/* Should never reach this place */
	fprintf (stderr, "Fatal: decompress_command called with an unknown argument\n");
	return 0;
}

void
decompress_command_and_arg (int type, char **cmd, char **flags)
{
	switch (type){
	case ISGUNZIPABLE_GUNZIP:
		*cmd   = "gzip";
		*flags = "-cdf";
		return;

	case ISGUNZIPABLE_BZIP:
		*cmd   = "bzip";
		*flags = "-d";
		return;


	case ISGUNZIPABLE_BZIP2:
		*cmd   = "bzip2";
		*flags = "-dc";
		return;
	}
	*cmd   = 0;
	*flags = 0;

	/* Should never reach this place */
	fprintf (stderr, "Fatal: decompress_command called with an unknown argument\n");
}

/* Hooks */
void add_hook (Hook **hook_list, void (*hook_fn)(void *), void *data)
{
    Hook *new_hook = xmalloc (sizeof (Hook), "add_hook");

    new_hook->hook_fn = hook_fn;
    new_hook->next    = *hook_list;
    new_hook->hook_data = data;

    *hook_list = new_hook;
}

void execute_hooks (Hook *hook_list)
{
    Hook *new_hook = 0;
    Hook *p;

    /* We copy the hook list first so tahat we let the hook
     * function call delete_hook
     */

    while (hook_list){
	add_hook (&new_hook, hook_list->hook_fn, hook_list->hook_data);
	hook_list = hook_list->next;
    }
    p = new_hook;

    while (new_hook){
	(*new_hook->hook_fn)(new_hook->hook_data);
	new_hook = new_hook->next;
    }

    for (hook_list = p; hook_list;){
	p = hook_list;
	hook_list = hook_list->next;
	free (p);
    }
}

void delete_hook (Hook **hook_list, void (*hook_fn)(void *))
{
    Hook *current, *new_list, *next;

    new_list = 0;

    for (current = *hook_list; current; current = next){
	next = current->next;
	if (current->hook_fn == hook_fn)
	    free (current);
	else
	    add_hook (&new_list, current->hook_fn, current->hook_data);
    }
    *hook_list = new_list;
}

int hook_present (Hook *hook_list, void (*hook_fn)(void *))
{
    Hook *p;

    for (p = hook_list; p; p = p->next)
	if (p->hook_fn == hook_fn)
	    return 1;
    return 0;
}

void wipe_password (char *passwd)
{
    char *p = passwd;

    for (;*p ; p++)
        *p = 0;
    free (passwd);
}

/* Convert "\E" -> esc character and ^x to control-x key and ^^ to ^ key */
/* Returns a newly allocated string */
char *convert_controls (char *s)
{
    char *valcopy = strdup (s);
    char *p, *q;

    /* Parse the escape special character */
    for (p = s, q = valcopy; *p;){
	if (*p == '\\'){
	    p++;
	    if ((*p == 'e') || (*p == 'E')){
		p++;
		*q++ = ESC_CHAR;
	    }
	} else {
	    if (*p == '^'){
		p++;
		if (*p == '^')
		    *q++ = *p++;
		else {
		    *p = (*p | 0x20);
		    if (*p >= 'a' && *p <= 'z') {
		        *q++ = *p++ - 'a' + 1;
		    } else
		        p++;
		}
	    } else
		*q++ = *p++;
	}
    }
    *q++ = 0;
    return valcopy;
}

/* Reverse the string */
char *reverse_string (char *string)
{
    int len = strlen (string);
    int i;
    const int steps = len/2;

    for (i = 0; i < steps; i++){
	char c = string [i];

	string [i] = string [len-i-1];
	string [len-i-1] = c;
    }
    return string;
}

char *resolve_symlinks (char *path)
{
    char *buf, *buf2, *p, *q, *r, c;
    int len;
    struct stat mybuf;

    if (*path != PATH_SEP)
        return NULL;
    r = buf = xmalloc (MC_MAXPATHLEN, "resolve symlinks");
    buf2 = xmalloc (MC_MAXPATHLEN, "resolve symlinks");
    *r++ = PATH_SEP;
    *r = 0;
    p = path;
    for (;;) {
	q = strchr (p + 1, PATH_SEP);
	if (!q) {
	    q = strchr (p + 1, 0);
	    if (q == p + 1)
	        break;
	}
	c = *q;
	*q = 0;
	if (mc_lstat (path, &mybuf) < 0) {
	    free (buf);
	    free (buf2);
	    *q = c;
	    return NULL;
	}
	if (!S_ISLNK (mybuf.st_mode))
	    strcpy (r, p + 1);
	else {
	    len = mc_readlink (path, buf2, MC_MAXPATHLEN);
	    if (len < 0) {
		free (buf);
		free (buf2);
		*q = c;
		return NULL;
	    }
	    buf2 [len] = 0;
	    if (*buf2 == PATH_SEP)
		strcpy (buf, buf2);
	    else
		strcpy (r, buf2);
	}
	canonicalize_pathname (buf);
	r = strchr (buf, 0);
	if (!*r || *(r - 1) != PATH_SEP) {
	    *r++ = PATH_SEP;
	    *r = 0;
	}
	*q = c;
	p = q;
	if (!c)
	    break;
    }
    if (!*buf)
	strcpy (buf, PATH_SEP_STR);
    else if (*(r - 1) == PATH_SEP && r != buf + 1)
	*(r - 1) = 0;
    free (buf2);
    return buf;
}

/* Finds out a relative path from first to second, i.e. goes as many ..
 * as needed up in first and then goes down using second */
char *diff_two_paths (char *first, char *second)
{
    char *p, *q, *r, *s, *buf = 0;
    int i, j, prevlen = -1, currlen;

    first = resolve_symlinks (first);
    if (first == NULL)
        return NULL;
    for (j = 0; j < 2; j++) {
	p = first;
	if (j) {
	    second = resolve_symlinks (second);
	    if (second == NULL) {
		free (first);
	        return buf;
	    }
	}
	q = second;
	for (;;) {
	    r = strchr (p, PATH_SEP);
	    s = strchr (q, PATH_SEP);
	    if (!r || !s)
	      break;
	    *r = 0; *s = 0;
	    if (strcmp (p, q)) {
		*r = PATH_SEP; *s = PATH_SEP;
		break;
	    } else {
		*r = PATH_SEP; *s = PATH_SEP;
	    }
	    p = r + 1;
	    q = s + 1;
	}
	p--;
	for (i = 0; (p = strchr (p + 1, PATH_SEP)) != NULL; i++);
	currlen = (i + 1) * 3 + strlen (q) + 1;
	if (j) {
	    if (currlen < prevlen)
	        free (buf);
	    else {
		free (first);
		free (second);
		return buf;
	    }
	}
	p = buf = xmalloc (currlen, "diff 2 paths");
	prevlen = currlen;
	for (; i >= 0; i--, p += 3)
	  strcpy (p, "../");
	strcpy (p, q);
    }
    free (first);
    free (second);
    return buf;
}

#ifndef HAVE_TRUNCATE
/* On SCO and Windows NT systems */
int my_ftruncate (int fd, long size)
{
#ifdef OS2_NT
    if(_chsize(fd, size))
	return -1;
    else
	return 0;
#else
    struct flock lk;

    lk.l_whence = 0;
    lk.l_start = size;
    lk.l_len = 0;

    return fcntl (fd, F_FREESP, &lk);
#endif
}

int truncate (const char *path, long size)
{
    int fd;
    int res;

    fd = open (path, O_RDWR, 0);
    if (fd < 0)
	return fd;
    res = my_ftruncate (fd, size);
    if (res < 0)
	return res;
    close (fd);
    return 0;

}

#endif

char *
concat_dir_and_file (const char *dir, const char *file)
{
    int l = strlen (dir);

    if (dir [l-1] == PATH_SEP)
	return copy_strings (dir, file, 0);
    else
	return copy_strings (dir, PATH_SEP_STR, file, 0);
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -