/* //////////////////////////////////////////////////////////////////////////// //////////// Choose disk image for given slot number? //////////////////// ///////////////////////////////////////////////////////////////////////////////////////// //// Adapted for linapple - apple][ emulator for Linux by beom beotiger Nov 2007 ///// /////////////////////////////////////////////////////////////////////////////////////// // Original source from one of Brain Games (http://www.braingames.getput.com) // game Super Transball 2.(http://www.braingames.getput.com/stransball2/default.asp) // // Brain Games crew creates brilliant retro-remakes! Please visit their site to find out more. // */ /* March 2012 AD by Krez, Beom Beotiger */ #include "stdafx.h" # include #include #ifndef _WIN32 //#include #include //#include #endif #include #include "list.h" #include "DiskFTP.h" #include "ftpparse.h" // how many file names we are able to see at once! #define FILES_IN_SCREEN 21 // delay after key pressed (in milliseconds??) #define KEY_DELAY 25 // define time when cache ftp dir.listing must be refreshed #define RENEW_TIME 24*3600 char * md5str (const char *input); // forward declaration of md5str func TCHAR g_sFTPDirListing[512] = TEXT("cache/ftp."); // name for FTP-directory listing //////////////////////////////////////////////////////////////////////////////////////// int getstatFTP(struct ftpparse *fp, int * size) { // gets file status and returns: 0 - special or error, 1 - file is a directory, 2 - file is a normal file // In: fp - ftpparse struct ftom ftpparse.h if(!fp->namelen) return 0; if(fp->flagtrycwd == 1) return 1; // can CWD, it is dir then if(fp->flagtryretr == 1) { // we're able to RETR, it's a file then?! if(size != NULL) *size = (int)(fp->size / 1024); return 2; } return 0; } //////////////////////////////////////////////////////////////////////////////////////// bool ChooseAnImageFTP(int sx,int sy, char *ftp_dir, int slot, char **filename, bool *isdir, int *index_file) { /* Parameters: sx, sy - window size, ftp_dir - what FTP directory to use, slot - in what slot should an image go (common: #6 for 5.25' 140Kb floppy disks, and #7 for hard-disks). slot #5 - for 800Kb floppy disks, but we do not use them in Apple][? (They are as a rule with .2mg extension) index_file - from which file we should start cursor (should be static and 0 when changing dir) Out: filename - chosen file name (or dir name) isdir - if chosen name is a directory */ double facx = double(g_ScreenWidth) / double(SCREEN_WIDTH); double facy = double(g_ScreenHeight) / double(SCREEN_HEIGHT); SDL_Surface *my_screen; // for background struct ftpparse FTP_PARSE; // for parsing ftp directories #ifndef _WIN32 struct stat info; #endif if(font_sfc == NULL) if(!fonts_initialization()) return false; //if we don't have a fonts, we just can do none char tmpstr[512]; char ftpdirpath [MAX_PATH]; snprintf(ftpdirpath, MAX_PATH, "%s/%s%s", g_sFTPLocalDir, g_sFTPDirListing, md5str(ftp_dir)); // get path for FTP dir listing // printf("Dir: %s, MD5(dir)=%s\n",ftp_dir,ftpdirpath); List files; // our files List sizes; // and their sizes (or 'dir' for directories) int act_file; // current file int first_file; // from which we output files char ch = 0; // prepare screen SDL_Surface *tempSurface; if(!g_WindowResized) { if(g_nAppMode == MODE_LOGO) tempSurface = g_hLogoBitmap; // use logobitmap else tempSurface = g_hDeviceBitmap; } else tempSurface = g_origscreen; my_screen = SDL_CreateRGBSurface(SDL_SWSURFACE, tempSurface->w, tempSurface->h, tempSurface->format->BitsPerPixel, 0, 0, 0, 0); if(tempSurface->format->palette && my_screen->format->palette) SDL_SetColors(my_screen, tempSurface->format->palette->colors, 0, tempSurface->format->palette->ncolors); surface_fader(my_screen, 0.2F, 0.2F, 0.2F, -1, 0); // fade it out to 20% of normal SDL_BlitSurface(tempSurface, NULL, my_screen, NULL); SDL_BlitSurface(my_screen, NULL, screen, NULL); // show background // ch = 0; #define NORMAL_LENGTH 60 if(strlen(ftp_dir) > NORMAL_LENGTH) { ch = ftp_dir[NORMAL_LENGTH]; ftp_dir[NORMAL_LENGTH] = 0;} //cut-off too long string font_print_centered(sx/2 ,5 * facy , ftp_dir, screen, 1.5 * facx, 1.3 * facy); if(ch) ftp_dir[NORMAL_LENGTH] = ch; //restore cut-off char font_print_centered(sx/2,20 * facy, "Connecting to FTP server... Please wait.", screen, 1 * facx, 1 * facy); SDL_Flip(screen); // show the screen bool OKI; #ifndef _WIN32 if(stat(ftpdirpath,&info) == 0 && info.st_mtime > time(NULL) - RENEW_TIME) { OKI = false; // use this file } else { OKI = ftp_get(ftp_dir, ftpdirpath); // get ftp dir listing } #else // in WIN32 let's use constant caching? -- need to be redone using file.mtime if(GetFileAttributes(ftpdirpath) != DWORD(-1)) OKI = false; else OKI = ftp_get(ftp_dir,ftpdirpath); // get ftp dir listing #endif if(OKI) { // error printf("Failed getting FTP directory %s to %s\n",ftp_dir,ftpdirpath); font_print_centered(sx/2,30 * facy, "Failure. Press any key!",screen, 1.4 * facx, 1.1 * facy); SDL_Flip(screen); // show the screen SDL_Delay(KEY_DELAY); // wait some time to be not too fast ////////////////////////////////// // Wait for keypress ////////////////////////////////// SDL_Event event; // event Uint8 *keyboard; // key state event.type = SDL_QUIT; while(event.type != SDL_KEYDOWN) { // wait for key pressed SDL_Delay(100); SDL_PollEvent(&event); } SDL_FreeSurface(my_screen); return false; } FILE *fdir = fopen(ftpdirpath,"r"); char *tmp; int i,j, B, N; // for cycles, beginning and end of list // build prev dir if(strcmp(ftp_dir, "ftp://")) { tmp = new char[3]; strcpy(tmp, ".."); files.Add(tmp); tmp = new char[5]; strcpy(tmp, ""); sizes.Add(tmp); // add sign of directory B = 1; } else B = 0; // for sorting dirs while (tmp = fgets(tmpstr,512,fdir)) // first looking for directories { // clear and then try to fill in FTP_PARSE struct memset(&FTP_PARSE,0,sizeof(FTP_PARSE)); ftpparse(&FTP_PARSE, tmp, strlen(tmp)); int what = getstatFTP(&FTP_PARSE, NULL); if (strlen(FTP_PARSE.name) > 0 && what == 1) // is directory! { tmp = new char[strlen(FTP_PARSE.name)+1]; // add entity to list strcpy(tmp, FTP_PARSE.name); files.Add(tmp); tmp = new char[6]; strcpy(tmp, ""); sizes.Add(tmp); // add sign of directory } /* if */ } // sort directories. Please, don't laugh at my bubble sorting - it the simplest thing I've ever seen --bb if(files.Length() > 2) { N = files.Length() - 1; // B = 1; - defined above for(i = N; i > B; i--) for(j = B; j < i; j++) if(strcasecmp(files[j], files[j + 1]) > 0) { files.Swap(j,j + 1); sizes.Swap(j,j + 1); } } B = files.Length(); // start for files (void) rewind (fdir); // to the start // now get all regular files while (tmp = fgets(tmpstr,512,fdir)) { int fsize; // clear and then try to fill in FTP_PARSE struct memset(&FTP_PARSE,0,sizeof(FTP_PARSE)); ftpparse(&FTP_PARSE, tmp, strlen(tmp)); if ((getstatFTP(&FTP_PARSE, &fsize) == 2)) // is normal file! { tmp = new char[strlen(FTP_PARSE.name)+1]; // add this entity to list strcpy(tmp, FTP_PARSE.name); files.Add(tmp); tmp = new char[10]; // 1400000KB snprintf(tmp, 9, "%dKB", fsize); sizes.Add(tmp); // add this size to list } /* if */ } (void) fclose (fdir); // do sorting for files if(files.Length() > 2 && B < files.Length()) { N = files.Length() - 1; // B = 1; for(i = N; i > B; i--) for(j = B; j < i; j++) if(strcasecmp(files[j], files[j + 1]) > 0) { files.Swap(j,j + 1); sizes.Swap(j,j + 1); } } // Count out cursor position and file number output act_file = *index_file; if(act_file >= files.Length()) act_file = 0; // cannot be more than files in list first_file = act_file - (FILES_IN_SCREEN / 2); if (first_file < 0) first_file = 0; // cannot be negativ... // Show all directories (first) and files then // char *tmp; char *siz; // int i; while(true) { SDL_BlitSurface(my_screen, NULL, screen, NULL); // show background font_print_centered(sx/2 ,5 * facy , ftp_dir, screen, 1.5 * facx, 1.3 * facy); if (slot == 6) font_print_centered(sx/2,20 * facy,"Choose image for floppy 140KB drive", screen, 1 * facx, 1 * facy); else if (slot == 7) font_print_centered(sx/2,20 * facy,"Choose image for Hard Disk", screen, 1 * facx, 1 * facy); else if (slot == 5) font_print_centered(sx/2,20 * facy,"Choose image for floppy 800KB drive", screen, 1 * facx, 1 * facy); else if (slot == 1) font_print_centered(sx/2,20 * facy,"Select file name for saving snapshot", screen, 1 * facx, 1 * facy); else if (slot == 0) font_print_centered(sx/2,20 * facy,"Select snapshot file name for loading", screen, 1 * facx, 1 * facy); font_print_centered(sx/2,30 * facy, "Press ENTER to choose, or ESC to cancel",screen, 1.4 * facx, 1.1 * facy); files.Rewind(); // from start sizes.Rewind(); i = 0; // printf("We've printed some messages, go to file list!\n"); // show all fetched dirs and files // topX of first fiel visible int TOPX = 45 * facy; while(files.Iterate(tmp)) { sizes.Iterate(siz); // also fetch size string if (i >= first_file && i < first_file + FILES_IN_SCREEN) { // FILES_IN_SCREEN items on screen // char tmp2[80],tmp3[256]; if (i == act_file) { // show item under cursor (in inverse mode) SDL_Rect r; r.x= 2; r.y= TOPX + (i-first_file) * 15 * facy - 1; if(strlen(tmp) > 46) r.w = 46 * 6 * 1.7 * facx + 2; else r.w= strlen(tmp) * 6 * 1.7 * facx + 2; // 6- FONT_SIZE_X r.h= 9 * 1.5 * facy; SDL_FillRect(screen, &r, SDL_MapRGB(screen->format,255,0,0));// in RED } /* if */ // print file name with enlarged font ch = 0; if(strlen(tmp) > 46) { ch = tmp[46]; tmp[46] = 0;} //cut-off too long string font_print(4, TOPX + (i - first_file) * 15 * facy, tmp, screen, 1.7 * facx, 1.5 * facy); // show name font_print(sx - 70*facx, TOPX + (i - first_file) * 15 * facy, siz, screen, 1.7 * facx, 1.5 * facy);// show info (dir or size) if(ch) tmp[46] = ch; //restore cut-off char } /* if */ i++; // next item } /* while */ ///////////////////////////////////////////////////////////////////////////////////////////// // draw rectangles rectangle(screen, 0, TOPX - 5, g_ScreenWidth, 320 * facy, SDL_MapRGB(screen->format, 255, 255, 255)); rectangle(screen, 480 * facx, TOPX - 5, 0, 320 * facy, SDL_MapRGB(screen->format, 255, 255, 255)); SDL_Flip(screen); // show the screen SDL_Delay(KEY_DELAY); // wait some time to be not too fast ////////////////////////////////// // Wait for keypress ////////////////////////////////// SDL_Event event; // event Uint8 *keyboard; // key state event.type = SDL_QUIT; while(event.type != SDL_KEYDOWN) { // wait for key pressed SDL_Delay(10); SDL_PollEvent(&event); } // control cursor keyboard = SDL_GetKeyState(NULL); // get current state of pressed (and not pressed) keys if (keyboard[SDLK_UP] || keyboard[SDLK_LEFT]) { if (act_file>0) act_file--; // up one position if (act_file= (first_file + FILES_IN_SCREEN)) first_file=act_file - FILES_IN_SCREEN + 1; } /* if */ if (keyboard[SDLK_PAGEUP]) { act_file-=FILES_IN_SCREEN; if (act_file<0) act_file=0; if (act_file=files.Length()) act_file=(files.Length()-1); if (act_file>=(first_file+FILES_IN_SCREEN)) first_file=act_file-FILES_IN_SCREEN + 1; } /* if */ // choose an item? if (keyboard[SDLK_RETURN]) { // dup string from selected file name *filename = strdup(php_trim(files[act_file],strlen(files[act_file]))); // printf("files[act_file]=%s, *filename=%s\n\n", files[act_file], *filename); if(!strcmp(sizes[act_file], "") || !strcmp(sizes[act_file], "")) *isdir = true; else *isdir = false; // this is directory (catalog in Apple][ terminology) *index_file = act_file; // remember current index files.Delete(); sizes.Delete(); SDL_FreeSurface(my_screen); return true; } /* if */ if (keyboard[SDLK_ESCAPE]) { files.Delete(); sizes.Delete(); SDL_FreeSurface(my_screen); return false; // ESC has been pressed } /* if */ if (keyboard[SDLK_HOME]) { // HOME? act_file=0; first_file=0; } /* if */ if (keyboard[SDLK_END]) { // END? act_file=files.Length() - 1; // go to the last possible file in list first_file=act_file - FILES_IN_SCREEN + 1; if(first_file < 0) first_file = 0; } /* if */ } } /* ChooseAnImageFTP */ /* md5.c - an implementation of the MD5 algorithm and MD5 crypt */ /* See RFC 1321 for a description of the MD5 algorithm. */ #define cpu_to_le32(x) (x) #define le32_to_cpu(x) cpu_to_le32(x) typedef unsigned int UINT4; /* F, G, H and I are basic MD5 functions. */ #define F(x, y, z) (((x) & (y)) | ((~x) & (z))) #define G(x, y, z) (((x) & (z)) | ((y) & (~z))) #define H(x, y, z) ((x) ^ (y) ^ (z)) #define I(x, y, z) ((y) ^ ((x) | (~z))) /* ROTATE_LEFT rotates x left n bits. */ #define ROTATE_LEFT(x, n) (((x) << (n)) | ((x >> (32 - (n))))) static UINT4 md5_initstate[4] = { 0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476 }; static char s1[4] = { 7, 12, 17, 22 }; static char s2[4] = { 5, 9, 14, 20 }; static char s3[4] = { 4, 11, 16, 23 }; static char s4[4] = { 6, 10, 15, 21 }; static UINT4 T[64] = { 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 }; static UINT4 state[4]; static unsigned int length; static unsigned char buffer[64]; static void md5_transform (const unsigned char block[64]) { int i, j; UINT4 a,b,c,d,tmp; const UINT4 *x = (UINT4 *) block; a = state[0]; b = state[1]; c = state[2]; d = state[3]; /* Round 1 */ for (i = 0; i < 16; i++) { tmp = a + F (b, c, d) + le32_to_cpu (x[i]) + T[i]; tmp = ROTATE_LEFT (tmp, s1[i & 3]); tmp += b; a = d; d = c; c = b; b = tmp; } /* Round 2 */ for (i = 0, j = 1; i < 16; i++, j += 5) { tmp = a + G (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+16]; tmp = ROTATE_LEFT (tmp, s2[i & 3]); tmp += b; a = d; d = c; c = b; b = tmp; } /* Round 3 */ for (i = 0, j = 5; i < 16; i++, j += 3) { tmp = a + H (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+32]; tmp = ROTATE_LEFT (tmp, s3[i & 3]); tmp += b; a = d; d = c; c = b; b = tmp; } /* Round 4 */ for (i = 0, j = 0; i < 16; i++, j += 7) { tmp = a + I (b, c, d) + le32_to_cpu (x[j & 15]) + T[i+48]; tmp = ROTATE_LEFT (tmp, s4[i & 3]); tmp += b; a = d; d = c; c = b; b = tmp; } state[0] += a; state[1] += b; state[2] += c; state[3] += d; } static void md5_init(void) { memcpy ((char *) state, (char *) md5_initstate, sizeof (md5_initstate)); length = 0; } static void md5_update (const char *input, int inputlen) { int buflen = length & 63; length += inputlen; if (buflen + inputlen < 64) { memcpy (buffer + buflen, input, inputlen); buflen += inputlen; return; } memcpy (buffer + buflen, input, 64 - buflen); md5_transform (buffer); input += 64 - buflen; inputlen -= 64 - buflen; while (inputlen >= 64) { md5_transform ((unsigned char*)input); input += 64; inputlen -= 64; } memcpy (buffer, input, inputlen); buflen = inputlen; } static unsigned char * md5_final() { int i, buflen = length & 63; buffer[buflen++] = 0x80; memset (buffer+buflen, 0, 64 - buflen); if (buflen > 56) { md5_transform (buffer); memset (buffer, 0, 64); buflen = 0; } *(UINT4 *) (buffer + 56) = cpu_to_le32 (8 * length); *(UINT4 *) (buffer + 60) = 0; md5_transform (buffer); for (i = 0; i < 4; i++) state[i] = cpu_to_le32 (state[i]); return (unsigned char *) state; } static char * md5 (const char *input) { md5_init(); // memcpy ((char *) state, (char *) md5_initstate, sizeof (md5_initstate)); // length = 0; md5_update (input, strlen (input)); return (char *)md5_final (); } char * md5str (const char *input) { char result[16 * 3 +1]; unsigned char* digest = (unsigned char*)md5 (input); int i; for (i=0; i < 16; i++) sprintf (result+2*i, "%02X", digest[i]); return result; }