main.c 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * This file is part of the UCB release of Plan 9. It is subject to the license
  3. * terms in the LICENSE file found in the top-level directory of this
  4. * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
  5. * part of the UCB release of Plan 9, including this file, may be copied,
  6. * modified, propagated, or distributed except according to the terms contained
  7. * in the LICENSE file.
  8. */
  9. #include "acd.h"
  10. int debug;
  11. void
  12. usage(void)
  13. {
  14. fprint(2, "usage: acd dev\n");
  15. threadexitsall("usage");
  16. }
  17. Alt
  18. mkalt(Channel *c, void *v, int op)
  19. {
  20. Alt a;
  21. memset(&a, 0, sizeof(a));
  22. a.c = c;
  23. a.v = v;
  24. a.op = op;
  25. return a;
  26. }
  27. void
  28. freetoc(Toc *t)
  29. {
  30. int i;
  31. free(t->title);
  32. for(i=0; i<t->ntrack; i++)
  33. free(t->track[i].title);
  34. }
  35. void
  36. eventwatcher(Drive *d)
  37. {
  38. enum { STATUS, WEVENT, TOCDISP, DBREQ, DBREPLY, NALT };
  39. Alt alts[NALT+1];
  40. Toc nt, tdb;
  41. Event *e;
  42. Window *w;
  43. Cdstatus s;
  44. char buf[40];
  45. w = d->w;
  46. alts[STATUS] = mkalt(d->cstatus, &s, CHANRCV);
  47. alts[WEVENT] = mkalt(w->cevent, &e, CHANRCV);
  48. alts[TOCDISP] = mkalt(d->ctocdisp, &nt, CHANRCV);
  49. alts[DBREQ] = mkalt(d->cdbreq, &tdb, CHANNOP);
  50. alts[DBREPLY] = mkalt(d->cdbreply, &nt, CHANRCV);
  51. alts[NALT] = mkalt(nil, nil, CHANEND);
  52. for(;;) {
  53. switch(alt(alts)) {
  54. case STATUS:
  55. //DPRINT(2, "s...");
  56. d->status = s;
  57. if(s.state == Scompleted) {
  58. s.state = Sunknown;
  59. advancetrack(d, w);
  60. }
  61. //DPRINT(2, "status %d %d %d %M %M\n", s.state, s.track, s.index, s.abs, s.rel);
  62. sprint(buf, "%d:%2.2d", s.rel.m, s.rel.s);
  63. setplaytime(w, buf);
  64. break;
  65. case WEVENT:
  66. //DPRINT(2, "w...");
  67. acmeevent(d, w, e);
  68. break;
  69. case TOCDISP:
  70. //DPRINT(2,"td...");
  71. freetoc(&d->toc);
  72. d->toc = nt;
  73. drawtoc(w, d, &d->toc);
  74. tdb = nt;
  75. alts[DBREQ].op = CHANSND;
  76. break;
  77. case DBREQ: /* sent */
  78. //DPRINT(2,"dreq...");
  79. alts[DBREQ].op = CHANNOP;
  80. break;
  81. case DBREPLY:
  82. //DPRINT(2,"drep...");
  83. freetoc(&d->toc);
  84. d->toc = nt;
  85. redrawtoc(w, &d->toc);
  86. break;
  87. }
  88. }
  89. }
  90. void
  91. threadmain(int argc, char **argv)
  92. {
  93. Scsi *s;
  94. Drive *d;
  95. char buf[80];
  96. ARGBEGIN{
  97. case 'v':
  98. debug++;
  99. scsiverbose++;
  100. }ARGEND
  101. if(argc != 1)
  102. usage();
  103. fmtinstall('M', msfconv);
  104. if((s = openscsi(argv[0])) == nil)
  105. error("opening scsi: %r");
  106. d = malloc(sizeof(*d));
  107. if(d == nil)
  108. error("out of memory");
  109. memset(d, 0, sizeof d);
  110. d->scsi = s;
  111. d->w = newwindow();
  112. d->ctocdisp = chancreate(sizeof(Toc), 0);
  113. d->cdbreq = chancreate(sizeof(Toc), 0);
  114. d->cdbreply = chancreate(sizeof(Toc), 0);
  115. d->cstatus = chancreate(sizeof(Cdstatus), 0);
  116. proccreate(wineventproc, d->w, STACK);
  117. proccreate(cddbproc, d, STACK);
  118. proccreate(cdstatusproc, d, STACK);
  119. cleanname(argv[0]);
  120. snprint(buf, sizeof(buf), "%s/", argv[0]);
  121. winname(d->w, buf);
  122. wintagwrite(d->w, "Stop Pause Resume Eject Ingest ", 5+6+7+6+7);
  123. eventwatcher(d);
  124. }