IFFRESULT IFFParser::IFFAscendChunk(IFFCHUNK* lpck) { ULONGLONG pos; pos = SetFilePos(0, IO::STREAM_SEEK_CUR); // Current position if (lpck->flags == 0) { int32 offset = lpck->ckSize-(pos-lpck->dataOffset); if (lpck->ckSize & 1) offset++; // Word-aligned chunks /*if (*/SetFilePos(offset, IO::STREAM_SEEK_CUR);// == 0xffffffff) /* return IFFERR_READWRITE; else return IFF_OK; */ } else { uint32 cksize = pos - lpck->dataOffset; if (lpck->ckSize == 0) // Unknown size data at time of chunk creation { lpck->ckSize = cksize; cksize = BigEndian32(cksize); SetFilePos(lpck->dataOffset-4, IO::STREAM_SEEK_SET); IFFWriteChunkBytes(&cksize, 4); // Write the chunk length SetFilePos(pos, IO::STREAM_SEEK_SET); } if (cksize & 1) { uint8 padbyte = 0; IFFWriteChunkBytes(&padbyte, 1); } } return IFF_OK; }
static BOOL do_save_sites_iff(struct display_globals *dg,char *filename,LONG *diskerr) { APTR iff; BOOL ok=FALSE; struct Node *node,*next; struct site_entry *e; #ifdef __AROS__ struct site_entry *entry_be; if (!(entry_be=AllocVec(sizeof(struct site_entry),MEMF_CLEAR))) { //*diskerr = ERROR_NO_FREE_STORE; *diskerr=IoErr(); return 0; } #endif // Open IFF file if ((iff=IFFOpen(filename,IFF_WRITE|IFF_SAFE,ID_OPUS))) { LONG type; int size; ok=TRUE; // mark in case no entries in list node = dg->dg_og->og_SiteList->list.lh_Head; while ((next = node->ln_Succ)) { e=(struct site_entry*)((Att_Node *)node)->data; if (e->se_has_custom_env) { type=ID_FTPSITE_LONG; // full site so include ftp_environment size=LARGE_SIZE; } else { type=ID_FTPSITE_SHORT; // short site so exclude ftp_environment size=SMALL_SIZE; } // Write site_entry if (!(ok=IFFPushChunk(iff,type))) break; #ifdef __AROS__ CopyMem(e,entry_be,size); entry_be->se_anon = AROS_WORD2BE(entry_be->se_anon); entry_be->se_port = AROS_LONG2BE(entry_be->se_port); entry_be->se_has_custom_env = AROS_WORD2BE(entry_be->se_has_custom_env); if (size == LARGE_SIZE) { entry_be->se_env_private.e_retry_count = AROS_LONG2BE(entry_be->se_env_private.e_retry_count); entry_be->se_env_private.e_retry_delay = AROS_LONG2BE(entry_be->se_env_private.e_retry_delay); entry_be->se_env_private.e_list_update = AROS_LONG2BE(entry_be->se_env_private.e_list_update); entry_be->se_env_private.e_timeout = AROS_LONG2BE(entry_be->se_env_private.e_timeout); entry_be->se_env_private.e_script_time = AROS_LONG2BE(entry_be->se_env_private.e_script_time); entry_be->se_env_private.e_indexsize = AROS_LONG2BE(entry_be->se_env_private.e_indexsize); entry_be->se_env_private.bitfield1 = AROS_LONG2BE(entry_be->se_env_private.bitfield1); entry_be->se_env_private.bitfield2 = AROS_LONG2BE(entry_be->se_env_private.bitfield2); } if (!(ok=IFFWriteChunkBytes(iff,(char *)entry_be,size))) #else if (!(ok=IFFWriteChunkBytes(iff,(char *)e,size))) #endif break; if (!(ok=IFFPopChunk(iff))) break; node = next; } // Close file IFFClose(iff); } #ifdef __AROS__ FreeVec(entry_be); #endif if (ok) return(TRUE); *diskerr=IoErr(); return(FALSE); }
// Save an environment int environment_save(Cfg_Environment *env,char *name,short snapshot,CFG_ENVR *data) { APTR iff; long success=0; struct OpenEnvironmentData *opendata=0; #ifdef __AROS__ CFG_ENVR *env_be; #endif // Invalid name? if (!name || !*name) return 0; // Get data pointer if not supplied if (!data) data=env->env; #ifdef __AROS__ if (!(env_be=AllocVec(sizeof(CFG_ENVR),MEMF_CLEAR))) return 0; #endif // Update main window position if (snapshot&ENVSAVE_WINDOW) { GetSemaphore(&GUI->backdrop->window_lock,SEMF_SHARED,0); display_store_pos(); FreeSemaphore(&GUI->backdrop->window_lock); } // Not snapshotting listers? if (!(snapshot&ENVSAVE_LAYOUT)) { if ((opendata=AllocMemH(env->volatile_memory,sizeof(struct OpenEnvironmentData)))) { opendata->memory=env->desktop_memory; opendata->volatile_memory=env->volatile_memory; opendata->flags=OEDF_BANK|OEDF_LSTR; OpenEnvironment(name,opendata); } } // Try to open file to write while ((iff=IFFOpen(name,MODE_NEWFILE,ID_EPUS))) { IPCData *ipc; Lister *lister; Buttons *buttons; Cfg_Desktop *desk; struct MinNode *node; Cfg_SoundEntry *sound; // Write environment settings #ifdef __AROS__ CopyMem(data,env_be,sizeof(CFG_ENVR)); { int i; env_be->screen_mode = AROS_LONG2BE(env_be->screen_mode); env_be->screen_flags = AROS_WORD2BE(env_be->screen_flags); env_be->screen_depth = AROS_WORD2BE(env_be->screen_depth); env_be->screen_width = AROS_WORD2BE(env_be->screen_width); env_be->screen_height = AROS_WORD2BE(env_be->screen_height); for (i=0; i<50; i++) env_be->palette[i] = AROS_LONG2BE(env_be->palette[i]); env_be->window_pos.Left = AROS_WORD2BE(env_be->window_pos.Left); env_be->window_pos.Top = AROS_WORD2BE(env_be->window_pos.Top); env_be->window_pos.Width = AROS_WORD2BE(env_be->window_pos.Width); env_be->window_pos.Height = AROS_WORD2BE(env_be->window_pos.Height); env_be->general_screen_flags = AROS_LONG2BE(env_be->general_screen_flags); env_be->palette_count = AROS_WORD2BE(env_be->palette_count); for (i=0; i<CUST_PENS; i++) { env_be->env_Colours[i][0][0] = AROS_LONG2BE(env_be->env_Colours[i][0][0]); env_be->env_Colours[i][0][1] = AROS_LONG2BE(env_be->env_Colours[i][0][1]); env_be->env_Colours[i][0][2] = AROS_LONG2BE(env_be->env_Colours[i][0][2]); env_be->env_Colours[i][1][0] = AROS_LONG2BE(env_be->env_Colours[i][1][0]); env_be->env_Colours[i][1][1] = AROS_LONG2BE(env_be->env_Colours[i][1][1]); env_be->env_Colours[i][1][2] = AROS_LONG2BE(env_be->env_Colours[i][1][2]); } env_be->env_ColourFlag = AROS_LONG2BE(env_be->env_ColourFlag); env_be->env_NewIconsFlags = AROS_LONG2BE(env_be->env_NewIconsFlags); env_be->display_options = AROS_WORD2BE(env_be->display_options); env_be->main_window_type = AROS_WORD2BE(env_be->main_window_type); env_be->hotkey_flags = AROS_WORD2BE(env_be->hotkey_flags); env_be->hotkey_code = AROS_WORD2BE(env_be->hotkey_code); env_be->hotkey_qual = AROS_WORD2BE(env_be->hotkey_qual); env_be->default_stack = AROS_LONG2BE(env_be->default_stack); env_be->lister_options = AROS_WORD2BE(env_be->lister_options); env_be->flags = AROS_LONG2BE(env_be->flags); env_be->lister_popup_code = AROS_WORD2BE(env_be->lister_popup_code); env_be->lister_popup_qual = AROS_WORD2BE(env_be->lister_popup_qual); env_be->env_flags = AROS_LONG2BE(env_be->env_flags); env_be->clock_left = AROS_WORD2BE(env_be->clock_left); env_be->clock_top = AROS_WORD2BE(env_be->clock_top); env_be->lister_width = AROS_WORD2BE(env_be->lister_width); env_be->lister_height = AROS_WORD2BE(env_be->lister_height); env_be->version = AROS_WORD2BE(env_be->version); env_be->desktop_flags = AROS_LONG2BE(env_be->desktop_flags); for (i=0; i<4; i++) env_be->env_BackgroundFlags[i] = AROS_WORD2BE(env_be->env_BackgroundFlags[i]); env_be->settings.copy_flags = AROS_LONG2BE(env_be->settings.copy_flags); env_be->settings.delete_flags = AROS_LONG2BE(env_be->settings.delete_flags); env_be->settings.error_flags = AROS_LONG2BE(env_be->settings.error_flags); env_be->settings.general_flags = AROS_LONG2BE(env_be->settings.general_flags); env_be->settings.icon_flags = AROS_LONG2BE(env_be->settings.icon_flags); env_be->settings.replace_method = AROS_WORD2BE(env_be->settings.replace_method); env_be->settings.replace_flags = AROS_WORD2BE(env_be->settings.replace_flags); env_be->settings.update_flags = AROS_LONG2BE(env_be->settings.update_flags); env_be->settings.dir_flags = AROS_LONG2BE(env_be->settings.dir_flags); env_be->settings.view_flags = AROS_LONG2BE(env_be->settings.view_flags); env_be->settings.max_buffer_count = AROS_WORD2BE(env_be->settings.max_buffer_count); env_be->settings.date_format = AROS_WORD2BE(env_be->settings.date_format); env_be->settings.date_flags = AROS_WORD2BE(env_be->settings.date_flags); env_be->settings.pop_code = AROS_WORD2BE(env_be->settings.pop_code); env_be->settings.pop_qual = AROS_WORD2BE(env_be->settings.pop_qual); env_be->settings.pop_qual_mask = AROS_WORD2BE(env_be->settings.pop_qual_mask); env_be->settings.pop_qual_same = AROS_WORD2BE(env_be->settings.pop_qual_same); env_be->settings.popup_delay = AROS_WORD2BE(env_be->settings.popup_delay); env_be->settings.max_openwith = AROS_WORD2BE(env_be->settings.max_openwith); env_be->settings.command_line_length = AROS_WORD2BE(env_be->settings.command_line_length); env_be->settings.max_filename = AROS_WORD2BE(env_be->settings.max_filename); env_be->settings.flags = AROS_LONG2BE(env_be->settings.flags); for (i=0; i<4; i++) env_be->env_BackgroundBorderColour[i] = AROS_LONG2BE(env_be->env_BackgroundBorderColour[i]); } if (!(IFFWriteChunk(iff,env_be,ID_ENVR,sizeof(CFG_ENVR)))) #else if (!(IFFWriteChunk(iff,data,ID_ENVR,sizeof(CFG_ENVR)))) #endif { success=IoErr(); break; } // Write some path names if ((success=write_env_string(iff,env->toolbar_path,ID_TBAR)) || (success=write_env_string(iff,env->menu_path,ID_LMEN)) || (success=write_env_string(iff,env->user_menu_path,ID_UMEN)) || (success=write_env_string(iff,env->scripts_path,ID_SCRP)) || (success=write_env_string(iff,env->hotkeys_path,ID_HKEY))) break; // Not snapshotting? if (!(snapshot&ENVSAVE_LAYOUT) && opendata) { ButtonBankNode *button; OpenListerNode *lister; // Go through existing listers for (lister=(OpenListerNode *)opendata->listers.mlh_Head; lister->node.ln_Succ;) { OpenListerNode *next=(OpenListerNode *)lister->node.ln_Succ; // Write lister data if (!(SaveListerDef(iff,(Cfg_Lister *)lister->lister))) break; // Remove this node, get next Remove((struct Node *)lister); lister=next; } // Go through buttons to open for (button=(ButtonBankNode *)opendata->buttons.mlh_Head; button->node.ln_Succ;) { ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ; ULONG pad[5]; #ifdef __AROS__ struct IBox pos_be; #endif // Write bank header if (!(IFFPushChunk(iff,ID_BANK))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=button->icon_pos_x; pad[3]=button->icon_pos_y; pad[4]=button->flags&BUTTONF_ICONIFIED; #ifdef __AROS__ CopyMem(&button->pos,&pos_be,sizeof(struct IBox)); pos_be.Left = AROS_WORD2BE(pos_be.Left); pos_be.Top = AROS_WORD2BE(pos_be.Top); pos_be.Width = AROS_WORD2BE(pos_be.Width); pos_be.Height = AROS_WORD2BE(pos_be.Height); pad[2] = AROS_LONG2BE(pad[2]); pad[3] = AROS_LONG2BE(pad[3]); pad[4] = AROS_LONG2BE(pad[4]); if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #else // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&button->pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #endif // Remove this node, get next Remove((struct Node *)button); button=next; } // Go through StartMenus to open for (button=(ButtonBankNode *)opendata->startmenus.mlh_Head; button->node.ln_Succ;) { ButtonBankNode *next=(ButtonBankNode *)button->node.ln_Succ; ULONG pad[5]; #ifdef __AROS__ struct IBox pos_be; #endif // Write bank header if (!(IFFPushChunk(iff,ID_STRT))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=button->icon_pos_x; pad[3]=button->icon_pos_y; pad[4]=button->flags; #ifdef __AROS__ CopyMem(&button->pos,&pos_be,sizeof(struct IBox)); pos_be.Left = AROS_WORD2BE(pos_be.Left); pos_be.Top = AROS_WORD2BE(pos_be.Top); pos_be.Width = AROS_WORD2BE(pos_be.Width); pos_be.Height = AROS_WORD2BE(pos_be.Height); pad[2] = AROS_LONG2BE(pad[2]); pad[3] = AROS_LONG2BE(pad[3]); pad[4] = AROS_LONG2BE(pad[4]); if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #else // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&button->pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,button->node.ln_Name,strlen(button->node.ln_Name)+1)) || !(IFFPopChunk(iff))) break; #endif // Remove this node, get next Remove((struct Node *)button); button=next; } } // Otherwise, snapshotting current layout else { // Lock lister list lock_listlock(&GUI->lister_list,FALSE); // Write lister definitions for (ipc=(IPCData *)GUI->lister_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { // Get lister lister=IPCDATA(ipc); // Valid lister definition? if (lister->lister) { // Update lister lister_update(lister); // Write lister data if (!(SaveListerDef(iff,lister->lister))) break; } } // Unlock lister list unlock_listlock(&GUI->lister_list); // Fail? if (ipc->node.mln_Succ) { success=IoErr(); break; } // Lock buttons list lock_listlock(&GUI->buttons_list,FALSE); // Write button file paths for (ipc=(IPCData *)GUI->buttons_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { // Get buttons pointer buttons=IPCDATA(ipc); // Valid button configuration? if (buttons->bank && buttons->bank->path[0]) { ULONG pad[5]; #ifdef __AROS__ struct IBox pos_be; #endif // Update buttons buttons_update(buttons); // Write bank header if (!(IFFPushChunk(iff,ID_BANK))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=buttons->icon_pos_x; pad[3]=buttons->icon_pos_y; pad[4]=buttons->flags&BUTTONF_ICONIFIED; #ifdef __AROS__ CopyMem(&buttons->pos,&pos_be,sizeof(struct IBox)); pos_be.Left = AROS_WORD2BE(pos_be.Left); pos_be.Top = AROS_WORD2BE(pos_be.Top); pos_be.Width = AROS_WORD2BE(pos_be.Width); pos_be.Height = AROS_WORD2BE(pos_be.Height); pad[2] = AROS_LONG2BE(pad[2]); pad[3] = AROS_LONG2BE(pad[3]); pad[4] = AROS_LONG2BE(pad[4]); if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos_be,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,buttons->bank->path,strlen(buttons->bank->path)+1)) || !(IFFPopChunk(iff))) break; #else // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&buttons->pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,buttons->bank->path,strlen(buttons->bank->path)+1)) || !(IFFPopChunk(iff))) break; #endif } } // Unlock buttons list unlock_listlock(&GUI->buttons_list); // Fail? if (ipc->node.mln_Succ) { success=IoErr(); break; } // Lock StartMenu list lock_listlock(&GUI->startmenu_list,FALSE); // Write StartMenu paths for (ipc=(IPCData *)GUI->startmenu_list.list.lh_Head; ipc->node.mln_Succ; ipc=(IPCData *)ipc->node.mln_Succ) { StartMenu *menu; // Get menu pointer menu=(StartMenu *)IPCDATA(ipc); // Lock the bank GetSemaphore(&menu->lock,SEMF_SHARED,0); // Valid configuration? if (menu->bank && menu->bank->path[0]) { ULONG pad[5]; struct IBox pos; // Get position pos.Left=menu->bank->window.pos.Left; pos.Top=menu->bank->window.pos.Top; #ifdef __AROS__ pos.Left = AROS_WORD2BE(pos.Left); pos.Top = AROS_WORD2BE(pos.Top); #endif // Write menu header if (!(IFFPushChunk(iff,ID_STRT))) break; // Fill out padding pad[0]=0; pad[1]=0; pad[2]=0; pad[3]=0; pad[4]=0; // Write padding and position and path if (!(IFFWriteChunkBytes(iff,pad,sizeof(pad))) || !(IFFWriteChunkBytes(iff,&pos,sizeof(struct IBox))) || !(IFFWriteChunkBytes(iff,menu->bank->path,strlen(menu->bank->path)+1)) || !(IFFPopChunk(iff))) break; } // Unlock bank FreeSemaphore(&menu->lock); } // Unlock startmenu list unlock_listlock(&GUI->startmenu_list); // Fail? if (ipc->node.mln_Succ) success=IoErr(); } // Failed? if (success) break; // Go through desktop list for (desk=(Cfg_Desktop *)env->desktop.mlh_Head; desk->node.mln_Succ; desk=(Cfg_Desktop *)desk->node.mln_Succ) { #ifdef __AROS__ char buffer[64]; // 12 bytes CFG_DESK + 34 bytes device name + 18 bytes extra CFG_DESK *desk_be = (CFG_DESK *)buffer; CopyMem(&desk->data,desk_be,desk->data.dt_Size); desk_be->dt_Type = AROS_WORD2BE(desk_be->dt_Type); desk_be->dt_Size = AROS_WORD2BE(desk_be->dt_Size); desk_be->dt_Flags = AROS_LONG2BE(desk_be->dt_Flags); if (desk->data.dt_Type != DESKTOP_HIDE_BAD && desk->data.dt_Type != DESKTOP_HIDE) desk_be->dt_Data = AROS_LONG2BE(desk_be->dt_Data); if (!(IFFWriteChunk(iff,desk_be,ID_DESK,desk->data.dt_Size))) #else // Write chunk if (!(IFFWriteChunk(iff,&desk->data,ID_DESK,desk->data.dt_Size))) #endif { success=IoErr(); break; } } // Go through pathlist for (node=env->path_list.mlh_Head;node->mln_Succ;node=node->mln_Succ) { // Write chunk if (!(IFFWriteChunk(iff,(char *)(node+1),ID_PATH,strlen((char *)(node+1))))) { success=IoErr(); break; } } // Go through sound list for (sound=(Cfg_SoundEntry *)env->sound_list.mlh_Head;sound->dse_Node.ln_Succ;sound=(Cfg_SoundEntry *)sound->dse_Node.ln_Succ) { #ifdef __AROS__ Cfg_SoundEntry sound_be; CopyMem(&sound,&sound_be,sizeof(Cfg_SoundEntry)); sound_be.dse_Volume = AROS_WORD2BE(sound_be.dse_Volume); sound_be.dse_Flags = AROS_WORD2BE(sound_be.dse_Flags); if (!(IFFWriteChunk(iff,sound_be.dse_Name,ID_SNDX,32+2+2+strlen(sound->dse_Sound)+1))) #else // Write chunk if (!(IFFWriteChunk(iff,sound->dse_Name,ID_SNDX,32+2+2+strlen(sound->dse_Sound)+1))) #endif { success=IoErr(); break; } } break; } // Close file if (!iff) success=IoErr(); else IFFClose(iff); #ifdef __AROS__ FreeVec(env_be); #endif // Write icon if successful (and enabled) if ((!success) && (GUI->flags&GUIF_SAVE_ICONS)) { WriteFileIcon("dopus5:icons/Environment",name); } // Free stuff FreeMemH(opendata); ClearMemHandle(env->volatile_memory); return success; }