home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 3 / PDCD_3.iso / utilities / utilsd / explain / !AWMerge / c / main next >
Encoding:
Text File  |  1995-05-21  |  10.4 KB  |  463 lines

  1. /* main.c
  2.  *
  3.  * Update !AWShared within !System
  4.  *
  5.  */
  6.  
  7. #include <string.h>
  8. #include <ctype.h>
  9. #include <stdlib.h>
  10.  
  11. #include "os.h"
  12. #include "bbc.h"
  13. #include "wimp.h"
  14. #include "event.h"
  15. #include "alarm.h"
  16. #include "wimpt.h"
  17. #include "win.h"
  18. #include "visdelay.h"
  19. #include "res.h"
  20. #include "resspr.h"
  21. #include "template.h"
  22. #include "version.h"
  23. #include "swis.h"
  24. #include "msgs.h"
  25. #include "werr.h"
  26.  
  27. #include "cortn.h"
  28. #include "field.h"
  29. #include "misc.h"
  30. #include "tracker.h"
  31.  
  32. static wimp_w main__w = (wimp_w) -1;
  33. static coroutine *main__co = NULL;
  34.  
  35. #define main__BUFSIZE 16384
  36. #define main__SCANSIZE 1024
  37.  
  38. static int main__wup(int x) { return (x + 3) & ~3; }
  39.  
  40. typedef struct
  41. {  int load, exec, size, attr, type;
  42. } main__finfo;
  43.  
  44. typedef struct
  45. {  int lo, hi;
  46. } main__filedate;
  47.  
  48. static struct
  49. {  char *sysname;
  50.    char *awname;
  51.    BOOL exitafter;
  52.    int  slotstart;  /* start time of the current time slice */
  53.    int  files, bytes;
  54. } main__info;
  55.  
  56. enum { main__SYSNAME = 2, main__CANCEL, main__UPDATE, main__MESSAGE }; 
  57.  
  58. static void main__yield(void)
  59. {
  60.    if (main__info.slotstart + 20 < alarm_timenow())
  61.    {  static int lastbytes = 0, lastfiles = 0;
  62.       if (main__info.bytes > 0 && (main__info.bytes != lastbytes || main__info.files != lastfiles))
  63.       {  field_printf(main__w, main__MESSAGE, msgs_lookup("main10"), main__info.files, main__info.bytes);
  64.          lastbytes = main__info.bytes;
  65.          lastfiles = main__info.files;
  66.       }
  67.       goto_co(MAIN_CO);
  68.    }
  69. }
  70.  
  71. static os_error *main__cdir(char *name)
  72. {  os_filestr fcb;
  73.    int c, sc;
  74.    os_error *err;
  75.  
  76.    for (c = 0; name[c]; c++)
  77.    {  if (name[c] == '.')
  78.       {  sc = name[c];
  79.          name[c] = '\0';
  80.          fcb.name = name;
  81.          fcb.action = 8;
  82.          fcb.end = 0;
  83.          if (err = os_file(&fcb), err) goto fail;
  84.          name[c] = sc;
  85.       }
  86.    }
  87.  
  88.    fcb.name =  name;
  89.    fcb.action = 8;
  90.    fcb.end = 0;
  91.    return os_file(&fcb);
  92.  
  93. fail:
  94.    name[c] = sc;
  95.    return err;
  96. }
  97.  
  98. static void main__getdate(main__filedate *d, os_filestr *fcb)
  99. {  if ((fcb->loadaddr & 0xFFF00000) == 0xFFF00000)
  100.    {  d->lo = fcb->execaddr;
  101.       d->hi = fcb->loadaddr & 0xFF;
  102.    }
  103. }
  104.  
  105. static int main__diffdate(main__filedate *lhs, main__filedate *rhs)
  106. {  if (lhs->hi == rhs->hi)
  107.       return lhs->lo - rhs->lo;
  108.  
  109.    return lhs->hi - rhs->hi;
  110. }
  111.  
  112. static os_error *main__copyfile(char *from, char *to)
  113. {  FILE *r, *w;
  114.    os_error *err;
  115.    os_filestr fcb, fcb2;
  116.    main__filedate fd, td;
  117.    char buffer[main__BUFSIZE];
  118.    int len;
  119.  
  120.    fcb.action = 17;
  121.    fcb.name = from;
  122.    if (err = os_file(&fcb), err) return err;
  123.  
  124.    if (fcb.action != 1)
  125.    {  fcb.loadaddr = fcb.action;
  126.       fcb.action = 19;
  127.       return os_file(&fcb);
  128.    }
  129.  
  130.    main__getdate(&fd, &fcb);
  131.  
  132.    fcb2.action = 17;
  133.    fcb2.name = to;
  134.    if (err = os_file(&fcb2), err) return err;
  135.  
  136.    if (fcb2.action == 2 || fcb2.action == 3)
  137.    {  fcb2.loadaddr = fcb2.action;
  138.       fcb2.action = 19;
  139.       return os_file(&fcb2);
  140.    }
  141.  
  142.    if (fcb2.action != 0)
  143.    {  main__getdate(&td, &fcb2);
  144.  
  145.       if (main__diffdate(&fd, &td) <= 0)
  146.          return NULL;
  147.    }
  148.  
  149.    main__yield();
  150.    
  151.    if (r = fopen(from, "r"), !r)
  152.       return misc_err("main8", from);   
  153.  
  154.    if (w = fopen(to, "w"), !w)
  155.    {  err = misc_err("main8", to);
  156.       goto fail;
  157.    }
  158.  
  159.    main__yield();
  160.    len = fread(buffer, 1, main__BUFSIZE, r);
  161.  
  162.    while (len > 0)
  163.    {
  164.       main__info.bytes += len;
  165.       
  166.       main__yield();
  167.       if (fwrite(buffer, 1, len, w) < len)
  168.       {  err = misc_err("main9", to);
  169.          goto fail2;
  170.       }
  171.       main__yield();
  172.       len = fread(buffer, 1, main__BUFSIZE, r);
  173.    }
  174.  
  175.    main__yield();
  176.  
  177.    fclose(r);
  178.    fclose(w);
  179.  
  180.    main__info.files++;
  181.  
  182.    fcb.action = 1;
  183.    fcb.name = to;
  184.  
  185.    return os_file(&fcb);
  186.  
  187. fail2:
  188.    fclose(w);
  189.  
  190. fail:
  191.    fclose(r);
  192.    return err;
  193. }
  194.  
  195. static os_error *main__copydir(char *from, char *to)
  196. {  os_gbpbstr gbpb;
  197.    char *fromleaf, *toleaf;
  198.    os_error *err;
  199.    char buffer[main__SCANSIZE];
  200.    int n;
  201.    main__finfo *fi;
  202.  
  203.    if (err = main__cdir(to), err) return err;
  204.  
  205.    fromleaf = from + strlen(from) + 1;
  206.    toleaf = to + strlen(to) + 1;
  207.  
  208.    gbpb.action      = 10;
  209.    gbpb.file_handle = (int) from;
  210.    gbpb.data_addr   = buffer;
  211.  
  212.    gbpb.seq_point   = 0;
  213.    gbpb.buf_len     = main__SCANSIZE;
  214.    gbpb.wild_fld    = "*";
  215.  
  216.    do
  217.    {  gbpb.number = 9999;   /* as many as possible */
  218.  
  219.       if (err = os_gbpb(&gbpb), err) return err;
  220.  
  221.       fromleaf[-1] = '.';
  222.       toleaf[-1] = '.';
  223.  
  224.       for (n = 0, fi = (main__finfo *) buffer; n < gbpb.number; n++)
  225.       {
  226.          strcpy(fromleaf, (char *) (fi+1));
  227.          strcpy(toleaf, (char *) (fi+1));
  228.  
  229.          switch (fi->type)
  230.          {  case 1:
  231.                if (err = main__copyfile(from, to), err)
  232.                   goto fail;
  233.                break;
  234.  
  235.             case 2: case 3:
  236.                if (err = main__copydir(from, to), err)
  237.                   goto fail;
  238.                break;
  239.          }
  240.  
  241.          main__yield();
  242.  
  243.          fi = (main__finfo *) (((char *) fi) + sizeof(main__finfo) + main__wup(strlen((char *) (fi+1))+1));
  244.       }
  245.  
  246.       fromleaf[-1] = '\0';
  247.       toleaf[-1] = '\0';
  248.  
  249.    } while (gbpb.seq_point >= 0);
  250.  
  251.    return NULL;
  252.  
  253. fail:
  254.    fromleaf[-1] = '\0';
  255.    toleaf[-1] = '\0';
  256.    return err;
  257. }
  258.  
  259. static void main__sysmerge(void *handle)
  260. {  char tobuf[256], frombuf[256];
  261.  
  262.    strcpy(tobuf, main__info.sysname);
  263.    strcat(tobuf, ".!AWShared");
  264.  
  265.    strcpy(frombuf, main__info.awname);
  266.  
  267.    wimpt_complain(main__copydir(frombuf, tobuf));
  268.  
  269.    if (main__info.exitafter)
  270.       exit(0);
  271.    else
  272.    {  field_settext(main__w, main__MESSAGE, msgs_lookup(main__info.bytes ? "main14" : "main15"));
  273.       field_settext(main__w, main__SYSNAME, "");
  274.       field_fade(main__w, main__UPDATE, TRUE);
  275.       field_settext(main__w, main__CANCEL, msgs_lookup("main13"));
  276.       field_fade(main__w, main__CANCEL, FALSE);
  277.    }
  278. }
  279.  
  280. static void main__alarm(int calledat, void *handle)
  281. {  handle = handle;
  282.  
  283.    main__info.slotstart = calledat;
  284.  
  285.    if (main__co) /* give it a slice of time */
  286.    {  goto_co(main__co);
  287.  
  288.       if (!monitor_co(main__co))
  289.       {  delete_co(main__co);  /* finished */
  290.          main__co = NULL;
  291.       }
  292.    }
  293.  
  294.    alarm_set(calledat + 25, main__alarm, handle);
  295. }
  296.  
  297. static void main__update(char *sysname, char *awname, BOOL exitafter)
  298. {  if (main__co) return;
  299.    main__info.sysname   = sysname;
  300.    main__info.awname    = awname;
  301.    main__info.exitafter = exitafter;
  302.    main__info.files =
  303.    main__info.bytes = 0;
  304.  
  305.    main__co = create_co(main__sysmerge, NULL);
  306.    if (!main__co) werr(TRUE, msgs_lookup("main7"));
  307. }
  308.  
  309. static char *main__awname(void)
  310. {  static char myname[257];
  311.    os_regset regs;
  312.  
  313.    regs.r[0] = (int) "AWMerge$Dir";
  314.    regs.r[1] = (int) myname;
  315.    regs.r[2] = 256;
  316.    regs.r[3] = 0;
  317.    regs.r[4] = 3;
  318.  
  319.    if (wimpt_complain(os_swix(OS_ReadVarVal, ®s)))
  320.       return NULL;
  321.  
  322.    myname[regs.r[2]] = '\0';
  323.  
  324.    strcat(myname, ".!AWShared");
  325.    return myname;
  326. }
  327.  
  328. static void main__handler(wimp_eventstr *e, void *handle)
  329. {  char *np, sysname[256];
  330.    handle = handle;
  331.  
  332.    switch (e->e)
  333.    {  case wimp_ECLOSE:
  334.          exit(1);
  335.          
  336.       case wimp_EOPEN:
  337.          wimpt_complain(wimp_open_wind(&e->data.o));
  338.          break;
  339.  
  340.       case wimp_EBUT:
  341.          switch (e->data.but.m.i)
  342.          {  case main__CANCEL:
  343.                exit(1); /* wait for button to pop up */
  344.                break;
  345.  
  346.             case main__UPDATE:
  347.                field_gettext(main__w, main__SYSNAME, sysname, 255);
  348.                field_fade(main__w, main__CANCEL, TRUE);
  349.                field_fade(main__w, main__UPDATE, TRUE);
  350.                field_settext(main__w, main__MESSAGE, msgs_lookup("main8"));
  351.                main__update(sysname, main__awname(), FALSE);
  352.                break;
  353.          }
  354.          break;
  355.  
  356.       case wimp_ESEND:
  357.       case wimp_ESENDWANTACK:
  358.          if (main__co) break;
  359.  
  360.          switch (e->data.msg.hdr.action)
  361.          {  case wimp_MDATALOAD:
  362.                np = e->data.msg.data.dataload.name +
  363.                     strlen (e->data.msg.data.dataload.name) -
  364.                     strlen("!System");
  365.                if (misc_strcicmp(np, "!System") == 0)
  366.                {  field_settext(main__w, main__SYSNAME, e->data.msg.data.dataload.name);
  367.                   field_settext(main__w, main__MESSAGE, msgs_lookup("main4"));
  368.                   field_fade(main__w, main__UPDATE, FALSE);
  369.                }
  370.                break;
  371.          }
  372.    }
  373. }
  374.  
  375. static os_error *main__interact(void)
  376. {  wimp_wind *wdef;
  377.    os_error *err;
  378.    wimp_wstate state;
  379.    int scx, scy;
  380.    os_regset regs;
  381.    char sysname[257];
  382.    char *sp, *pp;
  383.  
  384.    if (err = misc_template("merger", &wdef), err) return err;
  385.    if (err = wimp_create_wind(wdef, &main__w), err) return err;
  386.    win_register_event_handler(main__w, main__handler, NULL);
  387.  
  388.    field_settext(main__w, main__CANCEL, msgs_lookup("main11"));
  389.    field_settext(main__w, main__UPDATE, msgs_lookup("main12"));
  390.  
  391.    if (err = wimp_get_wind_state(main__w, &state), err) return err;
  392.  
  393.    scx = (bbc_vduvar(bbc_XWindLimit) + 1) << bbc_vduvar(bbc_XEigFactor);
  394.    scy = (bbc_vduvar(bbc_YWindLimit) + 1) << bbc_vduvar(bbc_YEigFactor);
  395.  
  396.    misc_boxto(&state.o.box, (scx - (state.o.box.x1 - state.o.box.x0)) / 2,
  397.                             (scy - (state.o.box.y1 - state.o.box.y0)) / 2);
  398.  
  399.    state.o.behind = -1;
  400.  
  401.    if (err = wimp_open_wind(&state.o), err)
  402.       return err;
  403.  
  404.    /* Try to find !System */
  405.  
  406.    regs.r[0] = (int) "System$Path";
  407.    regs.r[1] = (int) sysname;
  408.    regs.r[2] = 256;
  409.    regs.r[3] = 0;
  410.    regs.r[4] = 3;
  411.  
  412.    if (os_swix(OS_ReadVarVal, ®s))
  413.    {  field_settext(main__w, main__MESSAGE, msgs_lookup("main5"));
  414.       field_settext(main__w, main__SYSNAME, "");
  415.       field_fade(main__w, main__UPDATE, TRUE);
  416.    }
  417.    else
  418.    {  sysname[regs.r[2]] = '\0';
  419.       for (pp = NULL, sp = sysname; *sp > ' ' && *sp != ','; sp++)
  420.          if (*sp == ':' || *sp == '.')
  421.             pp = sp;
  422.    
  423.       if (pp) *pp = '\0';
  424.       
  425.       field_settext(main__w, main__MESSAGE, msgs_lookup("main4"));
  426.       field_settext(main__w, main__SYSNAME, sysname);
  427.    }
  428.  
  429.    return NULL;
  430. }
  431.  
  432. int main(int argc, char *argv[])
  433. {  wimpt_wimpversion(200);
  434.    misc_init("AWMerge");
  435.  
  436.    visdelay_init();
  437.    visdelay_begin();
  438.  
  439.    res_init("AWMerge");
  440.    resspr_init();
  441.    alarm_init();
  442.    msgs_init();
  443.    template_init();
  444.  
  445.    if (__versionnumber() < 3.80)
  446.       werr(TRUE, "AWMerge has been linked with an out of date RISC OS library");
  447.  
  448.    main__co = NULL;
  449.  
  450.    /* win_add_unknown_event_processor(main__ukproc, NULL); */
  451.    win_activeinc();
  452.    alarm_set(alarm_timenow() + 25, main__alarm, NULL);
  453.  
  454.    visdelay_end();
  455.  
  456.    if (argc < 2)
  457.       wimpt_complain(main__interact());
  458.    else
  459.       main__update(argv[1], main__awname(), TRUE);
  460.  
  461.    for (;;) event_process();
  462. }
  463.