コード例 #1
0
ファイル: xfer.c プロジェクト: crtc-demos/mode-infinity
bool match(char *pattern, char *string)
{
  char *star = strchr(pattern, '*') ;

  if ( star == NULL )	/* No globs, must match exactly */
    return qmatch(pattern, string, -1) ;

  if ( star != pattern ) { /* match and remove stuff before star */
    if ( !qmatch(pattern, string, star - pattern) )
      return false ;
    string += star - pattern ;
  }

  while (*star == '*') ++star ;	/* find char after star */

  if ( *star != '\0' ) {  /* loop searching for thing after star */
    while ( (string = strchr(string, *star)) != NULL ) {
      if ( match(star, string) )
	return true ;
      ++string ;	/* skip over initial match char */
    }

    return false ;
  }

  /* Nothing after star, so it must match */
  return true ;
}
コード例 #2
0
ファイル: cs.c プロジェクト: brho/akaros
/*
 *  generic query lookup.  The query is of one of the following
 *  forms:
 *
 *  attr1=val1 attr2=val2 attr3=val3 ...
 *
 *  returns the matching tuple
 *
 *  ipinfo attr=val attr1 attr2 attr3 ...
 *
 *  is like ipinfo and returns the attr{1-n}
 *  associated with the ip address.
 */
static char *genquery(struct mfile *mf, char *query)
{
	int i, n;
	char *p;
	char *attr[Maxattr];
	char *val[Maxattr];
	struct ndbtuple *t;
	struct ndbs s;

	n = getfields(query, attr, COUNT_OF(attr), 1, " ");
	if (n == 0)
		return "bad query";

	if (strcmp(attr[0], "ipinfo") == 0)
		return ipinfoquery(mf, attr, n);

	/* parse pairs */
	for (i = 0; i < n; i++) {
		p = strchr(attr[i], '=');
		if (p == 0)
			return "bad query";
		*p++ = 0;
		val[i] = p;
	}

	/* give dns a chance */
	if ((strcmp(attr[0], "dom") == 0 || strcmp(attr[0], "ip") == 0)
	    && val[0]) {
		t = dnsiplookup(val[0], &s);
		if (t) {
			if (qmatch(t, attr, val, n)) {
				qreply(mf, t);
				ndbfree(t);
				return 0;
			}
			ndbfree(t);
		}
	}

	/* first pair is always the key.  It can't be a '*' */
	t = ndbsearch(db, &s, attr[0], val[0]);

	/* search is the and of all the pairs */
	while (t) {
		if (qmatch(t, attr, val, n)) {
			qreply(mf, t);
			ndbfree(t);
			return 0;
		}

		ndbfree(t);
		t = ndbsnext(&s, attr[0], val[0]);
	}

	return "no match";
}
コード例 #3
0
ファイル: xfer.c プロジェクト: crtc-demos/mode-infinity
static bool crc_file_forall(char *inffile, void *data)
{
  FILE *file ;
  char *scan, filename[MAXLINELEN], buffer[BBCTRACKSIZE] ;
  int rbytes, crc = 0 ;

  if ( (scan = strrchr(inffile, '.')) == NULL || !qmatch(".inf", scan, -1) ) {
    printf("File %s is not an INF file, skipping\n", inffile) ;
    return true ;
  }

  strncpy(filename, inffile, scan - inffile) ;
  filename[scan - inffile] = '\0' ;

  if ( (file = fopen(filename, "r")) == NULL ) {
    printf("Problem opening %s, skipping\n", filename) ;
    return true ; /* don't abort because of this */
  }

  while ( (rbytes = fread(buffer, sizeof(char), BBCTRACKSIZE, file)) > 0 )
    crccalc(buffer, rbytes, &crc) ;

  fclose(file) ;

  printf("File %s has checksum %x\n", filename, crc) ;

  return true ;
}
コード例 #4
0
ファイル: xfer.c プロジェクト: crtc-demos/mode-infinity
static bbc_status_t send_file(serial_h com, char *inffile)
{
  char pcname[MAXLINELEN], bbcname[MAXLINELEN] ;
  char buffer[SENDBUFSIZE] ;
  bbc_status_t result = BBC_OK ;
  int load, exec, length, attr = 0, crc = 0 ;
  int nscan, type = 1, opt4 = -1 ;
  char *scan ;
  FILE *fileh ;
  bool fileerr = false ;

  /* Copy file without ".inf" extension */
  if ( (scan = strrchr(inffile, '.')) == NULL || !qmatch(".inf", scan, -1) ) {
    printf("File %s is not an INF file, skipping\n", inffile) ;
    return BBC_OK ;
  }

  strncpy(pcname, inffile, scan - inffile) ;
  pcname[scan - inffile] = '\0' ;

  /* Get load, exec, length information from INF file */
  if ( (fileh = fopen(inffile, "r")) == NULL ) {
    printf("Problem opening INF file %s\n", inffile) ;
    return BBC_OK ;
  }
  scan = fgets(buffer, SENDBUFSIZE, fileh) ;
  fclose(fileh) ;

  if ( scan == NULL ||
       sscanf(scan, "%s %x %x %x %n", bbcname,
              &load, &exec, &length, &nscan) != 4 ) {
    printf("Problem reading attributes from INF file %s\n", inffile) ;
    return BBC_OK ;
  }

  do {
    scan += nscan ;
    while ( isspace(*scan) ) ++scan ;
    if ( strncmp(scan, "Locked", 6) == 0 ) {
      attr |= FILE_Not_D|FILE_Not_D_Others ;
      nscan = 6 ;
    } else if ( sscanf(scan, " OPT4=%d%n", &opt4, &nscan) != 1 &&
                sscanf(scan, " ATTR=%x%n", &attr, &nscan) != 1 &&
                sscanf(scan, " TYPE=%d%n", &type, &nscan) != 1 )
      break ;
  } while ( true ) ;

  if ( type == 2 ) {
    printf("No standard BBC method of creating directories, skipping %s\n", pcname) ;
    return BBC_OK ;
  } else if ( type != 1 ) {
    printf("Cannot send unknown file %s with unknown OSFILE type %d, skipping\n",
           pcname, type) ;
    return BBC_OK ;
  }

  printf("Sending file %s %x %x %x %c%c%c%c from %s\n",
         bbcname, load, exec, length,
         (attr & FILE_Not_R) ? ' ' : 'R',
         (attr & FILE_Not_W) ? ' ' : 'W',
         (attr & FILE_Not_X) ? ' ' : 'X',
         (attr & FILE_Not_D) ? 'L' : ' ',
         pcname) ;

  /* Open real file and send it */
  if ( (fileh = fopen(pcname, "rb")) == NULL ) {
    printf("Problem opening file %s\n", pcname) ;
    return BBC_OK ;
  }

  serial_printf(com, "R%s\r%d\r%d\r%d\r%d\r", bbcname,
                load, exec, length, attr) ;
  if ( (result = bbc_readline(com, buffer, MAXLINELEN)) == BBC_SYNC ) {
    int nbytes = 0, remaining = length, nwait = SENDBUFSIZE ;

    /* The send loop is revolting. I don't like using sleep(), but it seems
       unavoidable; after the BBC has got a buffer full, it saves to disc.
       While it is saving, and NMI is claimed, it cannot alter the CTS line
       fast enough to prevent buffer overruns (even experimenting with FX 203
       doesn't help. We get around this by matching buffer sizes exactly, and
       putting in a delay after sending each buffer which should be long
       enough to write the buffer to disc. We also send the buffer in small
       chunks and allow the output to drain between writes. */
    while ( nbytes < length ) {
      int wbytes = remaining > MAXLINELEN ? MAXLINELEN : remaining ;

      if ( !fileerr &&
           (int)fread(buffer, sizeof(char), wbytes, fileh) != wbytes ) {
        printf("\nError reading file %s", pcname) ;
        fileerr = true ;
      }
      switch ( serial_write(com, buffer, wbytes) ) {
      case SERIAL_ERROR:
        error("Communications failure") ;
      case SERIAL_TIMEOUT: /* Want more sensible error handling here */
        error("Connection timed out") ;
      }
      serial_flush(com) ;
      remaining -= wbytes ;
      nbytes += wbytes ;
      crccalc(buffer, wbytes, &crc) ;
      printf("\rSent %d bytes of %d", nbytes, length) ;
      fflush(stdout) ;
      if ( nbytes >= nwait ) {
        sleep(SENDBUFSIZE / 512) ; /* Allow 1 extra second per 1/2 K sent */
        nwait += SENDBUFSIZE ;
      } else
        sleep(1) ; /* Allow some time for drain or raise CTS */
    }

    putchar('\n') ;

    serial_printf(com, "%d\r", crc) ;
    /* Synchronise once for CRC and once for writing info to disc */
    if ( (result = bbc_readline(com, buffer, MAXLINELEN)) != BBC_SYNC ) {
      if ( result == BBC_ERROR_2 )
        printf("CRC error sending file %s\n", pcname) ;
    } else if ( (result = bbc_readline(com, buffer, MAXLINELEN)) == BBC_SYNC )
      result = BBC_OK ;
  }

  fclose(fileh) ;

  /* Set !BOOT option if sending !BOOT file */
  if ( result == BBC_OK && opt4 >= 0 )
    if ( (result = setbootopt(com, opt4)) == BBC_SYNC )
      result = BBC_OK ;

  return result ;
}
コード例 #5
0
ファイル: xfer.c プロジェクト: crtc-demos/mode-infinity
static bbc_status_t retrieve_file(serial_h com, filelist *file)
{
  bbc_status_t result ;

  file->type = 0 ;

  if ( (result = getfileinfo(com, file)) == BBC_OK ) {
    char pcname[MAXLINELEN] ;
    FILE *pcfile ;
    bool fileerr = false ;

    if ( file->type == 0 ) { /* OSFILE returned 0 */
      printf("File %s does not exist on BBC, skipping\n", file->name) ;
      return BBC_OK ;
    }

    strcpy(pcname, file->name) ;

    /* Check if PC name is used */
    if ( !check_pcname(file->type == 2 ? "Directory" : "File",
                       pcname, MAXLINELEN) )
      return BBC_OK ;

    if ( file->type == 1 ) { /* OSFILE indicates it's a file */
      char buffer[BBCTRACKSIZE] ;
      int fhandle, size ;

      if ( (pcfile = fopen(pcname, "wb")) == NULL ) {
        printf("Can't open PC file %s to retrieve %s, skipping\n",
               pcname, file->name) ;
        return BBC_OK ;
      }

      printf("Retrieving file %s %x %x %x %c%c%c%c to %s\n",
             file->name, file->load, file->exec, file->length,
             (file->attrs & FILE_Not_R) ? ' ' : 'R',
             (file->attrs & FILE_Not_W) ? ' ' : 'W',
             (file->attrs & FILE_Not_X) ? ' ' : 'X',
             (file->attrs & FILE_Not_D) ? 'L' : ' ',
             pcname) ;

      serial_printf(com, "S%s\r", file->name) ;

      if ( (result = bbc_readline(com, buffer, MAXLINELEN)) == BBC_SYNC &&
           (result = bbc_readline(com, buffer, MAXLINELEN)) == BBC_OK &&
           sscanf(buffer, "%d", &fhandle) == 1 &&
           fhandle != 0 &&
           (result = bbc_readline(com, buffer, MAXLINELEN)) == BBC_OK &&
           sscanf(buffer, "%d", &size) == 1 ) {
        int remaining = size, nbytes = 0 ;
        unsigned int crc = 0;

        while ( remaining > 0 ) {
          int rbytes = remaining > BBCTRACKSIZE ? BBCTRACKSIZE : remaining ;

          if ( (result = bbc_read(com, buffer, &rbytes)) == BBC_OK ) {
            if ( !fileerr &&
                 (int)fwrite(buffer, sizeof(char), rbytes, pcfile) != rbytes )
              fileerr = true ;
            remaining -= rbytes ;
            nbytes += rbytes ;
            crccalc(buffer, rbytes, &crc) ;
            printf("\rRead %d bytes of %d", nbytes, size) ;
            fflush(stdout) ;
          } else /* Error reading bytes */
            break ;
        }

        putchar('\n') ;

        if ( result == BBC_OK ) {
          unsigned int bbccrc = 0 ;

          if ( (result = bbc_readline(com, buffer, MAXLINELEN)) != BBC_OK ||
               sscanf(buffer, "%u", &bbccrc) != 1 ) {
            printf("Problem retrieving CRC for %s from BBC\n", file->name) ;
            fileerr = true ;
          } else if ( bbccrc != crc ) {
            printf("CRC error for %s (%x not equal to %x)\n",
                   file->name, crc, bbccrc) ;
            fileerr = true ;
          }
        }
      } else {
        printf("Problem opening %s on BBC, skipping\n", file->name) ;
        fileerr = true ;
      }

      fclose(pcfile) ;
    } else if ( file->type == 2 ) { /* OSFILE indicates it's a directory */
      char pcdir[MAXLINELEN], bbcdir[MAXLINELEN] ;
      filelist *subfiles = NULL ;

      printf("Retrieving directory %s %x %x %x %c%c%c%c to %s\n",
             file->name, file->load, file->exec, file->length,
             (file->attrs & FILE_Not_R) ? ' ' : 'R',
             (file->attrs & FILE_Not_W) ? ' ' : 'W',
             (file->attrs & FILE_Not_X) ? ' ' : 'X',
             (file->attrs & FILE_Not_D) ? 'L' : ' ',
             pcname) ;
      (void)mkdir(pcname, 0755) ;
      if ( getcwd(pcdir, MAXLINELEN) &&
           (result = getcurdir(com, bbcdir, MAXLINELEN)) == BBC_OK ) {
        if ( chdir(pcname) == 0 ) {
          if ( (result = setcurdir(com, file->name)) == BBC_SYNC ) {
            if ( (result = getfilenames(com, "*", &subfiles, false)) == BBC_SYNC ) {
              result = BBC_OK ;

              while ( subfiles && !interrupted(false) ) {
                filelist *next = subfiles->next ;

                if ( (result = retrieve_file(com, subfiles)) != BBC_OK ) {
                  printf("Error retrieving file %s, skipping\n",
                         subfiles->name) ;
                  free(subfiles) ;
                  subfiles = next ;
                  fileerr = true ;
                  break ;
                }

                free(subfiles) ;
                subfiles = next ;
              }

              while ( subfiles ) {
                filelist *next = subfiles->next ;
                printf("Skipping file %s because of previous error\n",
                       subfiles->name) ;
                free(subfiles) ;
                subfiles = next ;
              }

              if ( interrupted(true) )
                fileerr = true ;
            }

            if ( result == BBC_OK &&
                 (result = setcurdir(com, bbcdir)) == BBC_SYNC )
              result = BBC_OK ;
          }
          (void)chdir(pcdir) ;
        }
      }
    } else {
      printf("File %s has unknown OSFILE type %d, skipping\n",
             file->name, file->type) ;
      return BBC_OK ;
    }

    if ( result == BBC_OK && !fileerr ) { /* Write .inf file */
      char *basename ;

      strcat(pcname, ".inf") ;

      /* Get basename to compare against; if !boot, get boot option */
      if ( (basename = strrchr(file->name, '.')) != NULL )
        ++basename ;
      else
        basename = file->name ;

      if ( (pcfile = fopen(pcname, "w")) != NULL ) {
        fprintf(pcfile, "%s %06x %06x %06x%s",
                file->name, file->load, file->exec, file->length,
                (file->attrs & FILE_Not_D) ? " Locked" : "") ;
        /* Use qmatch to use case-insensitive comparison */
        if ( qmatch("!boot", basename, -1) ) {
          char buffer[MAXLINELEN] ;

          if ( (result = getbootopt(com, buffer, MAXLINELEN)) == BBC_OK )
            fprintf(pcfile, " OPT4=%s", buffer) ;
        }
        fprintf(pcfile, " ATTR=%x TYPE=%d\n", file->attrs, file->type) ;
        fclose(pcfile) ;
      } else { /* Can't open .inf name, delete downloaded file */
        printf("Problem creating info file %s.inf, skipping\n", file->name) ;
        pcname[strlen(pcname) - 4] = '\0' ;
        remove(pcname) ;
      }
    } else { /* If download failed, remove file */
      remove(pcname) ;
    }
  }

  return result ;
}