Пример #1
0
/*
 * `from' may contain an address followed by other characters,
 * at least in /boot, so we permit whitespace (and more) after the address.
 * we do ensure that "delete" cannot be parsed as "de::".
 *
 * some callers don't check the return value for errors, so
 * set `to' to something distinctive in the case of a parse error.
 */
vlong
parseip(uchar *to, char *from)
{
	int i, elipsis = 0, v4 = 1;
	ulong x;
	char *p, *op;

	memset(to, 0, IPaddrlen);
	p = from;
	for(i = 0; i < IPaddrlen && ipcharok(*p); i+=2){
		op = p;
		x = strtoul(p, &p, 16);
		if(*p == '.' || (*p == 0 && i == 0)){	/* ends with v4? */
			if(i > IPaddrlen-4){
				memset(to, 0, IPaddrlen);
				return -1;		/* parse error */
			}
			p = v4parseip(to+i, op);
			i += 4;
			break;
		}
		/* v6: at most 4 hex digits, followed by colon or delim */
		if(x != (ushort)x || *p != ':' && !delimchar(*p)) {
			memset(to, 0, IPaddrlen);
			return -1;			/* parse error */
		}
		to[i] = x>>8;
		to[i+1] = x;
		if(*p == ':'){
			v4 = 0;
			if(*++p == ':'){	/* :: is elided zero short(s) */
				if (elipsis) {
					memset(to, 0, IPaddrlen);
					return -1;	/* second :: */
				}
				elipsis = i+2;
				p++;
			}
		} else if (p == op)		/* strtoul made no progress? */
			break;
	}
	if (p == from || !delimchar(*p)) {
		memset(to, 0, IPaddrlen);
		return -1;				/* parse error */
	}
	if(i < IPaddrlen){
		memmove(&to[elipsis+IPaddrlen-i], &to[elipsis], i-elipsis);
		memset(&to[elipsis], 0, IPaddrlen-i);
	}
	if(v4){
		to[10] = to[11] = 0xff;
		return nhgetl(to + IPv4off);
	} else
		return 6;
}
Пример #2
0
int _inet_pton(int af, const char *src, void *dst)
{
	int i, elipsis = 0;
	unsigned char *to;
	unsigned long x;
	const char *p, *op;

	if(af == AF_INET)
		return _inet_aton(src, (struct in_addr*)dst);

	if(af != AF_INET6){
		errno = EAFNOSUPPORT;
		return -1;
	}

	to = ((struct in6_addr*)dst)->s6_addr;
	memset(to, 0, 16);

	p = src;
	for(i = 0; i < 16 && ipcharok(*p); i+=2){
		op = p;
		x = strtoul(p, (char**)&p, 16);

		if(x != (unsigned short)x || *p != ':' && !delimchar(*p))
			return 0;                       /* parse error */

		to[i] = x>>8;
		to[i+1] = x;
		if(*p == ':'){
			if(*++p == ':'){        /* :: is elided zero short(s) */
				if (elipsis)
					return 0;       /* second :: */
				elipsis = i+2;
				p++;
			}
		} else if (p == op)             /* strtoul made no progress? */
			break;
	}
	if (p == src || !delimchar(*p))
		return 0;                               /* parse error */
	if(i < 16){
		memmove(&to[elipsis+16-i], &to[elipsis], i-elipsis);
		memset(&to[elipsis], 0, 16-i);
	}
	return 1;
}
Пример #3
0
int readline(char *buf, int size) {
  int idx;
  int len;
  int key;
  int i;
  int done;
  int hist_idx;
  int dir;

  if (size <= 0) {
    errno = EINVAL;
    return -1;
  }

  idx = 0;
  len = 0;
  done = 0;
  hist_idx = history_len;
  while (!done) {
    fflush(stdout);
    key = getkey();
    if (key < 0) return key;

    if (key == KEY_TAB) {
      int start;
      int end;
      int split;
      char mask[MAXPATH];
      struct direntry dirent;

      start = idx;
      while (start > 0 && !delimchar(buf[start - 1])) start--;
      end = split = start;
      while (end < len && !delimchar(buf[end])) {
        if (buf[end] == PS1 || buf[end] == PS2) split = end + 1;
        end++;
      }

      dir = find_dir(buf, start, end, split, mask);
      if (dir >= 0) {
        while (_readdir(dir, &dirent, 1) > 0) {
          int newlen = len - (end - split) + dirent.namelen;
          
          if (like(dirent.name, mask) && newlen < size - 1) {
            memmove(buf + split + dirent.namelen, buf + end, len - end);
            memcpy(buf + split, dirent.name, dirent.namelen);

            while (idx < split) putchar(buf[idx++]);
            while (idx > split)  {
              putchar('\b');
              idx--;
            }

            for (i = split; i < newlen; i++) putchar(buf[i]);
            if (newlen < len) {
              for (i = newlen; i < len; i++) putchar(' ');
              for (i = newlen; i < len; i++) putchar('\b');
            }

            end = split + dirent.namelen;
            len = newlen;
            idx = end;

            for (i = end; i < len; i++) putchar('\b');

            fflush(stdout);
            key = getkey();
            if (key < 0) break;
            if (key != KEY_TAB) break;
          }
        }
        close(dir);
        if (key < 0) return key;
      }
    }

    switch (key) {
      case KEY_LEFT:
        if (idx > 0) {
          putchar('\b');
          idx--;
        }
        break;

      case KEY_RIGHT:
        if (idx < len) {
          putchar(buf[idx]);
          idx++;
        }
        break;

      case KEY_CTRL_LEFT:
        if (idx > 0) {
          putchar('\b');
          idx--;
        }
        while (idx > 0 && buf[idx - 1] != ' ') {
          putchar('\b');
          idx--;
        }
        break;

      case KEY_CTRL_RIGHT:
        while (idx < len && buf[idx] != ' ') {
          putchar(buf[idx]);
          idx++;
        }
        if (idx < len) {
          putchar(buf[idx]);
          idx++;
        }
        break;

      case KEY_HOME:
        while (idx > 0) {
          putchar('\b');
          idx--;
        }
        break;

      case KEY_END:
        while (idx < len) {
          putchar(buf[idx]);
          idx++;
        }
        break;

      case KEY_DEL:
        if (idx < len) {
          len--;
          memmove(buf + idx, buf + idx + 1, len - idx);
          for (i = idx; i < len; i++) putchar(buf[i]);
          putchar(' ');
          putchar('\b');
          for (i = idx; i < len; i++) putchar('\b');
        }
        break;

      case KEY_INS:
        insmode = !insmode;
        break;

      case KEY_BACKSPACE:
        if (idx > 0) {
          putchar('\b');
          idx--;
          len--;
          memmove(buf + idx, buf + idx + 1, len - idx);
          for (i = idx; i < len; i++) putchar(buf[i]);
          putchar(' ');
          putchar('\b');
          for (i = idx; i < len; i++) putchar('\b');
        }
        break;

      case KEY_ESC:
        if (_break_on_escape) {
          buf[len] = 0;
          errno = EINTR;
          return -1;
        } else {
          for (i = 0; i < idx; i++) putchar('\b');
          for (i = 0; i < len; i++) putchar(' ');
          for (i = 0; i < len; i++) putchar('\b');
          idx = len = 0;
        }
        break;

      case KEY_EOF:
        if (len == 0) return -1;
        break;

      case KEY_ENTER:
        putchar('\r');
        putchar('\n');
        done = 1;
        break;

      case KEY_UP:
        if (hist_idx > 0) {
          hist_idx--;
          for (i = 0; i < idx; i++) putchar('\b');
          for (i = 0; i < len; i++) putchar(' ');
          for (i = 0; i < len; i++) putchar('\b');
          len = strlen(history[hist_idx]);
          if (len > size - 1) len = size - 1;
          idx = len;
          memcpy(buf, history[hist_idx], len);
          for (i = 0; i < len; i++) putchar(buf[i]);
        }
        break;

      case KEY_DOWN:
        if (hist_idx < history_len - 1) {
          hist_idx++;
          for (i = 0; i < idx; i++) putchar('\b');
          for (i = 0; i < len; i++) putchar(' ');
          for (i = 0; i < len; i++) putchar('\b');
          len = strlen(history[hist_idx]);
          if (len > size - 1) len = size - 1;
          idx = len;
          memcpy(buf, history[hist_idx], len);
          for (i = 0; i < len; i++) putchar(buf[i]);
        }
        break;

      case KEY_UNKNOWN:
        break;

      default:
        if (key >= 0x20 && key <= 0xFF) {
          if (insmode) {
            if (len < size - 1) {
              if (idx < len) memmove(buf + idx + 1, buf + idx, len - idx);
              buf[idx] = key;
              len++;
              for (i = idx; i < len; i++) putchar(buf[i]);
              idx++;
              for (i = idx; i < len; i++) putchar('\b');
            }
          } else {
            if (idx < size - 1) {
              buf[idx] = key;
              putchar(buf[idx]);
              if (idx == len) len++;
              idx++;
            }
          }
        }
    }
  }

  buf[len] = 0;

  add_to_history(buf);

  return len;
}