Beispiel #1
0
static int save_lua_report(udefrag_job_parameters *jp)
{
    wchar_t *path = NULL;
    WINX_FILE *f;
    wchar_t *cn;
    wchar_t compname[MAX_COMPUTERNAME_LENGTH + 1];
    char utf8_compname[(MAX_COMPUTERNAME_LENGTH + 1) * 4];
    char buffer[512];
    struct prb_traverser t;
    winx_file_info *file;
    char *comment;
    char *status;
    int length;
    winx_time tm;
    
    /* should be enough for any path in UTF-8 encoding */
    #define MAX_UTF8_PATH_LENGTH (256 * 1024)
    char *utf8_path;
    
    utf8_path = winx_tmalloc(MAX_UTF8_PATH_LENGTH);
    if(utf8_path == NULL){
        mtrace();
        return (-1);
    }
    
    path = get_report_path(jp);
    if(path == NULL)
        return UDEFRAG_NO_MEM;
    
    f = winx_fbopen(path,"w",RSB_SIZE);
    if(f == NULL){
        f = winx_fopen(path,"w");
        if(f == NULL){
            winx_free(path);
            winx_free(utf8_path);
            return (-1);
        }
    }

    /* print header */
    cn = winx_getenv(L"COMPUTERNAME");
    if(cn){
        wcsncpy(compname,cn,MAX_COMPUTERNAME_LENGTH + 1);
        compname[MAX_COMPUTERNAME_LENGTH] = 0;
        winx_free(cn);
    } else {
        wcscpy(compname,L"nil");
    }
    winx_to_utf8(utf8_compname,sizeof(utf8_compname),compname);
    memset(&tm,0,sizeof(winx_time));
    (void)winx_get_local_time(&tm);
    (void)_snprintf(buffer,sizeof(buffer),
        "-- UltraDefrag report for disk %c:\r\n\r\n"
        "format_version = 7\r\n\r\n"
        "volume_letter = \"%c\"\r\n"
        "computer_name = \"%hs\"\r\n\r\n"
        "current_time = {\r\n"
        "\tyear = %04i,\r\n"
        "\tmonth = %02i,\r\n"
        "\tday = %02i,\r\n"
        "\thour = %02i,\r\n"
        "\tmin = %02i,\r\n"
        "\tsec = %02i,\r\n"
        "\tisdst = false\r\n"
        "}\r\n\r\n"
        "files = {\r\n",
        jp->volume_letter, jp->volume_letter,utf8_compname,
        (int)tm.year,(int)tm.month,(int)tm.day,
        (int)tm.hour,(int)tm.minute,(int)tm.second
        );
    buffer[sizeof(buffer) - 1] = 0;
    (void)winx_fwrite(buffer,1,strlen(buffer),f);
    
    /* print body */
    prb_t_init(&t,jp->fragmented_files);
    file = prb_t_first(&t,jp->fragmented_files);
    while(file){
        if(is_directory(file))
            comment = "[DIR]";
        else if(is_compressed(file))
            comment = "[CMP]";
        else
            comment = " - ";
        
        /*
        * On change of status strings don't forget
        * also to adjust write_file_status routine
        * in udreportcnv.lua file.
        */
        if(is_locked(file))
            status = "locked";
        else if(is_moving_failed(file))
            status = "move failed";
        else if(is_in_improper_state(file))
            status = "invalid";
        else
            status = " - ";
        
        (void)_snprintf(buffer, sizeof(buffer),
            "\t{fragments = %u,"
            "size = %I64u,"
            "comment = \"%s\","
            "status = \"%s\","
            "path = \"",
            (UINT)file->disp.fragments,
            file->disp.clusters * jp->v_info.bytes_per_cluster,
            comment,
            status
            );
        buffer[sizeof(buffer) - 1] = 0;
        (void)winx_fwrite(buffer,1,strlen(buffer),f);

        if(file->path != NULL){
            /* skip \??\ sequence in the beginning of the path */
            length = (int)wcslen(file->path);
            if(length > 4){
                convert_to_utf8_path(utf8_path,MAX_UTF8_PATH_LENGTH,file->path + 4);
            } else {
                convert_to_utf8_path(utf8_path,MAX_UTF8_PATH_LENGTH,file->path);
            }
            (void)winx_fwrite(utf8_path,1,strlen(utf8_path),f);
        }

        (void)strcpy(buffer,"\"},\r\n");
        (void)winx_fwrite(buffer,1,strlen(buffer),f);

        file = prb_t_next(&t);
    }
    
    /* print footer */
    (void)strcpy(buffer,"}\r\n");
    (void)winx_fwrite(buffer,1,strlen(buffer),f);

    itrace("report saved to %ws",path);
    winx_fclose(f);
    winx_free(path);
    winx_free(utf8_path);
    return 0;
}
Beispiel #2
0
/* Checks that |tree| is well-formed
   and verifies that the values in |array[]| are actually in |tree|.
   There must be |n| elements in |array[]| and |tree|.
   Returns nonzero only if no errors detected. */
static int
verify_tree (struct prb_table *tree, int array[], size_t n)
{
  int okay = 1;

  /* Check |tree|'s bst_count against that supplied. */
  if (prb_count (tree) != n)
    {
      printf (" Tree count is %lu, but should be %lu.\n",
              (unsigned long) prb_count (tree), (unsigned long) n);
      okay = 0;
    }

  if (okay)
    {
      if (tree->prb_root != NULL && tree->prb_root->prb_color != PRB_BLACK)
        {
          printf (" Tree's root is not black.\n");
          okay = 0;
        }
    }

  if (okay)
    {
      /* Recursively verify tree structure. */
      size_t count;
      int bh;

      recurse_verify_tree (tree->prb_root, &okay, &count, 0, INT_MAX, &bh);
      if (count != n)
        {
          printf (" Tree has %lu nodes, but should have %lu.\n",
                  (unsigned long) count, (unsigned long) n);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that all the values in |array[]| are in |tree|. */
      size_t i;

      for (i = 0; i < n; i++)
        if (prb_find (tree, &array[i]) == NULL)
          {
            printf (" Tree does not contain expected value %d.\n", array[i]);
            okay = 0;
          }
    }

  if (okay)
    {
      /* Check that |prb_t_first()| and |prb_t_next()| work properly. */
      struct prb_traverser trav;
      size_t i;
      int prev = -1;
      int *item;

      for (i = 0, item = prb_t_first (&trav, tree); i < 2 * n && item != NULL;
           i++, item = prb_t_next (&trav))
        {
          if (*item <= prev)
            {
              printf (" Tree out of order: %d follows %d in traversal\n",
                      *item, prev);
              okay = 0;
            }

          prev = *item;
        }

      if (i != n)
        {
          printf (" Tree should have %lu items, but has %lu in traversal\n",
                  (unsigned long) n, (unsigned long) i);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that |prb_t_last()| and |prb_t_prev()| work properly. */
      struct prb_traverser trav;
      size_t i;
      int next = INT_MAX;
      int *item;

      for (i = 0, item = prb_t_last (&trav, tree); i < 2 * n && item != NULL;
           i++, item = prb_t_prev (&trav))
        {
          if (*item >= next)
            {
              printf (" Tree out of order: %d precedes %d in traversal\n",
                      *item, next);
              okay = 0;
            }

          next = *item;
        }

      if (i != n)
        {
          printf (" Tree should have %lu items, but has %lu in reverse\n",
                  (unsigned long) n, (unsigned long) i);
          okay = 0;
        }
    }

  if (okay)
    {
      /* Check that |prb_t_init()| works properly. */
      struct prb_traverser init, first, last;
      int *cur, *prev, *next;

      prb_t_init (&init, tree);
      prb_t_first (&first, tree);
      prb_t_last (&last, tree);

      cur = prb_t_cur (&init);
      if (cur != NULL)
        {
          printf (" Inited traverser should be null, but is actually %d.\n",
                  *cur);
          okay = 0;
        }

      next = prb_t_next (&init);
      if (next != prb_t_cur (&first))
        {
          printf (" Next after null should be %d, but is actually %d.\n",
                  *(int *) prb_t_cur (&first), *next);
          okay = 0;
        }
      prb_t_prev (&init);

      prev = prb_t_prev (&init);
      if (prev != prb_t_cur (&last))
        {
          printf (" Previous before null should be %d, but is actually %d.\n",
                  *(int *) prb_t_cur (&last), *prev);
          okay = 0;
        }
      prb_t_next (&init);
    }

  return okay;
}
Beispiel #3
0
/**
 * @brief Searches for the first movable file block
 * after the specified cluster on the volume.
 * @param[in] jp job parameters.
 * @param[in,out] min_lcn pointer to variable containing
 * minimum LCN - file blocks below it will be ignored.
 * @param[in] flags one of SKIP_xxx flags defined in udefrag.h
 * @param[out] first_file pointer to variable receiving information
 * about the file the first block belongs to.
 * @return Pointer to the first block. NULL indicates failure.
 */
winx_blockmap *find_first_block(udefrag_job_parameters *jp,
    ULONGLONG *min_lcn, int flags, winx_file_info **first_file)
{
    winx_file_info *found_file;
    winx_blockmap *first_block;
    winx_blockmap b;
    struct file_block fb, *item;
    struct prb_traverser t;
    int movable_file;
    ULONGLONG tm = winx_xtime();
    
    if(min_lcn == NULL || first_file == NULL)
        return NULL;
    
    found_file = NULL; first_block = NULL;
    b.lcn = *min_lcn; fb.block = &b;
    prb_t_init(&t,jp->file_blocks);
    item = prb_t_insert(&t,jp->file_blocks,&fb);
    if(item == &fb){
        /* block at min_lcn not found */
        item = prb_t_next(&t);
        if(prb_delete(jp->file_blocks,&fb) == NULL){
            etrace("cannot remove block from the tree");
            winx_flush_dbg_log(0); /* 'cause error is critical */
        }
    }
    if(item){
        found_file = item->file;
        first_block = item->block;
    }
    while(!jp->termination_router((void *)jp)){
        if(found_file == NULL) break;
        if(flags & SKIP_PARTIALLY_MOVABLE_FILES){
            movable_file = can_move_entirely(found_file,jp);
        } else {
            movable_file = can_move(found_file,jp);
        }
        if(is_file_locked(found_file,jp)) movable_file = 0;
        if(movable_file){
            if(jp->is_fat && is_directory(found_file) && first_block == found_file->disp.blockmap){
                /* skip first fragments of FAT directories */
            } else {
                /* desired block found */
                *min_lcn = first_block->lcn + 1; /* the current block will be skipped later anyway in this case */
                *first_file = found_file;
                jp->p_counters.searching_time += winx_xtime() - tm;
                return first_block;
            }
        }
        
        /* skip current block */
        *min_lcn = *min_lcn + 1;
        /* and go to the next one */
        item = prb_t_next(&t);
        if(item == NULL) break;
        found_file = item->file;
        first_block = item->block;
    }
    *first_file = NULL;
    jp->p_counters.searching_time += winx_xtime() - tm;
    return NULL;
}