File: ffindex_modify.c

package info (click to toggle)
ffindex 0.9.9.9-2
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 488 kB
  • sloc: ansic: 2,382; makefile: 163; perl: 86; python: 56; sh: 21; ruby: 6
file content (152 lines) | stat: -rw-r--r-- 4,254 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
 * Ffindex
 * written by Andreas Hauser <andy@splashground.de>.
 * Please add your name here if you distribute modified versions.
 * 
 * Ffindex is provided under the Create Commons license "Attribution-ShareAlike
 * 4.0", which basically captures the spirit of the Gnu Public License (GPL).
 * 
 * See:
 * http://creativecommons.org/licenses/by-sa/4.0/
*/

#define _GNU_SOURCE 1
#define _LARGEFILE64_SOURCE 1
#define _FILE_OFFSET_BITS 64

#include <sys/types.h>
#include <sys/stat.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <unistd.h>


#include "ffindex.h"
#include "ffutil.h"

#define MAX_FILENAME_LIST_FILES 4096

void usage(char *program_name)
{
    fprintf(stderr, "USAGE: %s -s|-u [-v] [-f file]* index_filename [filename]*\n"
                    "\t-f file\tfile each line containing a filename\n"
                    "\t\t-f can be specified up to %d times\n"
                    "\t-s\tsort index file\n"
                    "\t-u\tunlink entry (remove from index only)\n"
                    "\t-v\tprint version and other info then exit\n"
                    "EXAMPLE:\n"
                    "\t%s -us foo.ffindex entry1\n"
                    "\tTo clean up the data file after unlinking insert it to an new one:\n"
                    "\tffindex_build -as cleaned.ffdata cleaned.ffindex -d foo.ffdata -i foo.ffindex\n"
                    FFINDEX_COPYRIGHT,
                    basename(program_name), MAX_FILENAME_LIST_FILES, basename(program_name));
}

int main(int argn, char **argv)
{
  int sort = 0, unlink = 0, version = 0, use_tree = 1;
  int opt, err = EXIT_SUCCESS;
  char* list_filenames[MAX_FILENAME_LIST_FILES];
  size_t list_filenames_index = 0;
  while ((opt = getopt(argn, argv, "stuvf:")) != -1)
  {
    switch (opt)
    {
      case 'f':
        list_filenames[list_filenames_index++] = optarg;
        break;
      case 's':
        sort = 1;
        break;
      case 't':
        use_tree = 1;
        break;
      case 'u':
        unlink = 1;
        break;
      case 'v':
        version = 1;
        break;
      default:
        fprintf(stderr, "Option %c not recognized\n", opt);
        usage(basename(argv[0]));
        return EXIT_FAILURE;
    }
  }

  if(version == 1)
  {
    /* Don't you dare running it on a platform where byte != 8 bits */
    printf("%s version %.2f, off_t = %zd bits\n", argv[0], FFINDEX_VERSION, sizeof(off_t) * 8);
    return EXIT_SUCCESS;
  }

  if(optind >= argn)
  {
    usage(argv[0]);
    return EXIT_FAILURE;
  }

  char *index_filename = argv[optind++];
  FILE *index_file;

  index_file = fopen(index_filename, "r+");
  if(index_file == NULL) { perror(index_filename); return EXIT_FAILURE; }

  ffindex_index_t* index = ffindex_index_parse(index_file, 0);
  if(index == NULL) { perror("ffindex_index_parse failed"); return (EXIT_FAILURE); }

  fclose(index_file);

  /* Unlink entries */
  if(unlink)
  {
    if(use_tree)
    {
      /* Build tree */
      index = ffindex_index_as_tree(index);

      /* Tree keeps index sorted */
      sort = 0;

      /* For each list_file unlink all entries */
      if(list_filenames_index > 0)
        for(int i = 0; i < list_filenames_index; i++)
        {
          printf("Unlinking entries from '%s'\n", list_filenames[i]);
          FILE *list_file = fopen(list_filenames[i], "r");
          if( list_file == NULL) { perror(list_filenames[i]); return EXIT_FAILURE; }

          /* unlink entries in file, one per line */
          char path[PATH_MAX];
          while(fgets(path, PATH_MAX, list_file) != NULL)
            index = ffindex_unlink(index, ffnchomp(path, strnlen(path, PATH_MAX)));
        }

      /* unlink entries specified by args */
      for(int i = optind; i < argn; i++)
        index = ffindex_unlink(index, argv[i]);
    }
    else
      fprintf(stderr, "unused case\n");
  }

  if(sort)
    ffindex_sort_index_file(index);

  /* Write index back */
  index_file = fopen(index_filename, "w");
  if(index_file == NULL) { perror(index_filename); return EXIT_FAILURE; }
  err = ffindex_write(index, index_file);
  if(err)
    fferror_print(__FILE__, __LINE__, __func__, index_filename);

  ffindex_index_close(index);

  return err;
}

/* vim: ts=2 sw=2 et
*/