플젝을 뛰다보면....FTP 전송을 위한 client program이 필요로 하는 경우가 종종 잇다.
특히 과금쪽 분야는 거의 필수라고 해야되나 ? 꼭 백업라인 또는 전송 라인에서 추가된다.
그래서 이번 플젝 뛰면서 FTP 전송부분 검토하는 김에 정리해보록 하였다.

유닉스/리눅스 시스템에서 FTP 전송을 위해서는 다음의 3가지 방법이 많이 사용된다. 더 있는지는 모르겟다.

1. Shell Script
2. C/C++ system command
3. FTP Client module

1. Shell Script

통상적으로 FTP 전송을 수행 하는 FTP Client는 shell program을 많이 사용한다.
target에 ftp 전송으로 실행 모듈을 전송한다거나, 특정 폴더로 binary file을 전송하는 유틸리티들은
shell script을 만들어놓고 shell script를 수행 시킴으로 특정 파일을 전송하도록 하는 테크닉을 많이 사용한다.

ftpput.sh
#
# USING : ftpput SERVERIP USERID PASSWD FILENAME
#
ftp -i -n <<ENDOFFTP
open $1
user $2 $3
bin
prompt
hash
cd .
put $4
close
bye
ENDOFFTP

위의 script는 특정 서버, 특정 유저, 특정 파일을 binary 모드로 FTP put 하는 script 이다. 참 쉽죠잉...

2. C/C++에서 system command를 사용하는 방법.

shell script를 사용하는 경우 보다 processor에서 자동으로 특정 폴더를 검색하다가 전송 대상 파일이 검색되면 FTP 전송을
시도 한다거나, Network 설계상의 문제 또는 정책상의 문제로, file bypass를 해야하는 processor가 존재해야하는 경우가
종종 있는데, 그런 경우 C/C++ program에서 FTP file 전송을 해야 할 필요가 있다.
이런 경우, CentOS, Ubuntu linux 에서는 ftpput/ftpget/wput/wget 등의 utility를 C/C++ application에서
system command를 사용하여 호출하는 방법이 구현하기 쉽다.
단지, system function의 return 값이 해당 실행대상의 정상/비정상 실행여부와 상관없이, 호출만 되면 success로
return하기 때문에 장애처리는 불가능한 단점이 있다.

ftpput.c

#include <stdlib.h>
#define MAXSTR  256
typedef struct {
        char    szDestAddr[MAXSTR];
        char    szUser[MAXSTR];
        char    szPass[MAXSTR];
        char    szDestDir[MAXSTR];
        char    szFilename[MAXSTR];
} stCTRL;
main ()
{
        int     nRet;
        char    szTemp[MAXSTR*2];
        stCTRL  stCtrl;
        // Init
        strcpy (stCtrl.szDestAddr, "192.168.10.10");
        strcpy (stCtrl.szUser, "ftpuser");
        strcpy (stCtrl.szPass, "ftpuserpass");
        strcpy (stCtrl.szDestDir, ".");
        strcpy (stCtrl.szFilename, "TESTDATA.dat");
        // Exec
        sprintf (szTemp, "./ftpput --server=%s --user=%s --pass=%s --dir=%s --binary %s &",
                 stCtrl.szDestAddr, stCtrl.szUser, stCtrl.szPass, stCtrl.szDestDir, stCtrl.szFilename);
        nRet = system (szTemp);
        if (nRet < 0)
                printf ("FAIL %s\n", szTemp);
        else
                printf ("SUCCESS %s\n", szTemp);
        exit (0);
}

ftpput - perl source
출처 : http://unixwiz.net/tools/ftpput.html
#!/usr/bin/perl -w
#
# $Id: //websites/unixwiz/unixwiz.net/webroot/tools/ftpput.txt#1 $
#
# written by : Stephen J. Friedl
#               Software Consultant
#               Tustin, California USA
#
# This very simple program is a kind of inverse to wget for ftp: it
# *puts* files to a remote FTP server and returns an exit code that
# reports accurately success or failure.
#
# All the parameters are given on the command line (no .netrc support)
#
# COMMAND LINE PARAMS
# --------------------
#
# --help Display a short help listing
#
# --server=S    Use "S" as the remote FTP server to connect to. We don't
#               need the leading "ftp://" part (but it's stripped off if
#               provided). This is REQUIRED.
#
# --user=U      Use "U" as the login name as required by the remote machine.
#               In the absense of one, "anonymous" is used.
#
# --pass=P      Use "P" for the password on the remote machine.
#
# --dir=D       Change to directory D on the remote system before doing
#               any transfers. If not provided, the directory is not
#               changed before doing a transfer.
#
# --passive     Use passive (PASV) mode for this transfer, which is
#               required by some servers and some firewalls. If not
#               specified, active mode is used.
#
# --hash        Print a hash mark ("#") every 1024 bytes during the transfer
#               to watch it run.
#
# --verbose     Show the name of each file being sent. This is much less info
#               than the --debug option
#
use strict;
use warnings;
use Net::FTP;
my $Version = "unixwiz.net ftpput - version 1.0 (2003/05/09)";
my $server  = undef;
my $user    = undef;
my $pass    = undef;
my $dir     = undef;
my $debug   = 0;
my $hash    = 0;
my $passive = 0;
my $binary  = 0;
my $ascii   = 0;
my $verbose = 0;
my @FILES = ();
foreach ( @ARGV )
{
 if ( m/^--help/i )
 {
  print STDERR <<EOF;
$Version
usage: $0 [options] --server=SVR file files...
  --help        Show this brief help listing
  --debug       Enable debugging
  --server=SVR  Send to FTP server SVR
  --user=U      Login as user U (default = anonymous)
  --pass=P      Use password P (default = "-anonymous\@")
  --dir=D       Change to directory D on remote system
  --passive     Use passive mode instead of active
  --binary      Select binary mode
  --ascii       Select ASCII mode
  --hash        Print a hash (#) every 1024 bytes during transfer
  --verbose     Show each filename as it's being sent
  Full pathnames on the command line do NOT translate into directory
  names on the remote machine: the --dir=D parameter determines the
  final location exclusively. This program does not consult any .netrc
  files.
  This program exits 0=success and nonzero=failure.
EOF
  exit 1;
 }
 elsif ( m/^--user=(.+)$/ )                      # --user=U
 {
  $user = $1;
 }
 elsif ( m/^--pass(?:word)?=(.+)$/ )             # --pass=PASS
 {
  $pass = $1;
 }
 elsif ( m/^--dir=(.+)$/ )                       # --dir=DIR
 {
  $dir = $1;
 }
 elsif ( m/^--server=(.+)$/ )                    # --server=SVR
 {
  $server = $1;
 }
 elsif ( m/^--debug$/ )                          # --debug
 {
  $debug++;
 }
 elsif ( m/^--verbose$/ )                        # --verbose
 {
  $verbose++;
 }
 elsif ( m/^--passive$/ )                        # --passive
 {
  $passive = 1;
 }
 elsif ( m/^--hash$/ )                           # --hash
 {
  $hash = 1;
 }
 elsif ( m/^--binary$/ )                         # --binary
 {
  $binary = 1;
 }
 elsif ( m/^--ascii$/i )                         # --ascii
 {
  $ascii = 1;
 }
 elsif ( m/^-/ )
 {
  die "ERROR: {$_} is an invalid cmdline parameter\n";
 }
 elsif ( -r $_ )
 {
  push @FILES, $_;
 }
 else
 {
  die "ERROR: cannot open file {$_} for reading\n";
 }
}
 
#------------------------------------------------------------------------
# SANITY CHECKING ON PARAMETERS
#
$server =~ s|^ftp://|| if $server;
die "ERROR: missing file to send (try --help)\n" if @FILES == 0;
die "ERROR: missing --server (try --help)\n"  if not $server;
die "ERROR: can't provide both --binary and --ascii\n" if $binary and $ascii;
$user = "anonymous"   if not $user;
my $ftp;
my %FTPARGS = ();
$FTPARGS{Debug}   = $debug  if $debug;
$FTPARGS{Passive} = $passive  if $passive;
$FTPARGS{Hash}    = $hash  if $hash;
if ( not ( $ftp = Net::FTP->new( $server, %FTPARGS) ) )
{
 die "ERROR: cannot connect to FTP server $server\n";
}
if ( not $ftp->login($user, $pass) )
{
 die "ERROR: cannot login to $server with user $user\n";
}
if ( $dir )
{
 $ftp->cwd($dir) or die "ERROR: cannot cwd($dir)\n";
}
if ( $binary  )
{
 $ftp->binary() or die "ERROR: cannot set binary mode\n";
}
if ( $ascii )
{
 $ftp->ascii() or die "ERROR: cannot set ASCII mode\n";
}
foreach my $file ( @FILES )
{
 print "--> put $file\n"  if $verbose;
 if ( not $ftp->put($file) )
 {
  die "ERROR: cannot send $file\n";
 }
 print "    (sent OK)\n"  if $verbose;
}
$ftp->quit or die "ERROR: cannot quit FTP transfer\n";
exit 0;

3. FTP Client module C

1,2 번의 방법보다는 제일 확실한 방법으로서, FTP client C source를 직접 사용하는 방법으로
FTP 접속, 또는 전송중 장애가 발생한 경우 장애원인(cause)를 return 해줌으로서
장애처리까지 해야 하는 application의 경우는 반드시 이방법을 사용하여야 한다.

자세한 설명은 생략하고, 기냥 C source와, test application을 기록한다.

Remote directory path를 "YYYY/MM/DD" 와 같이 가변적인 경우, 그리고 FTP server 측에서 해당 Dir이 미생성인 경우에는
Client측에서 write 권한이 잇는 경우 생성 가능하여야 한다. 그런 이유로 다음의 function을 추가한다. (2010-08-20)

void    fnMkdirRemote (char *dirs)

Test_main.c

#include "p_ftp.h"
int main
(
 int  argc,
 char * argv[]
)
{
 int nRet;
 if (argc < 8)
 {
  // help
  printf ("usage:\n");
  printf ("\tftptest ServerIP User Pass Localdir Remotedir Sendfile Getfile\n");
  exit (0);
 }
 nRet = FtpPut_To_Host (argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);
 if (nRet < 0 )
 {
  printf ("Fail FTP FtpPut_To_Host File Name[%s]\n", argv[6]);
  switch (nRet)
  {
   case -1:
    printf ("[test_main.c] Connect FAILED\n");
    break;
   case -2:
    printf ("[test_main.c] Login FAILED\n");
    break;
   case -3:
    printf ("[test_main.c] Change local dir FAILED\n");
    break;
   case -4:
    printf ("[test_main.c] Change remote dir FAILED\n");
    break;
   case -5:
    printf ("[test_main.c] OPEN or FTP put FAILED\n");
    break;
   case -6:
    printf ("[test_main.c] Remote file rename FAILED\n");
    break;
   default:
    break;
  }
  return 0;
 }
 else
 {
  printf("SUCCESS FTP FtpPut_To_Host File Name[%s]\n", argv[6]);
 }
 nRet = FtpGet_To_Host (argv[1], argv[2], argv[3], argv[4], argv[5], argv[7]);
 if (nRet < 0 )
 {
  printf ("Fail FTP FtpGet_To_Host File Name[%s]\n", argv[7]);
  switch (nRet)
  {
   case -1:
    printf ("[test_main.c] Connect FAILED\n");
    break;
   case -2:
    printf ("[test_main.c] Login FAILED\n");
    break;
   case -3:
    printf ("[test_main.c] Change local dir FAILED\n");
    break;
   case -4:
    printf ("[test_main.c] Change remote dir FAILED\n");
    break;
   case -5:
    printf ("[test_main.c] FTP get FAILED\n");
    break;
   default:
    break;
  }
  return 0;
 }
 else
 {
  printf("SUCCESS FTP FtpGet_To_Host File Name[%s]\n", argv[7]);
 }
} /* end of main () */


p_ftp.h

/*------------------------------------------------------------------------------
 * function prototype
 *--------------------------------------------------------------------------- */
extern  int FtpPut_To_Host
(
    char    *ftpaddr,
    char    *user,
    char    *pass,
    char    *ldir,
    char    *rdir,
    char    *ftpsrc
);
extern  int FtpGet_To_Host
(
    char    *ftpaddr,
    char    *user,
    char    *pass,
    char    *ldir,
    char    *rdir,
    char    *ftpsrc
);
/*------------------------------------------------------------------------------
 * End of p_ftp.h
 *--------------------------------------------------------------------------- */
ftp_var.h

/*
 * FTP global variables.
 */
#define SMALL //
#include <sys/param.h>
#include <sys/socket.h>
#include <setjmp.h>
#if 0 //
#include <stringlist.h>
#endif // 0
#include <netinet/in.h>
#include <netdb.h>
#ifndef SMALL
#include <histedit.h>
#endif /* !SMALL */
#if 0 //
#include "extern.h"
#endif // 0
#define HASHBYTES 1024
#define FTPBUFLEN MAXPATHLEN + 200
#define STALLTIME 5 /* # of seconds of no xfer before "stalling" */
#define FTP_PORT 21 /* default if ! getservbyname("ftp/tcp") */
#define HTTP_PORT 80 /* default if ! getservbyname("http/tcp") */
#ifndef GATE_PORT
#define GATE_PORT 21 /* default if ! getservbyname("ftpgate/tcp") */
#endif
#ifndef GATE_SERVER
#define GATE_SERVER "" /* default server */
#endif
#define PAGER  "more" /* default pager if $PAGER isn't set */
/*
 * Options and other state info.
 */
int trace;   /* trace packets exchanged */
int hash;   /* print # for each buffer transferred */
int mark;   /* number of bytes between hashes */
//int sendport;  /* use PORT cmd for each data connection */
int epsv4;   /* use EPSV/EPRT cmds on IPv4 ftp */
//int verbose;  /* print messages coming back from server */
//int connected;  /* 1 = connected to server, -1 = logged in */
int fromatty;  /* input is from a terminal */
int interactive;  /* interactively prompt on m* cmds */
int confirmrest;  /* confirm rest of current m* cmd */
int debug;   /* debugging level */
int bell;   /* ring bell on cmd completion */
int doglob;   /* glob local file names */
int autologin;  /* establish user account on connection */
int proxy;   /* proxy server connection active */
int proxflag;  /* proxy connection exists */
int gatemode;  /* use gate-ftp */
char   *gateserver;  /* server to use for gate-ftp */
int sunique;  /* store files on server with unique name */
int runique;  /* store local files with unique name */
int mcase;   /* map upper to lower case for mget names */
int ntflag;   /* use ntin ntout tables for name translation */
int mapflag;  /* use mapin mapout templates on file names */
int preserve;  /* preserve modification time on files */
int progress;  /* display transfer progress bar */
//int code;   /* return/reply code for ftp command */
//int crflag;   /* if 1, strip car. rets. on ascii gets */
char pasv[BUFSIZ];  /* passive port for proxy data connection */
int passivemode;  /* passive mode enabled */
int restricted_data_ports; /* enable quarantine FTP area */
char   *altarg;   /* argv[1] with no shell-like preprocessing  */
char ntin[17];  /* input translation table */
char ntout[17];  /* output translation table */
char mapin[MAXPATHLEN]; /* input map template */
char mapout[MAXPATHLEN]; /* output map template */
//char typename[32];  /* name of file transfer type */
int type;   /* requested file transfer type */
//int curtype;  /* current file transfer type */
char structname[32];  /* name of file transfer structure */
int stru;   /* file transfer structure */
char formname[32];  /* name of file transfer format */
int form;   /* file transfer format */
char modename[32];  /* name of file transfer mode */
int mode;   /* file transfer mode */
char bytename[32];  /* local byte size in ascii */
int bytesize;  /* local byte size in binary */
int anonftp;  /* automatic anonymous login */
int dirchange;  /* remote directory changed by cd command */
int ttywidth;  /* width of tty */
char   *tmpdir;   /* temporary directory */
int     try_epsv;               /* try EPSV for this session */
#ifndef SMALL
int   editing;  /* command line editing enabled */
EditLine *el;   /* editline(3) status structure */
History  *hist;   /* editline(3) history structure */
char  *cursor_pos;  /* cursor position we're looking for */
size_t   cursor_argc;  /* location of cursor in margv */
size_t   cursor_argo;  /* offset of cursor in margv[cursor_argc] */
#endif /* !SMALL */
off_t bytes;   /* current # of bytes read */
off_t filesize;  /* size of file being transferred */
char   *direction;  /* direction transfer is occurring */
off_t restart_point;  /* offset to restart transfer */
char   *hostname;  /* name of host connected to */
int unix_server;  /* server is unix, can use binary for ascii */
int unix_proxy;  /* proxy is unix, can use binary for ascii */
char *ftpport;   /* port number to use for ftp connections */
char *httpport;   /* port number to use for http connections */
char *gateport;   /* port number to use for gateftp connections */
int dobind;   /* bind to specific address */
struct addrinfo * bindres0; /* addrinfo for address to bind to */
jmp_buf toplevel;  /* non-local goto stuff for cmd scanner */
char line[FTPBUFLEN]; /* input line buffer */
char *stringbase;  /* current scan point in line buffer */
char argbuf[FTPBUFLEN]; /* argument storage buffer */
char *argbase;  /* current storage point in arg buffer */
#if 0 //
StringList *marg_sl;  /* stringlist containing margv */
#endif // 0
int margc;   /* count of arguments on input line */
#define margv (marg_sl->sl_str) /* args parsed from input line */
//int     cpend;                  /* flag: if != 0, then pending server reply */
int mflag;   /* flag: if != 0, then active multi command */
int options;  /* used during socket creation */
/*
 * Format of command table.
 */
struct cmd {
 char *c_name; /* name of command */
 char *c_help; /* help string */
 char  c_bell; /* give bell when command completes */
 char  c_conn; /* must be connected to use command */
 char  c_proxy; /* proxy server may execute */
#ifndef SMALL
 char *c_complete; /* context sensitive completion list */
#endif /* !SMALL */
 void (*c_handler) __P((int, char **)); /* function to call */
};
struct macel {
 char mac_name[9]; /* macro name */
 char *mac_start; /* start of macro in macbuf */
 char *mac_end;  /* end of macro in macbuf */
};
int macnum;   /* number of defined macros */
struct macel macros[16];
char macbuf[4096];

p_ftp.c

#include <sys/cdefs.h>
#ifndef lint
#if 0
static char sccsid[] = "@(#)ftp.c 8.6 (Berkeley) 10/27/94";
__RCSID("$FreeBSD: src/usr.bin/ftp/ftp.c,v 1.28.2.6 2003/08/01 14:05:06 yar Exp $");
__RCSID_SOURCE("$NetBSD: ftp.c,v 1.29.2.1 1997/11/18 01:01:04 mellon Exp $");
#endif // 0
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <arpa/ftp.h>
#include <arpa/telnet.h>
#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#if 1 //
#include <fcntl.h>
#include <signal.h>
#endif // 1
#include <string.h>
#include <unistd.h>
#ifdef __STDC__
#include <stdarg.h>
#else
#include <varargs.h>
#endif
#include "ftp_var.h"
int data = -1;
int abrtflag = 0;
#if 0 //
jmp_buf ptabort;
#endif // 0
int ptabflg;
int ptflag = 0;
FILE *cin, *cout;
union sockunion {
 struct sockinet {
  u_char si_len;
  u_char si_family;
  u_short si_port;
 } su_si;
 struct sockaddr_in  su_sin;
 struct sockaddr_in6 su_sin6;
};
#define su_len  su_si.si_len
#define su_family su_si.si_family
#define su_port  su_si.si_port
union sockunion myctladdr, hisctladdr, data_addr;

#if 1 //
#define MAXLINE 1024
#define TYPE_A 1
#define TYPE_E 2
#define TYPE_I 3
#define TYPE_L 4
#define BINARY 0
#define ASCII 1
#define TENEX 2
#define PRELIM  1
#define COMPLETE 2
#define CONTINUE 3
#define ERROR  5
#ifdef DEBUG
int verbose = 5;
#else
int verbose = -1;
#endif
extern int errno;
int cpend = 0;
int curtype = 0;
int crflag = 1;
int sendport = -1;
int connected = 0;
char response_line[MAXLINE];
int code = -1;
int ftpsock;
FILE *responsefp;
FILE *commandfp;
struct sockaddr_in server;
// Function Prototypes
int initconn();
FILE *dataconn (char *lmode);
int command(char *fmt, ...);
int sendrequest(char *cmd, char *local, char *remote);
void file_close()
{
#if 0
 if(commandfp != NULL)
  fclose(commandfp);
 if(responsefp != NULL)
  fclose(responsefp);
#endif
 if(ftpsock)
  close(ftpsock);
}
int getreply(int expecteof)
{
 register int c, n;
 register int dig;
 register char *cp;
 int originalcode = 0, continuation = 0;
 int pflag = 0;
 void lostpeer();
 for (;;) {
  dig = n = code = 0;
  cp = response_line;
  while ((c = getc(responsefp)) != '\n') {
   if (c == IAC) {     /* handle telnet commands */
    switch (c = getc(responsefp)) {
     case WILL:
     case WONT:
      c = getc(responsefp);
      fprintf(commandfp, "%c%c%c", IAC, DONT, c);
      (void) fflush(commandfp);
      break;
     case DO:
     case DONT:
      c = getc(responsefp);
      fprintf(commandfp, "%c%c%c", IAC, WONT, c);
      (void) fflush(commandfp);
      break;
     default:
      break;
    }
    continue;
   }
   dig++;
   if (c == EOF) {
    if (expecteof) {
     code = 221;
     return (0);
    }
    lostpeer();
#if 0
    if (verbose) {
     printf ("421 Service not available, remote server has closed connection\n");
    }
#endif
    code = 421;
    return(4);
   }
   if (c != '\r' && (verbose > 0 || (verbose > -1 && n == '5' && dig > 4))) {
    (void) putchar(c);
   }
   if (dig < 4 && isdigit(c))
    code = code * 10 + (c - '0');
   if (!pflag && code == 227)
    pflag = 1;
   if (dig > 4 && pflag == 1 && isdigit(c))
    pflag = 2;
   if (dig == 4 && c == '-') {
    if (continuation)
    code = 0;
    continuation++;
   }
   if (n == 0)
    n = c;
   if (cp < &response_line[sizeof(response_line) - 1])
    *cp++ = c;
  }
  if ( (verbose > 0 || verbose > -1) && n == '5') {
   (void) putchar(c);
   (void) fflush (stdout);
  }
  if (continuation && code != originalcode) {
   if (originalcode == 0)
   originalcode = code;
   continue;
  }
  *cp = '\0';
  if (n != '1')
   cpend = 0;
  if (code == 421 || originalcode == 421)
   lostpeer();
  return (n - '0');
 }
}
int ftp_hookup(char *ftpAddr)
{
 struct hostent *gethostbyname();
 struct servent *sp;
 int len;
 struct sockaddr_in client;
 if((sp = getservbyname("ftp", "tcp")) == NULL) {
//  printf ("find port number\n");
  return -2;
 }
 client.sin_family = AF_INET;
 client.sin_addr.s_addr = inet_addr(ftpAddr);
 client.sin_port = sp->s_port;
 if((ftpsock = socket(client.sin_family, SOCK_STREAM, 0)) < 0) {
//  printf ("socket error addr=[%s]\n", ftpAddr);
  return -3;
 }
// alarm(1);
 if(connect(ftpsock, (struct sockaddr *) &client, sizeof(server)) < 0) {
  file_close();
  alarm(0);
//  printf ("ftp connect error=%d addr=[%s]\n", errno, ftpAddr);
  return -4;
 }
 alarm(0);
 len = sizeof(client);
  
 if (getsockname(ftpsock, (struct sockaddr *) &server, (socklen_t *) &len) < 0) {
//  printf ("ftp getsockname err=%d addr=[%s]\n", errno , ftpAddr);
  file_close();
  code = -1;
  return -5;
 }
 responsefp = fdopen(ftpsock, "r");
 commandfp = fdopen(ftpsock, "w");
 if(responsefp == NULL || commandfp == NULL) {
//  printf ("fdopen error\n");
  file_close();
  return -5;
 }
 /* read startup message from server */
 if(verbose <= 0) {
  //printf ("Connected to %s\n", ftpAddr);
 }
 if(getreply(0) > 2) {
  file_close();
  code = -1;
//  printf ("Service not available\n");
  return -6;
 }
#ifdef SO_OOBINLINE
 {
  int on = 1;
  if(setsockopt(ftpsock, SOL_SOCKET, SO_OOBINLINE, (char *)&on, sizeof(int)) < 0) {
//   printf ("ftp: setsockopt\n");
  }
 }
#endif
 return 0;
}
int command_dataconn(FILE **a_file, char *lmode, char *fmt, ...)
{
 va_list ap;
 int r;
// FILE *dataconn();
 abrtflag = 0;
 if (commandfp == NULL) {
  /*
  perror ("No control connection for command");
  */
  code = 421;
  return 0;
 }
 va_start(ap, fmt);
 //fmt = (char *)va_arg(ap, char *);
 vfprintf(commandfp, fmt, ap);
 va_end(ap);
 fprintf(commandfp, "\r\n");
 (void) fflush(commandfp);
 cpend = 1;
 r = getreply(!strcmp(fmt, "QUIT"));
 if(r == PRELIM)
  *a_file = dataconn(lmode);
 return r;
}
void lostpeer()
{
 if (connected) {
  if (commandfp != NULL) {
   (void) shutdown(fileno(commandfp), 1+1);
   (void) fclose(commandfp);
   commandfp = NULL;
  }
  if (data >= 0) {
   (void) shutdown(data, 1+1);
   (void) close(data);
   data = -1;
  }
  connected = 0;
 }
}
void quit_ftp()
{
 connected = 0;
 if(commandfp)
  (void) command("QUIT");
 file_close();
 data = -1;
 system("/bin/rm -rf /usr/tmp/sched* /usr/tmp/ftptl*");
}
int ftp_login(char *user, char *pass)
{
 int n;
 n = command("USER %s", user);
 switch(code) {
  case 331: /* 331 : User name okay, need password. */
   break;
  case 220:
   cpend = 1;
   n = getreply(0);
   break;
  case 500:
//   printf ("ftp: connection failed\n");
   quit_ftp();
   return -1;
  case 530:
//   printf ("ftp: login unknown\n");
   quit_ftp();
   return -2;
  case 421:
//   printf ("ftp: service not available\n");
   quit_ftp();
   return -3;
  default:
//   printf ("ftp: error code (%d)\n", code);
   quit_ftp();
   return -4;
 }
 if(n == 3) {    /* CONTINUE */
  code = 0;
  n = command("PASS %s", pass);
  //if(n == ERROR || code == 421) {
  /* 230 : User logged in, proceed.  */
   if(code != 230){
#if 0
    if(code == 421)
     printf ("ftp: [%s]\n", &response_line[4]);
    else
     printf ("ftp: connect failed1\n");
#endif
    quit_ftp();
    return -4;
   }
  //}
 }
 if(n != 2) { /* COMPLETE */
  return -5;
 }
 return 0;
}
void disconnect()
{
 quit_ftp();
}
#if 1   // [20Aug10] Make remote dir
void    fnMkdirRemote (char *dirs)
{
    char    szMkPath[512];
    char    *pToken;
    pToken = (char *) strtok (dirs, "/");
    if (pToken != NULL)
    {
        memset (&szMkPath, 0x00, sizeof (szMkPath));
        strcpy (szMkPath, pToken);
        command ("MKD %s", szMkPath);
        while (1)
        {
            pToken = (char *) strtok (NULL, "/");
            if (pToken != NULL)
            {
                sprintf (szMkPath, "%s/%s", szMkPath, pToken);
                command ("MKD %s", szMkPath);
            }
            else
                break;
        }
    }
}
#endif
int change_remote_dir(char *dirs)
{
 char *dir = NULL;
 /* printf("[change_remote_dir] dir=%s\n", dirs); */
 if((dir = (char *)strdup(dirs)) == NULL)
  return -1;
 code = -1;
 command("CWD %s", dir);
 /* 250 CWD command successful */
 /* 550 k: No such file or directory */
 if(code !=250){
  if(code == 550) {
#if 1
            // [20Aug10] Mkdir and retry CWD
            //command ("MKD %s", dir);
            fnMkdirRemote (dirs);
         command("CWD %s", dir);
            if (code == 550)
            {
       quit_ftp();
       return -2;
            }
#else
//   printf ("ftp3: %s\n", strchr(response_line, ':'));
   quit_ftp();
   return -2;
#endif  // !1
  }
  else{
//   printf ("ftp3: error code[%d]\n", code);
   quit_ftp();
   return -2;
  }
 }
 return 0;
}
struct  types {
 char *t_name;
 char *t_mode;
 int t_type;
 char *t_arg;
} types[] = {
 { "binary", "I",    TYPE_I, 0 },
 { "ascii",  "A",    TYPE_A, 0 },
 { "tenex",  "L",    TYPE_L, "8" },
/*
 { "image",  "I",    TYPE_I, 0 },
 { "ebcdic", "E",    TYPE_E, 0 },
*/
};
/* Set transfer type.  */
void settype(int type)
{
 register struct types *p;
 int comret;
 if ((unsigned int) type > (sizeof(types)/sizeof(types[0]))) {
//  printf ("%d: unknown mode\n", type);
  code = -1;
  return;
 }
 /* make sure values in window match table! */
 p = &types[type];
 if ((p->t_arg != NULL) && (*(p->t_arg) != '\0')) {
  comret = command ("TYPE %s %s", p->t_mode, p->t_arg);
 } else {
  comret = command("TYPE %s", p->t_mode);
 }
 if (comret == 2) {  /* COMPLETE */
  curtype = p->t_type;
 }
}
int put_file(char *name, char *remote_name)
{
 int rval;
 settype(BINARY);
 rval = sendrequest("STOR", name, remote_name);
 switch (rval) {
  case 1:
   /* non_fatal error */
//   printf ("ftp4: %s\n", strchr(response_line, ':'));
   rval = -7;
   break;
  case 2:
   rval = -5;
   break;
 }
 return rval;
}
int ftp_rename_file(char *name, char *new_name)
{
 settype(BINARY);
/********  RENAME FILE   ********/
 /* RNFR from-filename  */
 command("RNFR %s", name);
 /* RNFR ?깃났??寃쎌슦?먮쭔 RNTO ?쒕떎 */
 if(code != 350) {
  //printf ("ftp[RNFR]: %s\n", response_line);
  quit_ftp(); 
  return -2;
 }
 /* RNTO to-filename */
 command("RNTO %s", new_name); 
 if(code != 250) {
  quit_ftp(); 
  return -2;
 }
/********  RENAME FILE END  ********/
 return 0;
}

int pwd_remote_dir()
{
 code = -1;
 //command("CDUP");
 command("PWD");
 /* printf("PWD : %s\n", response_line); */
 /* 257 CWD command successful */
 if(code != 257) {
//  printf ("ftp2: %s\n", strchr(response_line, ':'));
  quit_ftp();
  return -2;
 }
 return 0;
}

#endif // !1

/*VARARGS*/
#if 1 //
int command(char *fmt, ...)
{
 va_list ap;
 int r;
 abrtflag = 0;
 if (commandfp == NULL) {
//  printf ("commandfp is NULL\n");
  code = 421;
  return (0);
 }
 va_start(ap, fmt);
 //va_start(ap, (void)nmb);
 //fmt = (char *)va_arg(ap, char *);
/*
#ifdef DEBUG
 fprintf(stderr, "SEND->");
 vfprintf(stderr, fmt, ap);
 fprintf(stderr, "\n");
#endif
*/
 vfprintf(commandfp, fmt, ap);
 va_end(ap);
 fprintf(commandfp, "\r\n");
 (void) fflush(commandfp);
 cpend = 1;
 r = getreply(!strcmp(fmt, "QUIT"));
 return(r);
}
int
empty (fd_set *mask, int sec)
#else
int
empty(mask, sec)
 fd_set *mask;
 int sec;
#endif // !1
{
 struct timeval t;
 t.tv_sec = (long) sec;
 t.tv_usec = 0;
 return (select(32, mask, (fd_set *) 0, (fd_set *) 0, &t));
}
#if 1 //
int sendrequest(char *cmd, char *local, char *remote)
{
 struct stat st;
 struct timeval start, stop;
 register int c, d;
 FILE *fin = NULL, *dout = 0, *popen();
 int (*closefunc)(), pclose(), fclose();
 long bytes = 0;
 char *lmode, buf[BUFSIZ], *bufp;
 int errormsg=0;
 closefunc = NULL;
 lmode = "w";
 fin = fopen(local, "r");
 if (fin == NULL) {
  code = -1;
  //printf ("return No Such File\n");
  return 0;
 }
 closefunc = fclose;
 if (fstat(fileno(fin), &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) {
  fclose(fin);
  fin = NULL;
  code = -1;
//  printf (" return permission denied[%s]\n", local);
  return 1;
 }
 if (initconn()) {
  code = -1;
  if (closefunc != NULL)
            fclose (fin);
//   (*closefunc)(fin);
  return 0;
 }
 if (command_dataconn(&dout, lmode, "%s %s", cmd, remote) != PRELIM)
 {
  if (closefunc != NULL)
            fclose (fin);
//   (*closefunc)(fin);
//  printf ("remote-command != PRELIM, CODE is %d\n", code);
  /* Permission denied */
  return 1;
 }
 if (dout == NULL)
 {
//  printf (" Abort Transfer : 0\n");
  goto abort;
 }
 (void) gettimeofday(&start, (struct timezone *)0);
 switch (curtype) {
  case TYPE_I:
  case TYPE_L:
   errno = d = 0;
   while ((c = read(fileno(fin), buf, sizeof (buf))) > 0) {
    bytes += c;
    for (bufp = buf; c > 0; c -= d, bufp += d)
     if ((d = write(fileno(dout), bufp, c)) <= 0) {
      break;
     } else {
      /* change image */
     }
   }
   if (c < 0) {
//    fprintf(stderr, "local: %s: strerror[%d]\n", local, errno);
    errormsg = 1;
   }
   if (d < 0) {
    errormsg = 1;
    goto abort;
   }
   break;
  case TYPE_A:
   while ((c = getc(fin)) != EOF) {
    if (c == '\n') {
     if (ferror(dout))
      break;
     (void) putc('\r', dout);
     /* change image */
     bytes++;
    }
    (void) putc(c, dout);
    /* change image */
    bytes++;
    /* if (c == '\r') { */
     /* (void)  putc('\0', dout);*/ /*this violates rfc */
     /* bytes++; */
    /* } */
   }
   if (ferror(fin)) {
    errormsg = 1;
//    printf ("local: %s: strerror [%d]\n", local, errno);
   }
   if (ferror(dout)) {
    if (errno != EPIPE)
     perror("netout");
    bytes = -1;
   }
   break;
 }
 (void) gettimeofday(&stop, (struct timezone *)0);
 if (closefunc != NULL)
        fclose (fin);
//  (*closefunc)(fin);
 (void) fclose(dout);
 dout = NULL;
 (void) getreply(0);
 if (!errormsg)
  return 0;
abort:
 if (!cpend) {
  code = -1;
  return 0;
 }
 if (data >= 0) {
  (void) close(data);
  data = -1;
 }
 if (dout) {
  (void) fclose(dout);
  dout = NULL;
 }
 (void) getreply(0);
 code = -1;
 if (closefunc != NULL && fin != NULL)
        fclose (fin);
//  (*closefunc)(fin);
 if (!errormsg)
  return 2;
 return 0;
}
#endif // !1
void
abortrecv(int notused)
{
#if 0 //
 alarmtimer(0);
#endif
 mflag = 0;
 abrtflag = 0;
 puts("\nreceive aborted\nwaiting for remote to finish abort.");
 (void)fflush(stdout);
#if 0 //
 longjmp(recvabort, 1);
#endif // 0
}
#if 1 //
int recvrequest(char *cmd, char *local, char *remote, char *lmode)
{
 FILE *fout = NULL, *din = 0, *popen();
// int (*closefunc)(), pclose(), fclose();
 int (*closefunc)();
 int is_retr, tcrflag, bare_lfs = 0;
 char *gunique();
 static int bufsize;
 static char *buf;
 long bytes = 0;
 register int c, d;
 struct timeval start, stop;
 struct stat st;
 off_t lseek();
 int errormsg=0;
 void abort_remote(FILE *din);
 is_retr = (strcmp(cmd, "RETR") == 0);
 closefunc = NULL;
 tcrflag = !crflag && is_retr;
 if (initconn()) {
  code = -1;
  return 0;
 }
 if (command_dataconn(&din, "r", "%s %s", cmd, remote) != PRELIM) {
//  printf ("Get %s failed.\n", remote);
  return -3;
 }
 fout = fopen(local, lmode);
 if (fout == NULL) {
//  printf ("local: %s: strerror [%d]\n", local, errno);
  errormsg = 1;
  goto abort;
 }
// closefunc = fclose;
 if (fstat(fileno(fout), &st) < 0 || st.st_blksize == 0)
  st.st_blksize = BUFSIZ;
 if (st.st_blksize > bufsize) {
  if (buf)
  (void) free(buf);
  buf = (char *) malloc((unsigned)st.st_blksize);
  if (buf == NULL) {
   perror("malloc");
   bufsize = 0;
   goto abort;
  }
  bufsize = st.st_blksize;
 }
 (void) gettimeofday(&start, (struct timezone *)0);
 switch (curtype) {
  case TYPE_I:
  case TYPE_L:
   errno = d = 0;
   while ((c = read(fileno(din), buf, bufsize)) > 0) {
    if ((d = write(fileno(fout), buf, c)) <= 0)
     break;
    /* change image */
    if (d != c)
     break;
/********
    if ((d = write(fileno(fout), buf, c)) != c)
     break;
******/
    bytes += c;
   }
   if (c < 0) {
    if (errno != EPIPE)
     perror("netin");
    bytes = -1;
   }
   if (d < c) {
    errormsg = 1;
    if (d < 0) {
//     printf ("local: %s: strerror [%d]\n", local, errno);
     goto abort;
    }
#if 0
                else {
     printf ("%s: short write\n", local);
    }
#endif
   }
   break;
  case TYPE_A:
   while ((c = getc(din)) != EOF) {
    if (c == '\n')
     bare_lfs++;
    while (c == '\r') {
     bytes++;
     if ((c = getc(din)) != '\n' || tcrflag) {
      if (ferror(fout))
       goto break2;
      (void) putc('\r', fout);
      if (c == '\0') {
       bytes++;
       goto contin2;
      }
      if (c == EOF)
       goto contin2;
     }
    }
    (void) putc(c, fout);
    /* change image */
    bytes++;
    contin2:    ;
   }
break2:
#if 0
   if (bare_lfs) {
    printf ("WARNING! %d bare linefeeds received in ASCII mode\n", bare_lfs);
    printf ("File may not have transferred correctly.\n");
   }
#endif
   if (ferror(din)) {
    if (errno != EPIPE)
    perror("netin");
    bytes = -1;
   }
   if (ferror(fout)) {
    errormsg = 1;
//    printf ("local: %s: strerror [%d]\n", local, errno);
   }
   break;
 }
 if (closefunc != NULL)
        fclose (fout);
//  (*closefunc)(fout);
 (void) gettimeofday(&stop, (struct timezone *)0);
 (void) fclose(din);
 din = NULL;
 (void) getreply(0);
 return 0;
abort:
 /* abort using RFC959 recommended IP,SYNC sequence  */
 (void) gettimeofday(&stop, (struct timezone *)0);
 if (!cpend) {
  code = -1;
  return 0;
 }
 abort_remote(din);
 code = -1;
 if (data >= 0) {
  (void) close(data);
  data = -1;
 }
 if (closefunc != NULL && fout != NULL)
        (void) fclose (fout);
//  (*closefunc)(fout);
 if (din) {
  (void) fclose(din);
  din = NULL;
 }
 return 2;
}
int get_file(char *localname, char *name)
{
 int rval;
 void settype(int type);
 settype(BINARY);
 rval = recvrequest("RETR", localname, name, "w");
 switch(rval) {
  case 1: /* non fatal error */
//   printf ("ftp: %s\n", strchr(response_line, ':'));
   break;
  case 2:
   rval = -5;
   break;
 }
 return rval;
}
#endif // 0
/*
 * Need to start a listen on the data channel before we send the command,
 * otherwise the server's connect may fail.
 */
#if 1 //
int initconn()
{
 register char *p, *a;
 int result, len, tmpno = 0;
 int on = 1;
 struct sockaddr_in data_addr;
noport:
 data_addr = server;
 if (sendport)
  data_addr.sin_port = 0; /* let system pick one */
 if (data != -1) {
  (void) close(data);
  data = -1;
 }
 data = socket(AF_INET, SOCK_STREAM, 0);
 if (data < 0) {
  perror("ftptool: socket");
  if (tmpno)
   sendport = 1;
  return (1);
 }
 if (!sendport)
  if (setsockopt(data, SOL_SOCKET, SO_REUSEADDR, (char *)&on, sizeof (on)) < 0) {
   perror("ftptool: setsockopt (reuse address)");
   goto bad;
  }
 if (bind(data, (struct sockaddr *)&data_addr, sizeof (data_addr)) < 0) {
  perror("ftptool: bind");
  goto bad;
 }
 len = sizeof (data_addr);
 if (getsockname(data, (struct sockaddr *)&data_addr, (socklen_t *) &len) < 0) {
  perror("ftptool: getsockname");
  goto bad;
 }
 if (listen(data, 5) < 0)
  perror("ftptool: listen");
 if (sendport) {
  a = (char *)&data_addr.sin_addr;
  p = (char *)&data_addr.sin_port;
#define UC(b) (((int)b)&0xff)
  result =
   command("PORT %d,%d,%d,%d,%d,%d",
    UC(a[0]), UC(a[1]), UC(a[2]), UC(a[3]),
    UC(p[0]), UC(p[1]));
  if (result == ERROR && sendport == -1) {
   sendport = 0;
   tmpno = 1;
   goto noport;
  }
  return (result != COMPLETE);
 }
 if (tmpno)
  sendport = 1;
 return (0);
bad:
 (void) close(data), data = -1;
 if (tmpno)
  sendport = 1;
 return (1);
}
#endif // 0
#if 1 //
FILE *dataconn (char *lmode)
#else
FILE *
dataconn(lmode)
 const char *lmode;
#endif // !1
{
 union sockunion from;
 int s, fromlen, tos;
 fromlen = myctladdr.su_len;
 if (passivemode)
  return (fdopen(data, lmode));
 s = accept(data, (struct sockaddr *) &from, (socklen_t *) &fromlen);
 if (s < 0) {
  warn("accept");
  (void)close(data), data = -1;
  return (NULL);
 }
 (void)close(data);
 data = s;
#ifdef IP_TOS
 if (data_addr.su_family == AF_INET)
      {
 tos = IPTOS_THROUGHPUT;
 if (setsockopt(s, IPPROTO_IP, IP_TOS, (char *)&tos, sizeof(int)) < 0)
  warn("setsockopt TOS (ignored)");
      }
#endif
 return (fdopen(data, lmode));
}
void
psabort(int notused)
// int notused;
{
#if 0 //
 alarmtimer(0);
#endif
 abrtflag++;
}
void
abortpt(int notused)
// int notused;
{
#if 0 //
 alarmtimer(0);
#endif
 putchar('\n');
 (void)fflush(stdout);
 ptabflg++;
 mflag = 0;
 abrtflag = 0;
#if 0 //
 longjmp(ptabort, 1);
#endif // 0
}
void
reset(int argc, char *argv[])
// int argc;
// char *argv[];
{
 fd_set mask;
 int nfnd = 1;
 FD_ZERO(&mask);
 while (nfnd > 0) {
  FD_SET(fileno(cin), &mask);
  if ((nfnd = empty(&mask, 0)) < 0) {
   warn("reset");
   code = -1;
   lostpeer();
  }
  else if (nfnd) {
   (void)getreply(0);
  }
 }
}
char *
gunique(const char *local)
// const char *local;
{
 static char szNew[MAXPATHLEN];
 char *cp = strrchr(local, '/');
 int d, count=0;
 char ext = '1';
 if (cp)
  *cp = '\0';
 d = access(cp == local ? "/" : cp ? local : ".", W_OK);
 if (cp)
  *cp = '/';
 if (d < 0) {
  warn("local: %s", local);
  return ((char *) 0);
 }
 (void)strcpy(szNew, local);
 cp = szNew + strlen(szNew);
 *cp++ = '.';
 while (!d) {
  if (++count == 100) {
   puts("runique: can't find unique file name.");
   return ((char *) 0);
  }
  *cp++ = ext;
  *cp = '\0';
  if (ext == '9')
   ext = '0';
  else
   ext++;
  if ((d = access(szNew, F_OK)) < 0)
   break;
  if (ext != '0')
   cp--;
  else if (*(cp - 2) == '.')
   *(cp - 1) = '1';
  else {
   *(cp - 2) = *(cp - 2) + 1;
   cp--;
  }
 }
 return (szNew);
}
void
abort_remote(FILE *din)
// FILE *din;
{
 char buf[BUFSIZ];
 int nfnd;
 fd_set mask;
 if (cout == NULL) {
  warnx("Lost control connection for abort.");
  if (ptabflg)
   code = -1;
  lostpeer();
  return;
 }
 /*
  * send IAC in urgent mode instead of DM because 4.3BSD places oob mark
  * after urgent byte rather than before as is protocol now
  */
 sprintf(buf, "%c%c%c", IAC, IP, IAC);
 if (send(fileno(cout), buf, 3, MSG_OOB) != 3)
  warn("abort");
 fprintf(cout, "%cABOR\r\n", DM);
 (void)fflush(cout);
 FD_ZERO(&mask);
 FD_SET(fileno(cin), &mask);
 if (din) {
  FD_SET(fileno(din), &mask);
 }
 if ((nfnd = empty(&mask, 10)) <= 0) {
  if (nfnd < 0) {
   warn("abort");
  }
  if (ptabflg)
   code = -1;
  lostpeer();
 }
 if (din && FD_ISSET(fileno(din), &mask)) {
  while (read(fileno(din), buf, BUFSIZ) > 0)
   /* LOOP */;
 }
 if (getreply(0) == ERROR && code == 552) {
  /* 552 needed for nic style abort */
  (void)getreply(0);
 }
 (void)getreply(0);
}
#if 1 //
int FtpGet_To_Host(char *ftpaddr, char *user, char *pass, char *ldir, char *rdir, char *ftpsrc)
{
 signal (SIGPIPE, SIG_IGN);
 if (ftp_hookup (ftpaddr) < 0) {
//  printf ("open host error\n");
  return(-1);
 }
 if (ftp_login (user, pass) < 0) {
//  printf ("incorrect login user=[%s] pswd=[%s]\n", user, pass);
  disconnect();
  return(-2);
 }
 connected = 1;
 if ( strlen (ldir) )
 {
  if ( chdir (ldir) < 0)
  {
//   printf ("chdir error ldir=[%s]\n", ldir);
   disconnect();
   return(-3);
  }
 }
 if ( strlen (rdir) )
 {
  if (change_remote_dir (rdir) < 0)
  {
//   printf ("remote chdir error rdir=[%s]\n", rdir);
   disconnect();
   return(-4);
  }
 }
 if (get_file (ftpsrc, ftpsrc) < 0) {
//  printf ("get_file err file=[%s]\n", ftpsrc);
  disconnect();
  return(-5);
 }
 pwd_remote_dir();
 disconnect();
 return 1;
} // end of FtpGet_To_Host ()
int FtpPut_To_Host(char *ftpaddr, char *user, char *pass, char *ldir, char *rdir, char *ftpsrc)
{
 char temp_name[256];
 signal(SIGPIPE, SIG_IGN);
 if (ftp_hookup(ftpaddr) < 0) {
//  printf ("open host error\n");
  return(-1);
 }
 if (ftp_login(user, pass) < 0) {
//  printf ("incorrect login user=[%s] pswd=[%s]\n", user, pass);
  disconnect();
  return(-2);
 }
 connected = 1;
 if ( strlen(ldir) )
 {
  if ( chdir(ldir) < 0)
  {
//   printf ("chdir error ldir=[%s]\n", ldir);
   disconnect();
   return(-3);
  }
 }
 if ( strlen(rdir) )
 {
  if(change_remote_dir(rdir) < 0)
  {
//   printf ("remote chdir error rdir=[%s]\n", rdir);
   disconnect();
   return(-4);
  }
 }
 sprintf(temp_name, "%s_tmp", ftpsrc);
 if (put_file(ftpsrc, temp_name) < 0) {
//  printf ("put_file err file=[%s] tmp=[%s]\n", ftpsrc, temp_name);
  disconnect();
  return(-5);
 }
 pwd_remote_dir();
 if (ftp_rename_file(temp_name, ftpsrc) < 0) {
  //printf ("rename file error tmp=[%s] file=[%s]\n", temp_name, ftpsrc);
  disconnect();
  return(-6);
 }
 disconnect();
 return 1;
} // end of FtpPut_To_Host ()
#endif // 1


Makefile

#
# Makefile
# Modify by jakeoh
#
# 10May06 jakeoh Make
#
# CC Environment
CC          = gcc -g
LD          = g++ -g
# INCLUDE DIRS
INCDIRS = -I.
# LIB DIRS
LIBDIRS = -L
# LIBS
#CFLAG=-W -pipe -mcpu=common -D_REENTRANT -DPDL_AIX_MAJOR_VERS=5 -DPDL_AIX_MINOR_VERS=3 -pthread -O -DPDL_NDEBUG ${INCDIRS}
CFLAG=-W -pipe -DCYGWIN -D_REENTRANT -DPDL_AIX_MAJOR_VERS=5 -DPDL_AIX_MINOR_VERS=3 -O -DPDL_NDEBUG ${INCDIRS}
SRCS= test_main.c \
    p_ftp.c
OBJS= test_main.o \
    p_ftp.o
BINS=ftptest
LD_OBJ=\
    test_main.o \
    p_ftp.o
.c.o:
 ${CC} ${CFLAG} -c $*.c

all: ${BINS}
${BINS}:${OBJS}
# ${CC} -o $@ ${OBJS} ${CFLAG} ${LDFLAGS}
 ${LD} -o $@ ${OBJS} ${CFLAG} ${LDFLAGS}
install:
copy:
 \cp ${BINS} /home/as/bin
run:
 \cp ${BINS} ${RUNDIRS}
 \cp ${MEDLIB} ${RUNDIRS}
cleanall:
 -rm ${BINS} ${OBJS} core
clean:
 -rm ${BINS} ${OBJS} core
new:
 make clean
 make

 

+ Recent posts