ftpupload.xsh

Upload file via FTP

<?xml version="1.0" encoding="utf-8"?>
<xsharper xmlns="http://www.xsharper.com/schemas/1.0">
    <versionInfo title="FTPUpload" value="Command line utility to upload files to FTP server." Version="0.1.0.0" Copyright="(C) 2009 DeltaX Inc." />
    <usage options="ifNoArguments" />
	<param>Usage: FTPUpload [parameters] ftp-server file1 [file2..]</param>
	<param />
    <param value="Parameters:" />
    <param switch="passive" value="Use passive mode" unspecified="-1" count="none" default="false" typename="bool" />
    <param switch="text" value="Use text mode (default binary)" unspecified="-1" default="false" count="none" typename="bool" />
    <param switch="mkdir" value="Create directory first" unspecified="-1" default="false" count="none" typename="bool" />
    <param switch="skipexisting" value="Skip existing files" unspecified="-1" default="0" count="none" typename="bool" />
    <param switch="exitIfFirstExists" value="Exit if the first exists, w/o uploading subsequent files" unspecified="-1" default="0" count="none" typename="bool" />
    <param value="" />
    <param name="ftp-server" count="single" value="FTP server address as ftp://user:password@server/directory/" required="true" />
    <param name="files" count="multiple" required="true" description="filenames" value="files to upload" last="true" />

    <?header using System.Net; ?>

    <?code string server=c.GetString("ftp-server");
        
        NetworkCredential nc=null;
        
        UriBuilder ub=new UriBuilder(server);
        string origPath=ub.Path;
        if (!string.IsNullOrEmpty(ub.UserName) ||
            !string.IsNullOrEmpty(ub.Password))
        {
            nc=new NetworkCredential(ub.UserName??"",ub.Password??"");
            ub.UserName=null;
            ub.Password=null;
        }
        bool ssl=false;
        if (ub.Scheme=="ftps" || ub.Scheme=="ftpas" || ub.Scheme=="ftpsa")
        {
            ssl=true;
            ub.Scheme="ftp";
        }             
        
        System.Net.FtpWebRequest wr;
        if (c.GetBool("mkdir",false))
        {
            int n=ub.Path.LastIndexOf('/');
            if (n!=-1)
                ub.Path=ub.Path.Substring(0,n);

            c.Write(XS.OutputType.Info, "Checking directory " + ub.Path+ "...");
            bool create=false;
            try {
                wr = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(ub.Uri);
                if (nc!=null)
                    wr.Credentials=nc;
                wr.Proxy=null;
                wr.KeepAlive=false;
                wr.UsePassive=c.GetBool("passive",false);
                wr.Method = System.Net.WebRequestMethods.Ftp.PrintWorkingDirectory;
                using (FtpWebResponse response = (FtpWebResponse)wr.GetResponse())
                    ;
                c.WriteLine(XS.OutputType.Info, "Already exists.");
            }
            catch (WebException e)
            {
                c.WriteLine(XS.OutputType.Info, "Does not exist");
                create=true;
            }
                
            if (create)
            {
                c.Write(XS.OutputType.Info, "Creating directory " + ub.Path+ "...");
                wr = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(ub.Uri);
                if (nc!=null)
                    wr.Credentials=nc;
                wr.Proxy=null;
                wr.KeepAlive=true;
                wr.Method = System.Net.WebRequestMethods.Ftp.MakeDirectory;
                c.WriteLine(XS.OutputType.Info, "Done.");
            }
        }
        
        int pr=10;
        int step=90/(c.GetStringArray("files").Length);
        bool first=true;
        foreach (string filename in c.GetStringArray("files"))
        {
            c.OnProgress(pr);
            step+=pr;
            // Upload file
            FileInfo fileInf = new FileInfo(filename);
            ub.Path=origPath;
            if (ub.Path.EndsWith("/"))
                ub.Path=ub.Path+Uri.EscapeDataString(fileInf.Name);         
                
            c.Write(XS.OutputType.Info, "Uploading " + ub.Uri + "...");
                        
            if (c.GetBool("skipexisting") || (c.GetBool("exitIfFirstExists") && first))
            {
                wr = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(ub.Uri);
                wr.UseBinary=!c.GetBool("text",false);
                wr.UsePassive=c.GetBool("passive",false);
                if (ssl)
                    wr.EnableSsl=ssl;
                if (nc!=null)
                    wr.Credentials=nc;
                wr.KeepAlive=false;
                wr.Proxy=null;
                wr.Method = System.Net.WebRequestMethods.Ftp.GetFileSize;
                bool upload=false;
                try {
                    using (FtpWebResponse response = (FtpWebResponse)wr.GetResponse())
                        ;
                }
                catch (WebException)
                {
                    upload=true;
                }
                if (!upload)
                {
                    c.WriteLine(XS.OutputType.Info, "Already exists.");             
                    if (c.GetBool("exitIfFirstExists") && first)
                        return null;
                    continue;           
                }
            }
            
            first=false;
            
            wr = (System.Net.FtpWebRequest)System.Net.FtpWebRequest.Create(ub.Uri);
            wr.UseBinary=!c.GetBool("text",false);
            wr.UsePassive=c.GetBool("passive",false);
            if (ssl)
                wr.EnableSsl=ssl;
            if (nc!=null)
                wr.Credentials=nc;
            wr.KeepAlive=false;
            wr.Proxy=null;
            wr.Method = System.Net.WebRequestMethods.Ftp.UploadFile;
            
            byte[] buf = new byte[2048];
            wr.ContentLength = fileInf.Length;
            using (FileStream fs = fileInf.OpenRead())
            {
                
                using (Stream strm = wr.GetRequestStream())
                {
                    int writeSince=0;
                    int len;
                    while ((len=fs.Read(buf,0,buf.Length))!=0)
                    {
                        c.CheckAbort();
                        c.OnProgress(1);
                        strm.Write(buf,0,len);
                        writeSince+=len;
                        if (writeSince>1024*10)
                        {
                            writeSince=0;
                            c.Write(XS.OutputType.Info,".");
                        }
                        
                    }
                }
            }
            using (FtpWebResponse response = (FtpWebResponse)wr.GetResponse())
                ;


            c.WriteLine(XS.OutputType.Info, "Done.");
            
            


        }       
            
    ?>
</xsharper>