home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / files / diskutil / unixflop / unixflop.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-04-22  |  13.8 KB  |  602 lines

  1. /* #define DEBUG /* */
  2.  
  3. #include <obdefs.h>
  4. #include <gemdefs.h>
  5. #include <osbind.h>
  6. #include <stdio.h>
  7. #include <fcntl.h>
  8.  
  9. #define TRUE 1
  10. #define FALSE 0
  11. #define WI_KIND        (SIZER|MOVER|FULLER|CLOSER|NAME|INFO)
  12.  
  13. #define NO_WINDOW (-1)
  14.  
  15. #define MIN_WIDTH  (2*gl_wbox)
  16. #define MIN_HEIGHT (3*gl_hbox)
  17.  
  18. extern int    gl_apid;
  19.  
  20. int    gl_hchar;
  21. int    gl_wchar;
  22. int    gl_wbox;
  23. int    gl_hbox;    /* system sizes */
  24.  
  25. int     phys_handle;    /* physical workstation handle */
  26. int     handle;        /* virtual workstation handle */
  27. int    wi_handle;    /* window handle */
  28. int    top_window;    /* handle of topped window */
  29.  
  30. int    xdesk,ydesk,hdesk,wdesk;
  31. int    xold,yold,hold,wold;
  32. int    xwork,ywork,hwork,wwork;    /* desktop and work areas */
  33.  
  34. int    msgbuff[8];    /* event message buffer */
  35. int    butstate;    /* keycode returned by event-mouse*/
  36. int    keycode;    /* keycode returned by event-keyboard */
  37. int    mx,my;        /* mouse x and y pos. */
  38. int    butdown;    /* button state tested for, UP/DOWN */
  39. int    ret;        /* dummy return variable */
  40.  
  41. int    hidden;        /* current state of cursor */
  42.  
  43. int    fulled;        /* current state of window */
  44.  
  45. int    contrl[12];
  46. int    intin[128];
  47. int    ptsin[128];
  48. int    intout[128];
  49. int    ptsout[128];    /* storage wasted for idiotic bindings */
  50.  
  51. int work_in[11];    /* Input to GSX parameter array */
  52. int work_out[57];    /* Output from GSX parameter array */
  53. int pxyarray[10];    /* input point array */
  54.  
  55. /****************************************************************/
  56. /*  GSX UTILITY ROUTINES.                    */
  57. /****************************************************************/
  58.  
  59. hide_mouse()
  60. {
  61.     if(! hidden){
  62.         graf_mouse(M_OFF,0x0L);
  63.         hidden=TRUE;
  64.     }
  65. }
  66.  
  67. show_mouse()
  68. {
  69.     if(hidden){
  70.         graf_mouse(M_ON,0x0L);
  71.         hidden=FALSE;
  72.     }
  73. }
  74.  
  75. /****************************************************************/
  76. /* open virtual workstation                    */
  77. /****************************************************************/
  78. open_vwork()
  79. {
  80. int i;
  81.     for(i=0;i<10;work_in[i++]=1);
  82.     work_in[10]=2;
  83.     handle=phys_handle;
  84.     v_opnvwk(work_in,&handle,work_out);
  85. }
  86.  
  87. /****************************************************************/
  88. /* set clipping rectangle                    */
  89. /****************************************************************/
  90. set_clip(x,y,w,h)
  91. int x,y,w,h;
  92. {
  93. int clip[4];
  94.     clip[0]=x;
  95.     clip[1]=y;
  96.     clip[2]=x+w;
  97.     clip[3]=y+h;
  98.     vs_clip(handle,1,clip);
  99. }
  100.  
  101. /****************************************************************/
  102. /* open window                            */
  103. /****************************************************************/
  104. open_window()
  105. {
  106.     wi_handle=wind_create(WI_KIND,xdesk,ydesk,wdesk,hdesk);
  107.     wind_set(wi_handle, WF_NAME," Unix Floppy Converter ",0,0);
  108.     graf_growbox(xdesk+wdesk/2,ydesk+hdesk/2,gl_wbox,gl_hbox,xdesk,
  109.                 ydesk,wdesk,hdesk);
  110.     wind_open(wi_handle,xdesk,ydesk,wdesk,hdesk);
  111.     wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
  112. }
  113.  
  114. /****************************************************************/
  115. /* find and redraw all clipping rectangles            */
  116. /****************************************************************/
  117. do_redraw(xc,yc,wc,hc)
  118. int xc,yc,wc,hc;
  119. {
  120. GRECT t1,t2;
  121.  
  122.     hide_mouse();
  123.     wind_update(TRUE);
  124.     t2.g_x=xc;
  125.     t2.g_y=yc;
  126.     t2.g_w=wc;
  127.     t2.g_h=hc;
  128.     wind_get(wi_handle,WF_FIRSTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
  129.     while (t1.g_w && t1.g_h) {
  130.       if (rect_intersect(t2,t1,&t1)) {
  131.         set_clip(t1.g_x,t1.g_y,t1.g_w,t1.g_h);
  132.         draw_sample();
  133.       }
  134.       wind_get(wi_handle,WF_NEXTXYWH,&t1.g_x,&t1.g_y,&t1.g_w,&t1.g_h);
  135.     }
  136.     wind_update(FALSE);
  137.     show_mouse();
  138. }
  139.  
  140. /****************************************************************/
  141. /*        Accessory Init. Until First Event_Multi        */
  142. /****************************************************************/
  143.  
  144. char *buffer, *endBuffer; /* memory for data */
  145. int drive;
  146. long freeMem;
  147. char *index(), *rindex();
  148.  
  149. main()
  150. {
  151.     appl_init();
  152.     phys_handle=graf_handle(&gl_wchar,&gl_hchar,&gl_wbox,&gl_hbox);
  153.     wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
  154.     open_vwork();
  155.         open_window();
  156.     graf_mouse(ARROW,0x0L);
  157.  
  158.     hidden=FALSE;
  159.     fulled=FALSE;
  160.     butdown=TRUE;
  161.  
  162.     freeMem = Malloc(-1L);
  163.     freeMem -= 10240;
  164.     if (freeMem < 20480) {
  165.         form_alert(1, "[3][Not enough memory][Ok]");
  166.         GemExit();
  167.     }
  168.     buffer = lmalloc(freeMem);
  169.  
  170.     multi(); 
  171. }
  172.  
  173. /* colas  --- */
  174.  
  175. #define safe_malloc_body(func) \
  176.         char *ptr = func(s); \
  177.     if (!ptr) {free(buffer); \
  178.         form_alert(1, "[3][Out of memory|quitting program][Ok]"); \
  179.         GemExit();} \
  180.     return ptr
  181.  
  182. char *lsafe_malloc(s) long s;{safe_malloc_body(lmalloc);}
  183. char *safe_malloc(s) int s;{safe_malloc_body(malloc);}
  184.  
  185. char *mprintf1(), *mprintf2(), *mprintf3();
  186. jmp_buf start;
  187.  
  188. info(s) char *s;{wind_set(wi_handle, WF_INFO,s ,0,0);}
  189.  
  190. multi()
  191. {
  192. int event;
  193.  
  194.       setjmp(start);
  195.       do {
  196.     event = evnt_multi(MU_MESAG | MU_BUTTON | MU_KEYBD,
  197.             1,3,butdown,
  198.             0,0,0,0,0,
  199.             0,0,0,0,0,
  200.             msgbuff,0,0,&mx,&my,&butstate,&ret,&keycode,&ret);
  201.  
  202.     info("Click in window to begin, close window or Undo to quit");
  203.     wind_update(TRUE);
  204.  
  205.     if (event & MU_MESAG)
  206.       switch (msgbuff[0]) {
  207.  
  208.       case WM_REDRAW:
  209.         do_redraw(msgbuff[4],msgbuff[5],msgbuff[6],msgbuff[7]);
  210.         break;
  211.  
  212.       case WM_NEWTOP:
  213.       case WM_TOPPED:
  214.         wind_set(wi_handle,WF_TOP,0,0,0,0);
  215.         break;
  216.  
  217.       case WM_SIZED:
  218.       case WM_MOVED:
  219.         if(msgbuff[6]<MIN_WIDTH)msgbuff[6]=MIN_WIDTH;
  220.         if(msgbuff[7]<MIN_HEIGHT)msgbuff[7]=MIN_HEIGHT;
  221.         wind_set(wi_handle,WF_CURRXYWH,msgbuff[4],msgbuff[5],
  222.                 msgbuff[6],msgbuff[7]);
  223.         wind_get(wi_handle,WF_WORKXYWH,&xwork,&ywork,&wwork,&hwork);
  224.         break;
  225.  
  226.       case WM_FULLED:
  227.         if(fulled){
  228.         wind_calc(WC_WORK,WI_KIND,xold,yold,wold,hold,
  229.                 &xwork,&ywork,&wwork,&hwork);
  230.         wind_set(wi_handle,WF_CURRXYWH,xold,yold,wold,hold);}
  231.         else{
  232.         wind_calc(WC_BORDER,WI_KIND,xwork,ywork,wwork,hwork,
  233.                 &xold,&yold,&wold,&hold);
  234.         wind_calc(WC_WORK,WI_KIND,xdesk,ydesk,wdesk,hdesk,
  235.                 &xwork,&ywork,&wwork,&hwork);
  236.         wind_set(wi_handle,WF_CURRXYWH,xdesk,ydesk,wdesk,hdesk);
  237.         }
  238.         fulled ^= TRUE;
  239.         break;
  240.  
  241.       } /* switch (msgbuff[0]) */
  242.  
  243.     if (event & MU_BUTTON) {
  244.       if(butdown) butdown = FALSE;
  245.       else butdown = TRUE;
  246.  
  247.       if (!butstate) do_main_alert();
  248.     }
  249.       if(event & MU_KEYBD){
  250.          do_redraw(xwork,ywork,wwork,hwork);
  251.          switch ((unsigned) keycode) {
  252.             case 0x6200: /* Help */
  253.             help();break;
  254.             case 0x6100: /* Undo */
  255.             GemExit();break;
  256.             case 0x7700: /* Home: resets button state */
  257.             butdown =~ 1;
  258.             break;
  259.             default:
  260.             do_main_alert();
  261.          }
  262.       }
  263.     
  264.     wind_update(FALSE); 
  265.  
  266.       }while(!((event & MU_MESAG) && (msgbuff[0] == WM_CLOSED)));
  267.       GemExit();
  268. }
  269.       
  270. GemExit() {
  271.       wind_close(wi_handle);
  272.       graf_shrinkbox(xwork+wwork/2,ywork+hwork/2,gl_wbox,gl_hbox,
  273.                     xwork,ywork,wwork,hwork);
  274.       wind_delete(wi_handle);
  275.       v_clsvwk(handle);
  276.       appl_exit();
  277.       exit(0);
  278. }
  279.  
  280. draw_sample()
  281. {
  282. int temp[4];
  283.     vsf_interior(handle,2);
  284.     vsf_style(handle,8);
  285.     vsf_color(handle,0);
  286.     temp[0]=xwork;
  287.     temp[1]=ywork;
  288.     temp[2]=xwork+wwork-1;
  289.     temp[3]=ywork+hwork-1;
  290.     v_bar(handle,temp);        /* blank the interior */
  291. }
  292.  
  293. do_main_alert()
  294. {
  295.     char *s;
  296.     int res = form_alert(1, s=mprintf1(
  297.     "[2][Select transfer:|Buffer size: %ldK][Unix -> ST|St -> Unix|Help]",
  298.     freeMem/1024));
  299.     free(s);
  300.     switch(res) {
  301.         case 1: raw2tar(); break;
  302.         case 2: tar2raw(); break;
  303.         default: help(); break;
  304.     }    
  305. }
  306.  
  307. help()
  308. {
  309.         /* max text is 5lines of 32 chars */
  310.     switch(form_alert(1,"[1][\
  311. Converts  disks made on an unix|\
  312. machine by a tar cf /dev/floppy|\
  313. (double density, 2 sides, 80trk|\
  314. 9sect) to/from atari st files. |\
  315.      (c) Colas Nahaboo May 1990]\
  316. [Ok]")) {
  317.     case 1: break;
  318.     }
  319. }
  320.  
  321. int size,s,s_max,track, side, block;
  322. char *buf;
  323. init_data() {
  324.     size=s=track=side=block=0;
  325.     s_max=512 * 9 * 2 * 80;
  326.     buf=buffer;
  327. }
  328.  
  329. raw2tar()
  330. {
  331.     init_data();
  332.     switch(form_alert(1,"[1][Insert raw unix disk|to read from in drive:][ A | B |Cancel]")) {
  333.         case 1: drive = 0;break;
  334.         case 2: drive = 1;break;
  335.     case 3: longjmp(start,1);
  336.     }
  337.     for (;;) {
  338.             if(convert_track_r2t(1, 0)) break;
  339.         if(convert_track_r2t(0, 1)) break;
  340.     }
  341.     switch(form_alert(1,"[3][Insert disk to write|files to in drive:][ A | B |Cancel]")) {
  342.         case 1: drive = 0;break;
  343.         case 2: drive = 1;break;
  344.     case 3: longjmp(start,1);
  345.     }
  346.     detar(buffer, endBuffer);
  347.     form_alert(1,"[1][Files written][Ok]");
  348. }
  349.  
  350. convert_track_r2t(next_side, incr_track)
  351. int next_side, incr_track;
  352. {
  353.     char mess[80];
  354.  
  355.     if ((buf - buffer) > (freeMem - 512*9)) 
  356.         fatal_error(0, "Disk does not fit in memory");
  357.     if (Floprd(buf, 0L, drive, 1, track, side, 9)) {
  358.         fatal_error(1, mprintf2("Read error|track %ld|side %ld",
  359.         (long) track, (long) side));
  360.     }
  361.     block = print_names(block, s, s +9 < s_max ? s+9 : s_max);
  362.     side = next_side; s += 9; track += incr_track;
  363.     buf += 9*512;
  364.     if (s >= s_max) {
  365.         return 1;
  366.     } else {
  367.            return 0;
  368.     }
  369. }
  370.  
  371. int print_names(block, s, s_end)
  372. int block, s, s_end;
  373. {
  374.     char *tmp;
  375.     while (block >= s && block < s_end) {
  376.         if (buf[(block-s) * 512] == '\0') {
  377.         /* end of tape reached */
  378.             info(tmp=mprintf1("End of file at block %ld", (long) block));
  379.         free(tmp);
  380.             s_max = block;
  381.             endBuffer = buf + (block-s) * 512;
  382.             block = -1;
  383.         } else {
  384.             long size;
  385.             sscanf(buf + (block-s) * 512 + 124, " %lo", &size);
  386.             info(tmp=mprintf3("Block %5ld: %.100s  -  %ldK", (long) block, 
  387.             buf + (block-s) * 512, size/1024));
  388.         free(tmp);
  389.         if (size)
  390.                 block = block + 2 + (int) ((size - 1)/ 512);
  391.         else
  392.         block++;
  393.          }
  394.     }
  395.     return block;
  396. }
  397.  
  398. detar(block, end)
  399. char *block, *end;
  400. {
  401.     long size;
  402.     int fd;
  403.     char path[100], name[100], *s;
  404.  
  405.     info("Reading unix floppy in memory...");
  406.     Dsetdrv(drive);
  407.     Dsetpath("\\");
  408.     while (block < end) {
  409.         sscanf(block + 124, " %lo", &size);
  410.         FixPath(block, path, name);
  411.         info(s=mprintf3("Creating %s\\%s (%ldK)", path, name,
  412.             (size+1023)/1024));
  413.     free(s);
  414.     CreateDir(path);
  415.         if (name[0]) { /* create normal file */
  416.         fd = Fcreate(s=mprintf2("%s\\%s", path, name), 0);
  417.         free(s);
  418.         if (!fd || Fwrite(fd, size, block + 512) != size)
  419.             fatal_error(1, mprintf1("cannot create file|%s", name));
  420.             Fclose(fd);      
  421.         block = block + (2 + ((size - 1)/ 512)) *512;
  422.     } else { /* create directory */
  423.         if(path[0] && Dcreate(path))
  424.             fatal_error(1, mprintf1("cannot create directory|%s", name));
  425.         block += 512;
  426.     }
  427.     }        
  428. }
  429.  
  430. /* parses path in  dir & name. dir: name ="" */
  431. FixPath(string, path, name)
  432. char *string, *path, *name;
  433. {
  434.     char *p;
  435.     if (index(string, ' ') || index(string, '\n'))
  436.         fatal_error(1, mprintf1("Bad file name: %s", string));
  437.     if (string[0] == '.' && string[1] == '/')
  438.         strcpy(path, string+2);
  439.     else
  440.         strcpy(path, string);
  441.     p = index(path, '/');
  442.     while(p) {
  443.         *p = '\\';
  444.     p = index(p, '/');
  445.     }
  446.  
  447.     p = rindex(path, '\\');
  448.     if(p) {
  449.         *p='\0';
  450.         strcpy(name, p+1);
  451.     } else {
  452.         strcpy(name, path);
  453.         path[0] = '\0';
  454.     }
  455. #ifdef DEBUG
  456.     p=mprintf3("[0][FixPath: string path name|(%s)|(%s)|(%s)][Continue]",
  457.         string, path, name);
  458.     form_alert(1, p);
  459.     free(p);
  460.     p=mprintf3("[0][(adresses: string path name|(%lx)|(%lx)|(%lx)][Continue]",
  461.         string, path, name);
  462.     form_alert(1, p);
  463.     free(p);
  464. #endif
  465.     
  466. }
  467.  
  468. CreateDir(path)
  469. char *path;
  470. {
  471.     if(path[0] && !(Fattrib(path,0,0) & 0x10)) {
  472.         CreateParentDir(path);
  473.     if(Dcreate(path))
  474.         fatal_error(1, mprintf1("cannot create directory|%s", path)); 
  475.     }
  476. }
  477.  
  478. CreateParentDir(path)
  479. char *path;
  480. {
  481.     char *p = rindex(path, '\\');
  482.     char *parent;
  483. #ifdef DEBUG
  484.     parent=mprintf1("[0][CreateParentDir(%s)][Continue]", path);
  485.     form_alert(1, parent);
  486.     free(parent);
  487. #endif
  488.     if(p && p != path){
  489.         parent = safe_malloc(p - path + 1);
  490.     strncpy(parent, path, p-path);
  491.     parent[p-path] = 0;
  492.     CreateDir(parent);
  493.     free(parent);
  494.     }
  495. }
  496.  
  497. fatal_error(free_string, s)
  498. int free_string;
  499. char *s;
  500. {
  501.     char *tmp;
  502.     form_alert(1, tmp=mprintf1("[3][Error|%s][Abort]", s));
  503.     free(tmp);
  504.     if (free_string) free(s);
  505.     longjmp(start, 1);
  506. }
  507.  
  508. /****************************************************************************/
  509.  
  510. tar2raw()
  511. {
  512.     static char default_path[80];
  513.     static char default_name[80];
  514.     int  button;
  515.  
  516.     if (!default_path[0]) {
  517.         strcpy(default_path, "A:\\*.*");
  518.         strcpy(default_name, "");
  519.     }
  520.     fsel_input(default_path, default_name, &button);
  521.     if (button)
  522.         printf("You have selected the file <%s>.\n", default_name);
  523.     else
  524.         printf("You have cancelled the file selection.\n");
  525.     for (;;) {
  526.         if(convert_track_t2r(1, 0)) break;
  527.     if(convert_track_t2r(0, 1)) break;
  528.     }
  529. }
  530.  
  531. convert_track_t2r(next_side, incr_track)
  532. int next_side, incr_track;
  533. {
  534. int fd;
  535.     static long total_size;
  536.     int read_size = read(fd, buf, 512 * 9);
  537.     total_size += read_size;
  538.     if (read_size != 512 * 9) {
  539.         s_max=total_size/512/9;
  540.         bzero(buf+read_size, 512*9 - read_size);
  541.     }
  542.     if (Flopwr(buf, 0L, 0, 1, track, side, 9)) {
  543.         char mess[80];
  544.         sprintf(mess, "error writing track %d, side %d\n", track, side);
  545.         fatal_error(mess);
  546.     }
  547.     block = print_names(block, s, s +9 < s_max ? s+9 : s_max);
  548.     side = next_side; s += 9; track += incr_track;
  549.     if (read_size != 512 * 9) {
  550.         long pos = lseek(fd, 0L, 2);
  551.         if (pos == -1) {
  552.             fatal_error("could not reach end of file\n");
  553.         } else if (pos != total_size) {
  554.             fatal_error("cannot read whole file\n");
  555.         } else if (read_size > 512 * 7) {
  556.             return 0;
  557.         } else {
  558.             return 1;
  559.         }
  560.     } else
  561.         return 0;
  562. }
  563.  
  564. /* strings ops */
  565.  
  566. char mprintfBuf[256];
  567.  
  568. char *
  569. mprintf1(format, arg1)
  570. char *format, *arg1;
  571. {
  572.     char *string;
  573.     sprintf(mprintfBuf, format, arg1);
  574.     string = safe_malloc(strlen(mprintfBuf) + 1);
  575.     strcpy(string, mprintfBuf);
  576.     return string;
  577. }
  578.  
  579. char *
  580. mprintf2(format, arg1, arg2)
  581. char *format, *arg1, *arg2;
  582. {
  583.     char *string;
  584.     sprintf(mprintfBuf, format, arg1, arg2);
  585.     string = safe_malloc(strlen(mprintfBuf) + 1);
  586.     strcpy(string, mprintfBuf);
  587.     return string;
  588. }
  589.  
  590. char *
  591. mprintf3(format, arg1, arg2, arg3)
  592. char *format, *arg1, *arg2, *arg3;
  593. {
  594.     char *string;
  595.     sprintf(mprintfBuf, format, arg1, arg2, arg3);
  596.     string = safe_malloc(strlen(mprintfBuf) + 1);
  597.     strcpy(string, mprintfBuf);
  598.     return string;
  599. }
  600.  
  601.  
  602.