Пример #1
0
int			parse_dir(t_list **list, char *str, int *pos)
{
	(void)g_op_tab;
	while (str[(*pos)] && (str[(*pos)] == ' ' || str[(*pos)] == '\t'))
		(*pos)++;
	if (str[(*pos)] == '%')
	{
		(*pos)++;
		if (str[(*pos)] == ':')
		{
			(*pos)++;
			ft_putstr(&str[*pos]);
			if (dir_label(str, pos, list) == FALSE)
				return (FALSE);
		}
		else if (dir_nb(str, pos) == FALSE)
			return (FALSE);
		(*list)->type_arg = T_DIR;
		return (TRUE);
	}
	else
		return (FALSE);
}
Пример #2
0
/**
 * load_directory - Prepare directory generation and create header
 * @secondary: secondary address used for reading the directory
 *
 * This function prepeares directory reading and fills the buffer
 * with the header line of the directory listing.
 * BUG: There is a not-well-known feature in the 1541/1571 disk
 * drives (and possibly others) that returns unparsed directory
 * sectors if $ is opened with a secondary address != 0. This
 * is not emulated here.
 */
static void load_directory(uint8_t secondary) {
  buffer_t *buf;
  path_t path;
  uint8_t pos=1;

  buf = alloc_buffer();
  if (!buf)
    return;

  uint8_t *name;

  buf->secondary = secondary;
  buf->read      = 1;
  buf->lastused  = 31;

  if (command_length > 2 && secondary == 0) {
    if(command_buffer[1]=='=') {
      if(command_buffer[2]=='P') {
        /* Parse Partition Directory */

        /* copy static header to start of buffer */
        memcpy_P(buf->data, dirheader, sizeof(dirheader));
        memcpy_P(buf->data + 32, syspart_line, sizeof(syspart_line));
        buf->lastused  = 63;

        /* set partition number */
        buf->data[HEADER_OFFSET_DRIVE] = max_part;

        /* Let the refill callback handle everything else */
        buf->refill = pdir_refill;

        if(command_length>3) {
          /* Parse the name pattern */
          if (parse_path(command_buffer+3, &path, &name, 0))
            return;

          buf->pvt.pdir.matchstr = name;
        }
        stick_buffer(buf);

        return;
      } else if(command_buffer[2]=='T') {
        buf->pvt.dir.format = DIR_FMT_CMD_SHORT;
        pos=3;
      }
    }
  }

  if (command_buffer[pos]) { /* do we have a path to scan? */
    if (command_length > 2) {
      /* Parse the name pattern */
      if (parse_path(command_buffer+pos, &path, &name, 0))
        return;

      if (opendir(&buf->pvt.dir.dh, &path))
        return;

      buf->pvt.dir.matchstr = name;

      /* Check for a filetype match */
      name = ustrchr(name, '=');
      if (name != NULL) {
        *name++ = 0;
        switch (*name) {
        case 'S':
          buf->pvt.dir.filetype = TYPE_SEQ;
          break;

        case 'P':
          buf->pvt.dir.filetype = TYPE_PRG;
          break;

        case 'U':
          buf->pvt.dir.filetype = TYPE_USR;
          break;

        case 'R':
          buf->pvt.dir.filetype = TYPE_REL;
          break;

        case 'C': /* This is guessed, not verified */
          buf->pvt.dir.filetype = TYPE_CBM;
          break;

        case 'B': /* CMD compatibility */
        case 'D': /* Specifying DEL matches everything anyway */
          buf->pvt.dir.filetype = TYPE_DIR;
          break;

        case 'H': /* Extension: Also show hidden files */
          buf->pvt.dir.filetype = FLAG_HIDDEN;
          break;
        }
        if(buf->pvt.dir.filetype) {
          name++;
          if(*name++ != ',') {
            goto scandone;
          }
        }
        while(*name) {
          switch(*name++) {
          case '>':
            if(parse_date(&date_match_start,&name))
              goto scandone;
            if(date_match_start.month && date_match_start.day) // ignore 00/00/00
              buf->pvt.dir.match_start = &date_match_start;
            break;
          case '<':
            if(parse_date(&date_match_end,&name))
              goto scandone;
            if(date_match_end.month && date_match_end.day) // ignore 00/00/00
              buf->pvt.dir.match_end = &date_match_end;
            break;
          case 'L':
            /* don't switch to long format if 'N' has already been sent */
            if(buf->pvt.dir.format != DIR_FMT_CBM)
              buf->pvt.dir.format = DIR_FMT_CMD_LONG;
            break;
          case 'N':
            buf->pvt.dir.format=DIR_FMT_CBM; /* turn off extended listing */
            break;
          default:
            goto scandone;
          }
          if(*name && *name++ != ',') {
            goto scandone;
          }
        }
      }
    } else {
      /* Command string is two characters long, parse the drive */
      if (command_buffer[1] == '0')
        path.part = current_part;
      else
        path.part = command_buffer[1] - '0' - 1;
      if (path.part >= max_part) {
        set_error(ERROR_DRIVE_NOT_READY);
        return;
      }
      path.dir = partition[path.part].current_dir;
      if (opendir(&buf->pvt.dir.dh, &path))
        return;
    }
  } else {
    path.part = current_part;
    path.dir  = partition[path.part].current_dir;  // if you do not do this, get_label will fail below.
    if (opendir(&buf->pvt.dir.dh, &path))
      return;
  }

scandone:
  if (secondary != 0) {
    /* Raw directory */

    if (partition[path.part].fop == &d64ops) {
      /* No need to fake it for D64 files */
      d64_raw_directory(&path, buf);
      return;
    }

    /* prepare a fake BAM sector */
    memset(buf->data, 0, 256);
    memset(buf->data + BAM_OFFSET_NAME - 2, 0xa0, BAM_A0_AREA_SIZE);

    /* fill label and id */
    if (dir_label(&path, buf->data + BAM_OFFSET_NAME - 2))
      return;

    if (disk_id(&path, buf->data + BAM_OFFSET_ID - 2))
      return;

    /* change padding of label and id to 0xa0 */
    name = buf->data + BAM_OFFSET_NAME - 2 + CBM_NAME_LENGTH;
    while (*--name == ' ')
      *name = 0xa0;

    if (buf->data[BAM_OFFSET_ID+2-2] == 0x20)
      buf->data[BAM_OFFSET_ID+2-2] = 0xa0;

    /* DOS version marker */
    buf->data[0] = 'A';

    buf->refill = rawdir_refill;
    buf->lastused = 253;
  } else {

    /* copy static header to start of buffer */
    memcpy_P(buf->data, dirheader, sizeof(dirheader));

    /* set partition number */
    buf->data[HEADER_OFFSET_DRIVE] = path.part+1;

    /* read directory name */
    if (dir_label(&path, buf->data+HEADER_OFFSET_NAME))
      return;

    /* read id */
    if (disk_id(&path,buf->data+HEADER_OFFSET_ID))
      return;

    /* Let the refill callback handle everything else */
    buf->refill = dir_refill;
  }

  /* Keep the buffer around */
  stick_buffer(buf);

  return;

}