debian: ปรับปรุงเครื่องคัดลอกซีดี บน Squeeze

จะรีไซเคิลเครื่องเก่า มาทำเครื่องคัดลอกซีดีเพื่อถวายวัด

สเปคเครื่องเก่าคือ AMD Sempron(tm) 2000+, RAM 512MB, HD 40G (เป็น /dev/sda)
ลงทุนซื้อใหม่คือ CD-Writer 4 ตัว ตัวละ 545 บาท (IDE 3 และ SATA 1)
เนื่องจากจะไม่มีจอภาพ จึงจะใช้เสียงเป็นตัวแจ้งสถานะ

จะทำให้มีการทำงานคือ

  • เมื่อเปิดเครื่อง ถาด /dev/sr0 จะดีดออกเพื่อรอการอ่านข้อมูล ใช้เสียงดัง 1 ปี๊บ ทุก 3 วินาที
  • เมื่อใส่แผ่นต้นฉบับ เครื่องจะตรวจสอบแผ่น ถ้าแผ่นเสียจะแจ้งเป็นเสียง 6 ปี๊บ ทุก 3 วินาที เพื่อรออ่านแผ่นใหม่
  • ถ้าแผ่นดีจะอ่านจนเสร็จ แล้วทั้ง 4 ถาดจะถูกดีดออกเพื่อรอการเขียนข้อมูล โดยใช้เสียงดัง 2 ปี๊บ ทุก 3 วินาที
  • จะเขียนวนไปเรื่อยจนกระทั่งปิดเครื่องเขียนด้วยถาดเปล่า ไดร์ฟนั้นก็จะหยุดทำงาน
  • เมื่อหยุดทำงานครบสามไดร์ฟแล้ว เครื่องจะปิดตัวเอง
  • ในระหว่างที่ถาดถูกดีดออก ถ้าไม่มีการใส่แผ่นใหม่เข้าไป หลังจากผ่านไป 100 ปี๊ป หรือเรากดถาดเปล่าดีดกลับเข้าไป ถาดจะปิดตัวเอง และปิดการทำงานของถาดนั้นตลอดไป

หมายเหตุ

  • เนื่องจากเป็นการทำงานแบบขนาน ทุกไดร์ฟจึงทำงานเป็นอิสระ
  • กำหนดให้ความเร็วในการเขียนเป็นแค่ 1x เพื่อให้ฮาร์ดดิสก์อ่านข้อมูลได้ทัน และเพิ่มความคงทนของข้อมูล
  • แผ่นที่เป็นเสียง Audio อ่านช้ามาก

ธีการสร้าง

เริ่มด้วยติดตั้งเดเบียน squeeze แบบไม่ติดตั้งอะไรเพิ่มเติมเลย
ดามด้วยเอาแพกเกจที่จำเป็นที่สคริปต์เราต้องเรียกใช้ คือ

  • eject สำหรับดีดถาดเข้า/ออก
  • setcd สำหรับตรวจสถานะถาด และ
  • cdrdao สำหรับการคัดลอกและเขียนข้อมูล
    • # aptitude install eject setcd cdrdao

      สร้างสคริปต์สำหรับให้ rc.local เรียกใช้ตอนเปิดเครื่อง สำหรับให้อ่านแผ่นต้นฉบับ
      ตั้งชื่อว่า d.rc-cpcd

      # vi /usr/local/sbin/d.rc-cpcd
      #!/bin/bash
      
      # CD COPIER PROGRAM
      
      # PREREQUISITE:
      #       # aptitude install eject cdrdao setcd dvd+rw-tools
      #       file: d.rc-cpcd d.func-cpcd
      
      # PUT d.rc-cpcd AND d.func-cpcd IN /usr/local/sbin
      # THEN CALL d.rc-cpcd FROM /etc/rc.local
      
      #VARIABLE
      SRC=/dev/sr0        #SOURCE DRIVE
      TOC=/tmp/toc.bin    #TEMP.IMAGE FILE
      DSC="
      /dev/sr0
      /dev/sr1
      /dev/sr2
      /dev/sr3
      "               #DESTINATION DRIVE
      
      . /usr/local/sbin/d.common-func
      
      wait_read_close() {
          # MAX RETRY LOOP = 100
          for (( i=0; i<=100; i++ )); do
              if setcd -i $SRC | grep 'CD tray is open' >> /dev/null; then
                  # SLEEP 1 SECONDS
                  beep_close
              elif setcd -i $SRC | grep 'Drive is not ready' >> /dev/null; then
                  sleep 1
              else   
                  if setcd -i $SRC | grep 'No disc is inserted' >> /dev/null; then
                      break
                  else   
                      #DO READ
                      cdrdao  read-cd --device $SRC --read-raw --datafile /tmp/data.bin $TOC
                      return
                  fi
              fi
          done
          eject -t $SRC
          /sbin/shutdown -h now
          return
      }
      
      
      rm -rf $TOC
      
      
      #CHECK 1ST CDR IS ORIGINAL CD THEN DUP. TO /tmp
      while ! [ -s $TOC ]; do
          eject $SRC
          echo "eject $SRC"
          wait_read_close $SRC
          beep
      done
      
      
      # CALL MULTIPLE INSTANCE IN $DSC DRIVES
      for i in $DSC; do
          if [ "$i" ]; then
              /usr/local/sbin/d.func-cpcd $i $TOC &
          fi
      done
      wait
      /sbin/shutdown -h now
      

      อีกไฟล์นึงเป็นฟังก์ชั่นสำหรับเขียนซีดี ตั้งชื่อว่า d.func-cpcd

      # vi /usr/local/sbin/d.func-cpcd
      #!/bin/bash
      
      DEV=$1
      TOC=$2
      SPEED=1
      
      . /usr/local/sbin/d.common-func
      
      wait_write_close() {
          # MAX RETRY LOOP = 100
          for (( i=0; i<=100; i++ )); do
              # WAIT FOR INSERT DISC
              if setcd -i $DEV | grep 'is open' >> /dev/null; then
                  beep_write; sleep 3
              elif setcd -i $DEV | grep 'Drive is not ready' >> /dev/null; then
                  sleep 1
              elif setcd -i $DEV | grep 'No disc' >> /dev/null; then
                  # IF NO DISC INSERTED THEN BREAK
                  exit 1
              else   
                  # DO WRITE
                  cdrdao write --device $DEV --speed $SPEED --overburn -n $TOC
                  # LAST CHECK WRITING
                  if setcd -i $DEV | grep 'error' >> /dev/null; then
                      beep_error; sleep 3
                      eject $DEV
                  else   
                      eject $DEV
                      return
                  fi
              fi
          done
          #END PROG
          eject -t $DEV
          exit 1
      }
      
      if [ ! $1 ] && [ ! $2 ] ; then
          echo " USAGE : $0 DRIVE SPEED TEMP-IMG"
          echo " EXAM1 : $0 /dev/sr0 /tmp/toc.bin"
          exit 1
      fi
      
      
      #CHECK IMAGE FILE
      if ! [ -f $TOC ] ; then
          echo " Image file $TOC does not existed"
          exit 1
      fi
      
      
      #COPY TO NEW BLANK CD
      while [ -f $TOC ]; do
          eject $DEV
          wait_write_close
          beep_write
      done
      

      และสุดท้ายคือไฟล์ฟังก์ชั่นที่ใช้ร่วมกัน

      # vi /usr/local/sbin/d.common-func
      #!/bin/bash
      
      beep() {
          echo -e "\a"
      }
      
      beep_close() {
          beep; sleep 1;
      }
      beep_write() {
          beep; sleep .15; beep
      }
      
      beep_error() {
          for i in `seq 1 6`; do beep; sleep .15; done
      }
      

      ต่อไปแก้ไขไฟล์ /etc/rc.local ให้มาเรียกใช้โปรแกรม d.rc-cpcd ตอนเปิดเครื่อง

      # vi /etc/rc.local
      ...
      /usr/local/sbin/d.rc-cpcd
      exit 0
      

      เสร็จแล้วรีบูตทดสอบได้เลย