home *** CD-ROM | disk | FTP | other *** search
/ ftp.shrubbery.net / 2015-02-07.ftp.shrubbery.net.tar / ftp.shrubbery.net / pub / pc / unix / unx.arc / MV.ASM < prev    next >
Assembly Source File  |  1986-06-02  |  6KB  |  268 lines

  1.     page 66,132
  2. ;---- mv.com ------------------------------------------------
  3. ; Usage: mv from to
  4. ;    or: mv file {file {file...}} directory
  5. ; Moves files; cannot move across file systems.
  6. ; Useful for moving files to different directory.
  7. ; Not really very robust; doesn't like drive specs; not too smart.
  8. ; Sept 5 Dank: Fixed case mv \fred\*.* . bug by adding dirbuf2
  9. ; 6/2/86 DRK: added better error message for filetype!=directory if >2 args
  10. ;---------------------------------------------------------------
  11.  
  12.     extrn    _args:near,_shift:near,argc:word,argv:word
  13.     extrn    ffirst:near,fnext:near,fnam:byte,finder:word
  14.  
  15. basefn    equ    30    ; offset from finder of base filename
  16. stderr    equ    2
  17.  
  18.  
  19. code    segment    public 'CODE'
  20. assume cs:code,ds:code,es:code
  21.  
  22. f_attrib    equ    21        ; offset from DTA of file attrib
  23.  
  24.     org    100h            ; this is a .com program, unfortunately
  25.  
  26. main    proc    near
  27.     jmp    mv
  28. main    endp
  29.  
  30.     db    27
  31.     db    '[2J', 13, 10
  32.     db    'mv, 1984 & 1986 by DRK.', 13, 10
  33.     db    'How long did it take you to try typing me?', 13, 10
  34. umsg:    db    'usage: mv file newfilename', 13, 10
  35.     db    '   or: mv file {file {file ...}} newdirectory', 13, 10
  36.     db    " Don't use drive letters.", 13, 10
  37. ulen    =    $ - offset umsg
  38.     db    26
  39.  
  40. movmsg:    db    '?mv: error moving files', 13, 10
  41. movlen    =    $ - offset movmsg
  42.  
  43. drmsg:    db    '?mv: last arg is not a directory', 13, 10
  44. drlen    =    $ - offset drmsg
  45.  
  46. lastarg        dw    ?        ; pointer to last argument
  47. lastargisdir    db    ?        ; true if last argument is a directory
  48. renaming    db    ?        ; boolean- true if just rename
  49. newfname    dw    ?        ; pointer to new filename
  50. dirbuf        db    64 dup (?)    ; holds current directory
  51. dirbuf2        db    64 dup (?)    ; holds destination sometimes
  52.  
  53. mv    proc    near
  54.  
  55.     ; Get arguments.
  56.     call    _args
  57.  
  58.     ; Check # of arguments- must be > 1
  59.     cmp    argc,1
  60.     ja    usageok
  61.     jmp    usage
  62.  
  63. usageok:
  64.     ; Get last argument; it's referred to often.
  65.     mov    si, argc
  66.     add    si, si
  67.     mov    si, argv[si]
  68.     mov    lastarg, si
  69.  
  70.     mov    lastargisdir, 0
  71.     mov    dx, si
  72.     mov    ax, 4300h
  73.     int    21h            ; Get file mode bits; err if no file.
  74.     jc    lastnotdir
  75.         test    cx, 10h        ; true if directory
  76.         jz    lastnotdir
  77.             mov    lastargisdir, 1        ; must be 0 or 1
  78. lastnotdir:
  79.  
  80.     ;------------- Check lastarg for special cases ------------
  81.     ;   \, /
  82.     mov    si, lastarg
  83.     cld
  84.     lodsb
  85.     cmp    al, '/'
  86.     jz    dest_maybe_root
  87.     cmp    al, '\'
  88.     jnz    dest_not_root
  89. dest_maybe_root:
  90.     lodsb
  91.     cmp    al, 0
  92.     jnz    dest_not_root
  93. dest_root:
  94.     inc    lastarg        ; make it point to null
  95.     jmp    not_renaming
  96. dest_not_root:
  97.     ;----- . and .. ---------------------------
  98.     ; First, just in case, get the current directory.
  99.     lea    si, dirbuf
  100.     mov    byte ptr [si], '\'
  101.     inc    si
  102.     mov    dl, 0
  103.     mov    ah, 47h
  104.     INT    21h
  105.     ; Now check the destination of the move.
  106.     mov    si, lastarg
  107.     lodsb
  108.     cmp    al, '.'
  109.     jnz    no_special_case
  110.     lodsb
  111.     cmp    al, 0
  112.     jnz    parent
  113.     ; moving to current directory.  Use dirbuf as destination.
  114.     mov    si, offset dirbuf
  115.     mov    lastarg, si
  116.     jmp    not_renaming
  117.  
  118. parent:
  119.     cmp    al, '.'
  120.     jnz    no_special_case
  121.     lodsb
  122.     cmp    al, 0
  123.     jnz    no_special_case
  124.     ; Moving to parent directory.
  125.     ; We must find the next-to-last \ and turn it into a null
  126.     ; in order to make the name of our parent directory.
  127.     ; But first, verify that we're not the top level.
  128.     lea    si, dirbuf
  129.     cmp    byte ptr [si][1], 0
  130.     jz    no_parent
  131.     mov    di, 0
  132. parlp:    lodsb
  133.     cmp    al, '\'
  134.     jz    par_slash
  135.     cmp    al, '/'
  136.     jnz    par_nslash
  137. par_slash:    mov    di, si
  138.         dec    di
  139. par_nslash:
  140.     cmp    al, 0
  141.     jnz    parlp
  142.  
  143.     cmp    di, offset dirbuf
  144.     jnz    got_parent
  145.         ; If parent is top level, need to turn char After
  146.         ; slash to a null.
  147.         inc    di
  148. got_parent:
  149.     mov    al, 0
  150.     stosb
  151.     jmp    not_renaming
  152. no_parent:
  153.     jmp    move_error
  154.  
  155. no_special_case:
  156.     ;-------------------------------------------------
  157.     ; renaming = !lastargisdir;
  158.     ; if (argc > 2 && renaming) error("What you tryin t'pull?");
  159.     mov    al, lastargisdir
  160.     xor    al, 1
  161.     mov    renaming, al
  162.     cmp    argc, 2
  163.     jz    wants_rename
  164.         or    al, al
  165.         jz    not_renaming
  166.             lea    dx, drmsg
  167.             mov    cx, drlen
  168.             jmp    err
  169. wants_rename:
  170. not_renaming:
  171.  
  172.     ;----- Main Loop -------
  173.     ; do {
  174.     ;   find_first_matching(argv[2]);
  175.     ;   repeat
  176.     ;       build_dest_filename;
  177.     ;       move;
  178.     ;       until renaming or (not find_next);
  179.     ;   shift;
  180.     ;   } while (argc != 1) and not renaming;
  181.  
  182. while_loop:
  183.     mov    dx, argv[2]
  184.     mov    cx, 0
  185.     call    ffirst
  186.     jc    while_done
  187.  
  188. rept_loop:
  189.     ; Make the destination filename.
  190.     ; if (renaming) then
  191.     ;    newfname := lastarg
  192.     ; else
  193.     ;    newfname := lastarg + '\' + basefilename;
  194.     test    renaming, -1
  195.     jz    mn_not_ren
  196.         push    lastarg
  197.         pop    newfname
  198.         jmp    short mn_done
  199. mn_not_ren:
  200.         cld            ; setup for string move
  201.         mov    di, offset dirbuf2
  202.         mov    newfname, di
  203.         mov    si, lastarg
  204. mn_cl:        lodsb
  205.         cmp    al, 0
  206.         jz    mn_addslash
  207.         stosb
  208.         jmp    mn_cl
  209. mn_addslash:    mov    al, '\'
  210.         stosb
  211.         mov    si, finder
  212.         add    si, basefn;
  213. mn_cl2:        lodsb
  214.         stosb
  215.         cmp    al, 0
  216.         jnz    mn_cl2
  217.  
  218. mn_done:
  219.     ;------------------------------------
  220.     ; Move.
  221.     mov    dx, offset fnam
  222.     mov    di, newfname
  223.     mov    ah, 56h
  224.     int    21h
  225.     jc    move_error
  226.  
  227.     ;       until renaming or (not find_next);
  228.     test    renaming, -1
  229.     jnz    while_done
  230.     call    fnext
  231.     jnc    rept_loop
  232.  
  233.     ;   shift;
  234.     call    _shift
  235.     dec    argc
  236.     cmp    argc, 1
  237.     jz    while_done
  238.     jmp    while_loop
  239.  
  240. while_done:
  241.     mov    al, 0        ; no error
  242. exit:
  243.     mov    ah, 4ch
  244.     int    21h        ; terminate process, return status in AL.
  245.  
  246. ;------------------------------------------------------------
  247. usage:
  248.     mov    dx, offset umsg
  249.     mov    cx, ulen
  250.     jmp    short err
  251.  
  252. move_error:
  253.     mov    dx, offset movmsg
  254.     mov    cx, movlen
  255.  
  256. err:    mov    ah, 40h
  257.     mov    bx, stderr
  258.     int    21h
  259.     mov    al, 1
  260.     jmp    exit
  261.  
  262. mv    endp
  263.  
  264. code    ends
  265.  
  266.     end    main
  267.  
  268.