📄 freebcp.c
字号:
/* FreeTDS - Library of routines accessing Sybase and Microsoft databases * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#if HAVE_CONFIG_H#include <config.h>#endif#include <stdio.h>#include <ctype.h>#if HAVE_STDLIB_H#include <stdlib.h>#endif /* HAVE_STDLIB_H */#if HAVE_STRING_H#include <string.h>#endif /* HAVE_STRING_H */#if HAVE_STRINGS_H#include <strings.h>#endif /* HAVE_STRINGS_H */#if HAVE_UNISTD_H#include <unistd.h>#endif#include "tds.h"#include <sybfront.h>#include <sybdb.h>#include "freebcp.h"static char software_version[] = "$Id: freebcp.c,v 1.48 2006/12/01 21:51:11 jklowden Exp $";static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };void pusage(void);int process_parameters(int, char **, struct pd *);static int unescape(char arg[]);int login_to_database(struct pd *, DBPROCESS **);int file_character(BCPPARAMDATA * pdata, DBPROCESS * dbproc, DBINT dir);int file_native(BCPPARAMDATA * pdata, DBPROCESS * dbproc, DBINT dir);int file_formatted(BCPPARAMDATA * pdata, DBPROCESS * dbproc, DBINT dir);int setoptions (DBPROCESS * dbproc, BCPPARAMDATA * params);int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line);intmain(int argc, char **argv){ BCPPARAMDATA params; DBPROCESS *dbproc; int ok = FALSE; memset(¶ms, '\0', sizeof(params)); params.textsize = 4096; /* our default text size is 4K */ if (process_parameters(argc, argv, ¶ms) == FALSE) { exit(1); } if (getenv("FREEBCP")) { fprintf(stderr, "User name: \"%s\"\n", params.user); } if (login_to_database(¶ms, &dbproc) == FALSE) { exit(1); } if (!setoptions(dbproc, ¶ms)) return FALSE; if (params.cflag) { /* character format file */ ok = file_character(¶ms, dbproc, params.direction); } else if (params.nflag) { /* native format file */ ok = file_native(¶ms, dbproc, params.direction); } else if (params.fflag) { /* formatted file */ ok = file_formatted(¶ms, dbproc, params.direction); } else { ok = FALSE; } exit((ok == TRUE) ? 0 : 1); return 0;}static int unescape(char arg[]){ char *p = arg, *next; char escaped; while ((next = strchr(p, '\\')) != NULL) { p = next; switch (p[1]) { case '0': escaped = '\0'; break; case 't': escaped = '\t'; break; case 'r': escaped = '\r'; break; case 'n': escaped = '\n'; break; case '\\': escaped = '\\'; break; default: ++p; continue; } /* Overwrite the backslash with the intended character, and shift everything down one */ *p++ = escaped; memmove(p, p+1, 1 + strlen(p+1)); } return strchr(p, 0) - arg;}intprocess_parameters(int argc, char **argv, BCPPARAMDATA *pdata){ extern char *optarg; extern int optind; extern int optopt; int ch; if (argc < 6) { pusage(); return (FALSE); } /* * Set some defaults and read the table, file, and direction arguments. */ pdata->firstrow = 0; pdata->lastrow = 0; pdata->batchsize = 1000; pdata->maxerrors = 10; /* argument 1 - the database object */ pdata->dbobject = strdup(argv[1]); if (pdata->dbobject == NULL) { fprintf(stderr, "Out of memory!\n"); return FALSE; } /* argument 2 - the direction */ strcpy(pdata->dbdirection, argv[2]); if (strcmp(pdata->dbdirection, "in") == 0) { pdata->direction = DB_IN; } else if (strcmp(pdata->dbdirection, "out") == 0) { pdata->direction = DB_OUT; } else if (strcmp(pdata->dbdirection, "queryout") == 0) { pdata->direction = DB_QUERYOUT; } else { fprintf(stderr, "Copy direction must be either 'in', 'out' or 'queryout'.\n"); return (FALSE); } /* argument 3 - the datafile name */ strcpy(pdata->hostfilename, argv[3]); /* * Get the rest of the arguments */ optind = 4; /* start processing options after table, direction, & filename */ while ((ch = getopt(argc, argv, "m:f:e:F:L:b:t:r:U:P:I:S:h:T:A:O:0:ncEdvV")) != -1) { switch (ch) { case 'v': case 'V': printf("freebcp version %s\n", software_version); return FALSE; break; case 'm': pdata->mflag++; pdata->maxerrors = atoi(optarg); break; case 'f': pdata->fflag++; strcpy(pdata->formatfile, optarg); break; case 'e': pdata->eflag++; pdata->errorfile = strdup(optarg); break; case 'F': pdata->Fflag++; pdata->firstrow = atoi(optarg); break; case 'L': pdata->Lflag++; pdata->lastrow = atoi(optarg); break; case 'b': pdata->bflag++; pdata->batchsize = atoi(optarg); break; case 'n': pdata->nflag++; break; case 'c': pdata->cflag++; break; case 'E': pdata->Eflag++; break; case 'd': tdsdump_open(NULL); break; case 't': pdata->tflag++; pdata->fieldterm = strdup(optarg); pdata->fieldtermlen = unescape(pdata->fieldterm); break; case 'r': pdata->rflag++; pdata->rowterm = strdup(optarg); pdata->rowtermlen = unescape(pdata->rowterm); break; case 'U': pdata->Uflag++; pdata->user = strdup(optarg); break; case 'P': pdata->Pflag++; if ((strcmp(optarg, "-")) == 0) { char pwd[255], *nl; memset(pwd, 0, 255); fgets(pwd, 255, stdin); nl = strchr(pwd, '\n'); if(nl) *nl = '\0'; pdata->pass = strdup(pwd); } else { pdata->pass = strdup(optarg); } break; case 'I': pdata->Iflag++; strcpy(pdata->interfacesfile, optarg); break; case 'S': pdata->Sflag++; pdata->server = strdup(optarg); break; case 'h': pdata->hint = strdup(optarg); break; case 'O': case '0': pdata->options = strdup(optarg); break; case 'T': pdata->Tflag++; pdata->textsize = atoi(optarg); break; case 'A': pdata->Aflag++; pdata->packetsize = atoi(optarg); break; case '?': default: pusage(); return (FALSE); } } /* * Check for required/disallowed option combinations */ /* these must be specified */ if (!pdata->Uflag || !pdata->Pflag || !pdata->Sflag) { fprintf(stderr, "All 3 options -U, -P, -S must be supplied.\n"); return (FALSE); } /* only one of these can be specified */ if (pdata->cflag + pdata->nflag + pdata->fflag != 1) { fprintf(stderr, "Exactly one of options -c, -n, -f must be supplied.\n"); return (FALSE); } /* character mode file: Fill in some default values*/ if (pdata->cflag) { if (!pdata->tflag || !pdata->fieldterm) { /* field terminator not specified */ pdata->fieldterm = "\t"; pdata->fieldtermlen = 1; } if (!pdata->rflag || !pdata->rowterm) { /* row terminator not specified */ pdata->rowterm = "\n"; pdata->rowtermlen = 1; } } return (TRUE);}intlogin_to_database(BCPPARAMDATA * pdata, DBPROCESS ** pdbproc){ LOGINREC *login; /* Initialize DB-Library. */ if (dbinit() == FAIL) return (FALSE); /* * Install the user-supplied error-handling and message-handling * routines. They are defined at the bottom of this source file. */ dberrhandle(err_handler); dbmsghandle(msg_handler); /* If the interfaces file was specified explicitly, set it. */ if (pdata->interfacesfile != NULL) dbsetifile(pdata->interfacesfile); /* * Allocate and initialize the LOGINREC structure to be used * to open a connection to SQL Server. */ login = dblogin(); DBSETLUSER(login, pdata->user); DBSETLPWD(login, pdata->pass); DBSETLAPP(login, "FreeBCP"); /* if packet size specified, set in login record */ if (pdata->Aflag && pdata->packetsize > 0) { DBSETLPACKET(login, pdata->packetsize); } /* Enable bulk copy for this connection. */ BCP_SETL(login, TRUE); /* * ** Get a connection to the database.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -