Skip to content

Commit

Permalink
Merge pull request #5 from mach-kernel/auxtype-filename
Browse files Browse the repository at this point in the history
File type & auxtype in filename
  • Loading branch information
mach-kernel authored Feb 13, 2018
2 parents a5d01d0 + 8c24002 commit b5d413c
Show file tree
Hide file tree
Showing 5 changed files with 153 additions and 34 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ Any and all contributions are welcome. Included is also a `cadius.pro` file you

## Changelog

#### 1.3
- Adds ability to specify a file's `type` and `auxtype` via the filename, resolving [#4](https://github.com/mach-kernel/cadius/issues/4). A big thank you to @JohnMBrooks for testing this PR!
- `REPLACEFILE` command, `DELETEFILE` support for type/auxtype suffix.

#### 1.2-b3
- Fix Windows build issues, make some shared OS methods static / remove from `os.c` ([@mach-kernel](https://github.com/mach-kernel))

Expand Down
65 changes: 64 additions & 1 deletion Src/Main.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@

#define ACTION_ADD_FILE 60
#define ACTION_ADD_FOLDER 61
#define ACTION_REPLACE_FILE 62

#define ACTION_CREATE_FOLDER 70
#define ACTION_CREATE_VOLUME 71
Expand Down Expand Up @@ -77,7 +78,7 @@ int main(int argc, char *argv[])
verbose = 0;

/* Message Information */
printf("%s v 1.2-b3, (c) Brutal Deluxe 2011-2013.\n",argv[0]);
printf("%s v 1.3, (c) Brutal Deluxe 2011-2013.\n",argv[0]);

/* Vérification des paramètres */
if(argc < 3)
Expand Down Expand Up @@ -381,6 +382,35 @@ int main(int argc, char *argv[])
printf(" => File(s) : %d, Folder(s) : %d, Error(s) : %d\n",current_image->nb_add_file,current_image->nb_add_folder,current_image->nb_add_error);

/* Libération mémoire */
mem_free_image(current_image);
}
else if(param->action == ACTION_REPLACE_FILE)
{
/** Charge l'image 2mg **/
current_image = LoadProdosImage(param->image_file_path);
if(current_image == NULL)
return(3);

int fcharloc = 0;
for (int i=strlen(param->file_path); i >= 0; --i) {
if (!strncmp(&param->file_path[i], FOLDER_CHARACTER, sizeof(FOLDER_CHARACTER)))
{
fcharloc = i;
break;
}
}

// Prepare parameters for delete
char *file_name = param->file_path + fcharloc;
char *prodos_file_name = strdup(param->prodos_folder_path);
strcat(prodos_file_name, &FOLDER_CHARACTER);
strcat(prodos_file_name, file_name);

printf(" - Replacing file '%s' :\n",param->file_path);

DeleteProdosFile(current_image, prodos_file_name);
AddFile(current_image, param->file_path, param->prodos_folder_path,1);

mem_free_image(current_image);
}
else if(param->action == ACTION_CLEAR_HIGH_BIT)
Expand Down Expand Up @@ -479,6 +509,13 @@ void usage(char *program_path)
printf(" %s DELETEVOLUME <[2mg|hdv|po]_image_path>\n",program_path);
printf(" ----\n");
printf(" %s ADDFILE <[2mg|hdv|po]_image_path> <prodos_folder_path> <file_path>\n",program_path);
printf(" Specify a file's type and auxtype by formatting the file name: THING.S16#B30000\n");
printf(" Delimiter must be '#'. Also works with REPLACEFILE, DELETEFILE, etc.\n");
printf(" ----\n");
printf(" %s REPLACEFILE <[2mg|hdv|po]_image_path> <prodos_folder_path> <file_path>\n",program_path);
printf(" You may also specify a different type/auxtype for the file you intend to replace\n");
printf(" (i.e. by changing the suffix) \n");
printf(" ----\n");
printf(" %s ADDFOLDER <[2mg|hdv|po]_image_path> <prodos_folder_path> <folder_path>\n",program_path);
printf(" ----\n");
printf(" %s CREATEFOLDER <[2mg|hdv|po]_image_path> <prodos_folder_path>\n",program_path);
Expand Down Expand Up @@ -910,6 +947,32 @@ struct parameter *GetParamLine(int argc, char *argv[])
return(param);
}

/** ADDFILE <2mg_image_path> <target_folder_path> <file_path> **/
if(!my_stricmp(argv[1],"REPLACEFILE") && argc == 5)
{
param->action = ACTION_REPLACE_FILE;

/* Chemin du fichier Image */
param->image_file_path = strdup(argv[2]);

/* Chemin du dossier où copier ce fichier */
param->prodos_folder_path = strdup(argv[3]);

/* Chemin du fichier Windows */
param->file_path = strdup(argv[4]);

/* Vérification */
if(param->image_file_path == NULL || param->file_path == NULL || param->prodos_folder_path == NULL)
{
printf(" Error : Impossible to allocate memory for structure Param.\n");
mem_free_param(param);
return(NULL);
}

/* OK */
return(param);
}

/** ADDFOLDER <2mg_image_path> <target_folder_path> <folder_path> **/
if(!my_stricmp(argv[1],"ADDFOLDER") && argc == 5)
{
Expand Down
77 changes: 56 additions & 21 deletions Src/Prodos_Add.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,16 @@ static WORD CreateSeedlingContent(struct prodos_image *,struct prodos_file *,uns
static WORD CreateSaplingContent(struct prodos_image *,struct prodos_file *,unsigned char *,int,int,int);
static WORD CreateTreeContent(struct prodos_image *,struct prodos_file *,unsigned char *,int,int,int,int);

/***************************************************************/
/* AddFile() : Ajoute un fichier Windows à l'archive Prodos. */
/***************************************************************/
/**
* @brief Adds a file.
*
* @param current_image The current image
* @param file_path The file path
* @param target_folder_path The target folder path
* @param[in] update_image The update image
*
* @return { description_of_the_return_value }
*/
int AddFile(struct prodos_image *current_image, char *file_path, char *target_folder_path, int update_image)
{
int i, is_volume_header, error, is_valid;
Expand All @@ -49,8 +56,7 @@ int AddFile(struct prodos_image *current_image, char *file_path, char *target_fo

/** Charge le fichier depuis le disque **/
current_file = LoadFile(file_path);
if(current_file == NULL)
return(1);
if(current_file == NULL) return(1);

/** On vérifie si ce fichier est compatible Prodos **/
/* Nom */
Expand Down Expand Up @@ -277,9 +283,13 @@ void AddFolder(struct prodos_image *current_image, char *folder_path, char *targ
}


/********************************************************************/
/* LoadFile() : Charge un fichier depuis le disque de la machine. */
/********************************************************************/
/**
* @brief Loads a file from disk.
*
* @param file_path_data The file path data
*
* @return { description_of_the_return_value }
*/
static struct prodos_file *LoadFile(char *file_path_data)
{
int i, found;
Expand All @@ -295,26 +305,38 @@ static struct prodos_file *LoadFile(char *file_path_data)
printf(" Error : Impossible to allocate memory.\n");
return(NULL);
}
/* Extrait le répertoire du nom de fichier */

// Start from end of string until we arrive to path delimiter
strcpy(folder_path,file_path_data);
for(i=strlen(folder_path); i>=0; i--)
if(folder_path[i] == '\\' || folder_path[i] == '/')
if(!strncmp(&folder_path[i], FOLDER_CHARACTER, sizeof(FOLDER_CHARACTER)))
{
folder_path[i+1] = '\0';
break;
}

/** Extrait le nom de fichier **/
// Similarly, also extract the filename
strcpy(file_name,file_path_data);
for(i=strlen(file_path_data); i>=0; i--)
if(file_path_data[i] == '\\' || file_path_data[i] == '/')
if(!strncmp(&folder_path[i], FOLDER_CHARACTER, sizeof(FOLDER_CHARACTER)))
{
strcpy(file_name,&file_path_data[i+1]);
break;
}

// Attempt to extract ProDOS metadata from the filename
char *prodos_meta = strchr(file_name, '#');
// Skip the delim char and chop off the name string
if (prodos_meta && strlen(prodos_meta + 1) == 6)
{
*prodos_meta = '\0';
prodos_meta++;
}
else prodos_meta = NULL;

current_file->file_name = strdup(file_name);
current_file->file_name_case = strdup(file_name);
current_file->file_name_case = strdup(file_name);

if(current_file->file_name == NULL || current_file->file_name_case == NULL)
{
free(current_file);
Expand Down Expand Up @@ -360,6 +382,19 @@ static struct prodos_file *LoadFile(char *file_path_data)
/** Récupération des Propriétés Date/Time du fichier **/
os_GetFileCreationModificationDate(file_path_data,current_file);

// Override values in _FileInformation.txt if the suffix is present
if (prodos_meta)
{
char type;
WORD aux_type;

if (sscanf(prodos_meta, "%02hhX%04hX", &type, &aux_type) == 2)
{
current_file->type = type;
current_file->aux_type = aux_type;
}
}

/* Renvoie la structure */
return(current_file);
}
Expand Down Expand Up @@ -400,45 +435,45 @@ static int GetFileInformation(char *file_information_path, char *file_name, stru
GetLineValue(line_tab[i],"Type",local_buffer);
if(strlen(local_buffer) == 2)
{
sscanf(local_buffer,"%02X",&value);
sscanf(local_buffer,"%02lX",&value);
current_file->type = (unsigned char) value;
}
GetLineValue(line_tab[i],"AuxType",local_buffer);
if(strlen(local_buffer) == 4)
{
sscanf(local_buffer,"%04X",&value);
sscanf(local_buffer,"%04lX",&value);
current_file->aux_type = (WORD) value;
}
GetLineValue(line_tab[i],"VersionCreate",local_buffer);
if(strlen(local_buffer) == 2)
{
sscanf(local_buffer,"%02X",&value);
sscanf(local_buffer,"%02lX",&value);
current_file->version_create = (unsigned char) value;
}
GetLineValue(line_tab[i],"MinVersion",local_buffer);
if(strlen(local_buffer) == 2)
{
sscanf(local_buffer,"%02X",&value);
sscanf(local_buffer,"%02lX",&value);
current_file->min_version = (unsigned char) value;
}
GetLineValue(line_tab[i],"Access",local_buffer);
if(strlen(local_buffer) == 2)
{
sscanf(local_buffer,"%02X",&value);
sscanf(local_buffer,"%02lX",&value);
current_file->access = (unsigned char) value;
}
GetLineValue(line_tab[i],"FolderInfo1",local_buffer);
if(strlen(local_buffer) == 36)
for(j=0; j<18; j++)
{
sscanf(&local_buffer[2*j],"%02X",&value);
sscanf(&local_buffer[2*j],"%02lX",&value);
current_file->resource_finderinfo_1[j] = (unsigned char) value;
}
GetLineValue(line_tab[i],"FolderInfo2",local_buffer);
if(strlen(local_buffer) == 36)
for(j=0; j<18; j++)
{
sscanf(&local_buffer[2*j],"%02X",&value);
sscanf(&local_buffer[2*j],"%02lX",&value);
current_file->resource_finderinfo_2[j] = (unsigned char) value;
}

Expand Down
13 changes: 10 additions & 3 deletions Src/Prodos_Delete.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,21 @@ static int EmptyEntryFolder(struct prodos_image *,struct file_descriptive_entry
static void DeleteEmptyFolder(struct prodos_image *,struct file_descriptive_entry *);
static int compare_folder(const void *,const void *);

/***********************************************************/
/* DeleteProdosFile() : Suppression d'un fichier Prodos. */
/***********************************************************/
/**
* @brief Delete a ProDOS file
*
* @param current_image The current image
* @param prodos_file_path The prodos file path
*/
void DeleteProdosFile(struct prodos_image *current_image, char *prodos_file_path)
{
int error;
struct file_descriptive_entry *current_entry;

// If there's a type suffix, remove it before continuing
char *suffix = strchr(prodos_file_path, '#');
if (suffix && strlen(suffix + 1) == 6) *suffix = '\0';

/* Recherche l'entrée Prodos */
current_entry = GetProdosFile(current_image,prodos_file_path);
if(current_entry == NULL)
Expand Down
28 changes: 19 additions & 9 deletions Src/Prodos_Extract.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,10 +258,14 @@ void ExtractVolumeFiles(struct prodos_image *current_image, char *output_directo
free(windows_folder_path);
}


/************************************************************/
/* CreateOutputFile() : Création d'un fichier sur disque. */
/************************************************************/
/**
* Writes a file to disk
*
* @brief CreateOutputFile
* @param current_file
* @param output_directory_path
* @return
*/
static int CreateOutputFile(struct prodos_file *current_file, char *output_directory_path)
{
int error;
Expand All @@ -278,15 +282,21 @@ static int CreateOutputFile(struct prodos_file *current_file, char *output_direc
return(1);
}
strcpy(directory_path,output_directory_path);
if(strlen(directory_path) > 0)
if(directory_path[strlen(directory_path)-1] != '\\' && directory_path[strlen(directory_path)-1] != '/')
strcat(directory_path,FOLDER_CHARACTER);

/* Chemin du fichier : Data */
if(strlen(directory_path) > 0 && directory_path[strlen(directory_path)-1] != FOLDER_CHARACTER)
strcat(directory_path,FOLDER_CHARACTER);

// Data file path
strcpy(file_data_path,directory_path);
strcat(file_data_path,current_file->entry->file_name_case);

/* Chemin du fichier : Resource */
// Append the file type and auxtype extension
char extension[7];
strcat(file_data_path, "#");
sprintf(extension, "%02hhX%04hX", current_file->entry->file_type, current_file->entry->file_aux_type);
strcat(file_data_path, extension);

// ResourceFork path
strcpy(file_resource_path,file_data_path);
strcat(file_resource_path,"_ResourceFork.bin");

Expand Down

0 comments on commit b5d413c

Please sign in to comment.