Diff

Differences From Artifact [7c511aec25]:

To Artifact [3e9adabf49]:


   139    139   	unsigned long long inode;
   140    140   	union {
   141    141   		struct {
   142    142   			int childcount;
   143    143   		} dir;
   144    144   		struct {
   145    145   			int executable;
          146  +			int suid;
          147  +			int worldaccessible;
   146    148   			off_t size;
   147    149   		} file;
   148    150   		struct {
   149    151   			off_t size;
   150    152   			char source[256];
   151    153   		} symlink;
   152    154   	} typeinfo;
................................................................................
   808    810   	return;
   809    811   }
   810    812   
   811    813   /* Get information about a path, and optionally list children */
   812    814   static int appfs_get_path_info(const char *path, struct appfs_pathinfo *pathinfo) {
   813    815   	Tcl_Interp *interp;
   814    816   	Tcl_Obj *attrs_dict, *attr_value;
   815         -	const char *attr_value_str;
          817  +	const char *attr_value_str, *attr_value_str_i;
   816    818   	Tcl_WideInt attr_value_wide;
   817    819   	int attr_value_int;
   818    820   	static __thread Tcl_Obj *attr_key_type = NULL, *attr_key_perms = NULL, *attr_key_size = NULL, *attr_key_time = NULL, *attr_key_source = NULL, *attr_key_childcount = NULL, *attr_key_packaged = NULL;
   819    821   	int cache_ret;
   820    822   	int tcl_ret;
   821    823   	int retval;
   822    824   	uid_t fsuid;
................................................................................
   930    932   				}
   931    933   
   932    934   				break;
   933    935   			case 'f': /* file */
   934    936   				pathinfo->type = APPFS_PATHTYPE_FILE;
   935    937   				pathinfo->typeinfo.file.size = 0;
   936    938   				pathinfo->typeinfo.file.executable = 0;
          939  +				pathinfo->typeinfo.file.suid = 0;
          940  +				pathinfo->typeinfo.file.worldaccessible = 0;
   937    941   
   938    942   				Tcl_DictObjGet(interp, attrs_dict, attr_key_size, &attr_value);
   939    943   				if (attr_value != NULL) {
   940    944   					tcl_ret = Tcl_GetWideIntFromObj(NULL, attr_value, &attr_value_wide);
   941    945   					if (tcl_ret == TCL_OK) {
   942    946   						pathinfo->typeinfo.file.size = attr_value_wide;
   943    947   					}
   944    948   				}
   945    949   
   946    950   				Tcl_DictObjGet(interp, attrs_dict, attr_key_perms, &attr_value);
   947    951   				if (attr_value != NULL) {
   948    952   					attr_value_str = Tcl_GetString(attr_value);
   949         -					if (attr_value_str[0] == 'x') {
   950         -						pathinfo->typeinfo.file.executable = 1;
          953  +					for (attr_value_str_i = &attr_value_str[0]; *attr_value_str_i != '\0'; attr_value_str_i++) {
          954  +						switch (*attr_value_str_i) {
          955  +							case 'x':
          956  +								pathinfo->typeinfo.file.executable = 1;
          957  +
          958  +								break;
          959  +							case 'U':
          960  +								pathinfo->typeinfo.file.suid = 1;
          961  +
          962  +								break;
          963  +							case '-':
          964  +								pathinfo->typeinfo.file.worldaccessible = 1;
          965  +
          966  +								break;
          967  +						}
   951    968   					}
   952    969   				}
   953    970   				break;
   954    971   			case 's': /* symlink */
   955    972   				pathinfo->type = APPFS_PATHTYPE_SYMLINK;
   956    973   				pathinfo->typeinfo.symlink.size = 0;
   957    974   				pathinfo->typeinfo.symlink.source[0] = '\0';
................................................................................
  1180   1197   			break;
  1181   1198   		case APPFS_PATHTYPE_FILE:
  1182   1199   			if (pathinfo.typeinfo.file.executable) {
  1183   1200   				stbuf->st_mode = S_IFREG | 0555;
  1184   1201   			} else {
  1185   1202   				stbuf->st_mode = S_IFREG | 0444;
  1186   1203   			}
         1204  +
         1205  +			if (pathinfo.typeinfo.file.suid) {
         1206  +				stbuf->st_mode = S_IFREG | 04000;
         1207  +			}
         1208  +
         1209  +			if (pathinfo.typeinfo.file.worldaccessible) {
         1210  +				stbuf->st_mode &= ~077;
         1211  +			}
  1187   1212   
  1188   1213   			stbuf->st_nlink = 1;
  1189   1214   			stbuf->st_size = pathinfo.typeinfo.file.size;
         1215  +
  1190   1216   			break;
  1191   1217   		case APPFS_PATHTYPE_SYMLINK:
  1192   1218   			stbuf->st_mode = S_IFLNK | 0555;
  1193   1219   			stbuf->st_nlink = 1;
  1194   1220   			stbuf->st_size = pathinfo.typeinfo.symlink.size;
  1195   1221   			break;
  1196   1222   		case APPFS_PATHTYPE_SOCKET: