home *** CD-ROM | disk | FTP | other *** search
/ Magazyn Amiga Shareware Floppies / ma64.dms / ma64.adf / FTPMount-1.0 / Source / split.c < prev    next >
C/C++ Source or Header  |  1995-12-10  |  5KB  |  269 lines

  1. /*
  2.  * This source file is Copyright 1995 by Evan Scott.
  3.  * All rights reserved.
  4.  * Permission is granted to distribute this file provided no
  5.  * fees beyond distribution costs are levied.
  6.  */
  7.  
  8. #include <exec/types.h>
  9. #include <exec/memory.h>
  10. #include <exec/alerts.h>
  11.  
  12. #include <dos/dos.h>
  13. #include <dos/dosextens.h>
  14. #include <dos/dostags.h>
  15.  
  16. #include <proto/exec.h>
  17. #include <proto/dos.h>
  18.  
  19. #include <stdio.h>
  20. #include <stdlib.h>
  21. #include <string.h>
  22.  
  23. #include "evtypes.h"
  24. #include "verify.h"
  25. #include "tcp.h"
  26.  
  27. #include "site.h"
  28. #include "ftp.h"
  29. #include "split.h"
  30.  
  31. #include "globals.h"
  32.  
  33. boolean collapse(b8 *s)
  34. {
  35.     b8 *t, *u;
  36.     
  37.     t = s;
  38.     u = s;
  39.     
  40.     /* . & .. are illegal */
  41.     if (u[0] == '.') {
  42.         if (u[1] == 0) return false;
  43.         if (u[1] == '/') return false;
  44.         if (u[1] == '.') {
  45.             if (u[2] == 0) return false;
  46.             if (u[2] == '/') return false;
  47.         }
  48.     }
  49.     
  50.     while (*u) {
  51.         if (t == s && u[0] == '/') {
  52.             // return false; // used to do this, but people didn't want it to error
  53.             u++;    /* ignore it */
  54.             continue;
  55.         }
  56.         
  57.         if (u[0] == '/' && u[1] == '.') {
  58.             if (u[2] == 0) return false;
  59.             if (u[2] == '/') return false;
  60.             if (u[2] == '.') {
  61.                 if (u[3] == 0) return false;
  62.                 if (u[3] == '/') return false;
  63.             }
  64.         }
  65.         
  66.         if (u[0] == '/' && u[1] == '/') {
  67.             while (--t > s) {
  68.                 if (*t == '/') break;
  69.             }
  70.             u++;
  71.             if (t == s) u++;
  72.         } else {
  73.             *t++ = *u++;
  74.         }
  75.     }
  76.     
  77.     if (t > s && t[-1] == '/') t[-1] = 0;    /* cull the trailing '/' */
  78.     
  79.     *t = 0;
  80.     
  81.     return true;
  82. }
  83.  
  84. boolean split_data(lock *l, b8 *z, split *sd)
  85. {
  86.     b8 *s, *t;
  87.     int len1, len2, len3;
  88.     /* 
  89.      * sigh ... all that work to separate the libs to processes ... just
  90.      * given up and used the global DosBase here
  91.      */
  92.     struct DevProc *dp;
  93.     
  94.     truth(z != nil);
  95.     
  96.     if (!l && z[0] == 0) {
  97.         
  98.         sd->port = local_port;
  99.         sd->path = nil;
  100.         
  101.         sd->work = nil;
  102.  
  103.         return true;
  104.     }
  105.     
  106.     s = (b8 *)allocate(z[0] + 1, V_cstr);
  107.     if (!s) {
  108.         sd->work = nil;
  109.         return false;
  110.     }
  111.     
  112.     if (z[0])
  113.         memcpy(s, &z[1], z[0]);
  114.  
  115.     s[z[0]] = 0;
  116.     
  117.     sd->work = s;
  118.  
  119.     for (; ; s++) {    
  120.         if (!*s) {
  121.             z = sd->work;
  122.             break;
  123.         }
  124.         
  125.         if (*s == ':') {
  126.             s++;
  127.             dp = GetDeviceProc(sd->work, nil);
  128.             if (!dp) {
  129.                 deallocate(sd->work, V_cstr);
  130.                 sd->work = nil;
  131.                 return false;
  132.             }
  133.             
  134.             l = (lock *)(dp->dvp_Lock << 2);
  135.             
  136.             FreeDeviceProc(dp);
  137.             
  138.             z = s;
  139.             
  140.             break;
  141.         }
  142.     }
  143.     
  144.     /* have to look at lock to see where we are relative to */
  145.     
  146.     if (!l || (l->port == local_port && l->rfsl == ftphosts_lock)) {
  147.         s = z;
  148.         goto resolve;
  149.     }
  150.     
  151.     verify(l, V_lock);
  152.     
  153.     if (l->port == local_port) {    /* most handlers might allow this, but there's no point */
  154.         show_string("Split Fail B");
  155.         deallocate(sd->work, V_cstr);
  156.         sd->work = nil;
  157.         return false;
  158.     }
  159.     
  160.     /* construct a full path name so we can collapse it sensibly */
  161.     
  162.     if (l->fname[0] == 0) {
  163.         len1 = strlen(l->port->mp_Node.ln_Name);
  164.         len2 = strlen(z);
  165.         
  166.         s = (b8 *)allocate(len1 + len2 + 2, V_cstr);
  167.         if (!s) {
  168.             deallocate(sd->work, V_cstr);
  169.             sd->work = nil;
  170.             return false;
  171.         }
  172.         
  173.         strcpy(s, l->port->mp_Node.ln_Name);
  174.         
  175.         if (sd->work[0]) {
  176.             s[len1] = '/';
  177.             strcpy(&s[len1 + 1], z);
  178.         } else {
  179.             s[len1] = 0;
  180.         }
  181.         
  182.         deallocate(sd->work, V_cstr);
  183.         sd->work = s;
  184.     } else {
  185.         len1 = strlen(l->port->mp_Node.ln_Name);
  186.         len2 = strlen(l->fname);
  187.         len3 = strlen(z);
  188.         
  189.         s = (b8 *)allocate(len1 + len2 + len3 + 3, V_cstr);
  190.         if (!s) {
  191.             deallocate(sd->work, V_cstr);
  192.             sd->work = nil;
  193.             return false;
  194.         }
  195.         
  196.         strcpy(s, l->port->mp_Node.ln_Name);
  197.         s[len1] = '/';
  198.         strcpy(&s[len1 + 1], l->fname);
  199.         if (sd->work[0]) {
  200.             s[len1 + len2 + 1] = '/';
  201.             strcpy(&s[len1 + len2 + 2], z);
  202.         } else {
  203.             s[len1 + len2 + 1] = 0;
  204.         }
  205.         deallocate(sd->work, V_cstr);
  206.         sd->work = s;
  207.     }
  208.     
  209. resolve:
  210.     if (!collapse(s)) {
  211.         deallocate(sd->work, V_cstr);
  212.         sd->work = nil;
  213.         return false;
  214.     }
  215.     
  216.     for (t = s; *t; t++) {
  217.         if (*t == '/') {
  218.             *t++ = 0;
  219.             sd->port = get_site(s);
  220.             if (!sd->port) {
  221.                 deallocate(sd->work, V_cstr);
  222.                 sd->work = nil;
  223.                 return false;
  224.             }
  225.             if (t[0])
  226.                 sd->path = t;
  227.             else
  228.                 sd->path = nil;
  229.             return true;
  230.         }
  231.     }
  232.     
  233.     if (s[0] == 0) {
  234.         deallocate(sd->work, V_cstr);
  235.         sd->work = nil;
  236.         sd->path = nil;
  237.         sd->port = local_port;
  238.         return true;
  239.     }
  240.     
  241.     /* ok, we don't have a '/' so check for .info or Unnamed or
  242.        Disk or Default ... they are "special" */
  243.     if (stricmp(s, "Disk") == 0 ||
  244.             strnicmp(s, "Unnamed", 7) == 0 ||
  245.             stricmp(s, ".backdrop") == 0 ||
  246.             stricmp(s, "Default") == 0 ||
  247.             stricmp(&s[strlen(s) - 5], ".info") == 0) {
  248.         sd->port = local_port;
  249.         sd->path = s;
  250.         return true;
  251.     }
  252.     
  253.     sd->port = get_site(s);
  254.     deallocate(sd->work, V_cstr);
  255.     sd->work = nil;
  256.     sd->path = nil;
  257.     
  258.     if (!sd->port) return false;
  259.     return true;
  260. }
  261.  
  262. void end_split(split *sd)
  263. {
  264.     if (sd->work) {
  265.         deallocate(sd->work, V_cstr);
  266.         sd->work = nil;
  267.     }
  268. }
  269.