4 * (c) Copyright 1997-1999,2006 by Matthew Dillon. Permission to
5 * use and distribute based on the FreeBSD copyright.
7 * $DragonFly: src/bin/cpdup/fsmid.c,v 1.3 2008/11/10 14:30:02 swildner Exp $
12 typedef struct FSMIDNode {
13 struct FSMIDNode *fid_Next;
19 static FSMIDNode *fsmid_lookup(const char *sfile);
20 static void fsmid_cache(const char *dpath, int ddirlen);
22 static char *FSMIDDCache; /* cache source directory name */
23 static FSMIDNode *FSMIDBase;
24 static int FSMIDDCacheDirLen;
25 static int FSMIDDCacheDirty;
30 if (FSMIDDCacheDirty && FSMIDDCache && NotForRealOpt == 0) {
33 if ((fo = fopen(FSMIDDCache, "w")) != NULL) {
36 for (node = FSMIDBase; node; node = node->fid_Next) {
37 if (node->fid_Accessed && node->fid_Code) {
38 fprintf(fo, "%016jx %zu %s\n",
39 (intmax_t)node->fid_Code,
40 strlen(node->fid_Name),
54 while ((node = FSMIDBase) != NULL) {
55 FSMIDBase = node->fid_Next;
67 fsmid_cache(const char *dpath, int ddirlen)
77 ddirlen == FSMIDDCacheDirLen &&
78 strncmp(dpath, FSMIDDCache, ddirlen) == 0
84 * Different cache, flush old cache
87 if (FSMIDDCache != NULL)
94 FSMIDDCacheDirLen = ddirlen;
95 FSMIDDCache = mprintf("%*.*s%s", ddirlen, ddirlen, dpath, FSMIDCacheFile);
97 if ((fi = fopen(FSMIDDCache, "r")) != NULL) {
98 FSMIDNode **pnode = &FSMIDBase;
103 FSMIDNode *node = *pnode = malloc(sizeof(FSMIDNode));
109 if (pnode == NULL || node == NULL)
110 fatal("out of memory");
112 bzero(node, sizeof(FSMIDNode));
113 node->fid_Code = strtoull(fextract(fi, -1, &c, ' '), NULL, 16);
114 node->fid_Accessed = 1;
115 if ((s = fextract(fi, -1, &c, ' ')) != NULL) {
116 nlen = strtol(s, NULL, 0);
120 * extracting fid_Name - name may contain embedded control
123 CountSourceReadBytes += nlen+1;
124 node->fid_Name = fextract(fi, nlen, &c, EOF);
126 fprintf(stderr, "Error parsing FSMID Cache: %s (%c)\n", FSMIDDCache, c);
127 while (c != EOF && c != '\n')
132 pnode = &node->fid_Next;
139 * fsmid_lookup: lookup/create fsmid entry
143 fsmid_lookup(const char *sfile)
148 for (pnode = &FSMIDBase; (node = *pnode) != NULL; pnode = &node->fid_Next) {
149 if (strcmp(sfile, node->fid_Name) == 0) {
154 if ((node = *pnode = malloc(sizeof(FSMIDNode))) == NULL)
155 fatal("out of memory");
156 bzero(node, sizeof(FSMIDNode));
157 node->fid_Name = strdup(sfile);
158 FSMIDDCacheDirty = 1;
160 node->fid_Accessed = 1;
165 * fsmid_check: check FSMID against file
167 * Return -1 if check failed
168 * Return 0 if check succeeded
170 * dpath can be NULL, in which case we are force-updating
174 fsmid_check(int64_t fsmid, const char *dpath)
180 if ((dfile = strrchr(dpath, '/')) != NULL)
184 ddirlen = dfile - dpath;
186 fsmid_cache(dpath, ddirlen);
188 node = fsmid_lookup(dfile);
190 if (node->fid_Code != fsmid) {
191 node->fid_Code = fsmid;
192 FSMIDDCacheDirty = 1;