tar: Handle archives with the prefix field
Also, handle names and prefixes that fill the entire field (and have no NUL byte) by using a precision specifier.
This commit is contained in:
		
							
								
								
									
										8
									
								
								tar.c
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								tar.c
									
									
									
									
									
								
							@@ -27,6 +27,7 @@ struct Header {
 | 
				
			|||||||
	char gname[32];
 | 
						char gname[32];
 | 
				
			||||||
	char major[8];
 | 
						char major[8];
 | 
				
			||||||
	char minor[8];
 | 
						char minor[8];
 | 
				
			||||||
 | 
						char prefix[155];
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
enum {
 | 
					enum {
 | 
				
			||||||
@@ -298,11 +299,14 @@ c(const char * path)
 | 
				
			|||||||
static void
 | 
					static void
 | 
				
			||||||
xt(int (*fn)(char*, int, char[Blksiz]))
 | 
					xt(int (*fn)(char*, int, char[Blksiz]))
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	char b[Blksiz], fname[101];
 | 
						char b[Blksiz], fname[257], *s;
 | 
				
			||||||
	Header *h = (void*)b;
 | 
						Header *h = (void*)b;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	while(fread(b, Blksiz, 1, tarfile) && h->name[0] != '\0') {
 | 
						while(fread(b, Blksiz, 1, tarfile) && h->name[0] != '\0') {
 | 
				
			||||||
		snprintf(fname, sizeof fname, "%s", h->name);
 | 
							s = fname;
 | 
				
			||||||
 | 
							if (h->prefix[0] != '\0')
 | 
				
			||||||
 | 
								s += sprintf(s, "%.*s/", (int)sizeof h->prefix, h->prefix);
 | 
				
			||||||
 | 
							sprintf(s, "%.*s", (int)sizeof h->name, h->name);
 | 
				
			||||||
		fn(fname, strtol(h->size, 0, 8), b);
 | 
							fn(fname, strtol(h->size, 0, 8), b);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user