Diff

Differences From Artifact [7ee6ccc5a2]:

To Artifact [45ff02ebc8]:


    44     44   	char name[256];
    45     45   };
    46     46   
    47     47   struct appfs_pathinfo {
    48     48   	appfs_pathtype_t type;
    49     49   	time_t time;
    50     50   	char hostname[256];
           51  +	unsigned long long inode;
    51     52   	union {
    52     53   		struct {
    53     54   			int childcount;
    54     55   		} dir;
    55     56   		struct {
    56     57   			int executable;
    57     58   			off_t size;
................................................................................
   271    272   	APPFS_DEBUG("SQL: %s", sql);
   272    273   	sqlite_ret = sqlite3_exec(globalThread.db, sql, appfs_getchildren_cb, &head, NULL);
   273    274   	sqlite3_free(sql);
   274    275   
   275    276   	if (sqlite_ret != SQLITE_OK) {
   276    277   		APPFS_DEBUG("Call to sqlite3_exec failed.");
   277    278   
          279  +		appfs_free_list_children(head);
          280  +
   278    281   		return(NULL);
   279    282   	}
   280    283   
   281    284   	if (head != NULL) {
   282    285   		*children_count_p = head->counter + 1;
   283    286   	}
   284    287   
................................................................................
   398    401   	}
   399    402   
   400    403   	return(retval);
   401    404   }
   402    405   
   403    406   static int appfs_getfileinfo_cb(void *_pathinfo, int columns, char **values, char **names) {
   404    407   	struct appfs_pathinfo *pathinfo = _pathinfo;
   405         -	const char *type, *time, *source, *size, *perms, *sha1;
          408  +	const char *type, *time, *source, *size, *perms, *sha1, *rowid;
   406    409   
   407    410   	type = values[0];
   408    411   	time = values[1];
   409    412   	source = values[2];
   410    413   	size = values[3];
   411    414   	perms = values[4];
   412    415   	sha1 = values[5];
          416  +	rowid = values[6];
   413    417   
   414    418   	pathinfo->time = strtoull(time, NULL, 10);
          419  +
          420  +	/* Package file inodes start at 2^32, fake inodes are before then */
          421  +	pathinfo->inode = strtoull(rowid, NULL, 10) + 4294967296ULL;
   415    422   
   416    423   	if (strcmp(type, "file") == 0) {
   417    424   		pathinfo->type = APPFS_PATHTYPE_FILE;
   418    425   
   419    426   		if (!size) {
   420    427   			size = "0";
   421    428   		}
................................................................................
   486    493   		file = path;
   487    494   		directory = "";
   488    495   	} else {
   489    496   		*file = '\0';
   490    497   		file++;
   491    498   	}
   492    499   
   493         -	sql = sqlite3_mprintf("SELECT type, time, source, size, perms, file_sha1 FROM files WHERE package_sha1 = %Q AND file_directory = %Q AND file_name = %Q;", package_hash, directory, file);
          500  +	sql = sqlite3_mprintf("SELECT type, time, source, size, perms, file_sha1, rowid FROM files WHERE package_sha1 = %Q AND file_directory = %Q AND file_name = %Q;", package_hash, directory, file);
   494    501   	if (sql == NULL) {
   495    502   		APPFS_DEBUG("Call to sqlite3_mprintf failed.");
   496    503   
   497    504   		free(path);
   498    505   
   499    506   		return(-EIO);
   500    507   	}
................................................................................
   561    568   		snprintf(new_child->name, sizeof(new_child->name), "%s", name);
   562    569   
   563    570   		*children = new_child;
   564    571   	}
   565    572   
   566    573   	return(0);
   567    574   }
          575  +
          576  +/* Generate an inode for a given path */
          577  +static long long appfs_get_path_inode(const char *path) {
          578  +	long long retval;
          579  +	const char *p;
          580  +
          581  +	retval = 10;
          582  +
          583  +	for (p = path; *p; p++) {
          584  +		retval %= 4290960290ULL;
          585  +		retval += *p;
          586  +		retval <<= 7;
          587  +	}
          588  +
          589  +	retval += 10;
          590  +	retval %= 4294967296ULL;
          591  +
          592  +	return(retval);
          593  +}
   568    594   
   569    595   /* Get information about a path, and optionally list children */
   570    596   static int appfs_get_path_info(const char *_path, struct appfs_pathinfo *pathinfo, struct appfs_children **children) {
   571    597   	struct appfs_children *dir_children;
   572    598   	char *hostname, *packagename, *os_cpuArch, *os, *cpuArch, *version;
   573    599   	char *path, *path_s;
   574    600   	char *package_hash;
................................................................................
   587    613   	if (_path[0] != '/') {
   588    614   		return(-ENOENT);
   589    615   	}
   590    616   
   591    617   	if (_path[1] == '\0') {
   592    618   		/* Request for the root directory */
   593    619   		pathinfo->hostname[0] = '\0';
          620  +		pathinfo->inode = 1;
   594    621   
   595    622   		sql = sqlite3_mprintf("SELECT DISTINCT hostname FROM packages;");
   596    623   
   597    624   		retval = appfs_get_path_info_sql(sql, 1, NULL, pathinfo, children);
   598    625   
   599    626   		/* The root directory always exists, even if it has no subordinates */
   600    627   		if (retval != 0) {
................................................................................
   606    633   		}
   607    634   
   608    635   		return(retval);
   609    636   	}
   610    637   
   611    638   	path = strdup(_path);
   612    639   	path_s = path;
          640  +
          641  +	pathinfo->inode = appfs_get_path_inode(path);
   613    642   
   614    643   	hostname = path + 1;
   615    644   	packagename = strchr(hostname, '/');
   616    645   
   617    646   	if (packagename != NULL) {
   618    647   		*packagename = '\0';
   619    648   		packagename++;
................................................................................
   737    766   
   738    767   		if (dir_children != NULL) {
   739    768   			pathinfo->typeinfo.dir.childcount = files_count;
   740    769   		}
   741    770   
   742    771   		if (children) {
   743    772   			*children = dir_children;
          773  +		} else {
          774  +			appfs_free_list_children(dir_children);
   744    775   		}
   745    776   	}
   746    777   
   747    778   	free(path_s);
   748    779   
   749    780   	return(0);
   750    781   }
................................................................................
   789    820   	}
   790    821   
   791    822   	memset(stbuf, 0, sizeof(struct stat));
   792    823   
   793    824   	stbuf->st_mtime = pathinfo.time;
   794    825   	stbuf->st_ctime = pathinfo.time;
   795    826   	stbuf->st_atime = pathinfo.time;
          827  +	stbuf->st_ino   = pathinfo.inode;
   796    828   
   797    829   	switch (pathinfo.type) {
   798    830   		case APPFS_PATHTYPE_DIRECTORY:
   799    831   			stbuf->st_mode = S_IFDIR | 0555;
   800    832   			stbuf->st_nlink = 2 + pathinfo.typeinfo.dir.childcount;
   801    833   			break;
   802    834   		case APPFS_PATHTYPE_FILE: