UtilityBase is now of type struct UtilityBase *
[AROS.git] / workbench / c / Copy.c
blobaa227572110f93144c4884b8ed8e15d9636c1dbd
1 /*
2 (C) 1998 AROS - The Amiga Research OS
3 $Id$
5 Desc: Copy CLI command
6 Lang: english
7 */
9 /*****************************************************************************
11 NAME
13 Copy
15 SYNOPSIS
17 SOURCE/M/A,DEST/A
19 LOCATION
21 Workbench:c
23 FUNCTION
25 Creates identical copies of one or more files.
27 INPUTS
29 SOURCE - The files that are to be copied. You can specify a pattern
30 here.
32 DEST - The directory, where the copies of the files are to be
33 stored. If only one file was specified as SOURCE, this
34 can be a different filename. The new file will named DEST.
36 RESULT
38 Standard DOS return codes.
40 NOTES
42 EXAMPLE
44 BUGS
46 Pattern-Matching does not work, yet.
48 Error messages could be more comprehensive.
50 SEE ALSO
52 Delete(), Rename(), MakeDir()
54 INTERNALS
56 HISTORY
58 ******************************************************************************/
60 #include <aros/rt.h>
62 #include <proto/exec.h>
63 #include <exec/memory.h>
64 #include <exec/types.h>
65 #include <proto/dos.h>
66 #include <dos/dos.h>
67 #include <dos/rdargs.h>
68 #include <utility/tagitem.h>
71 static const char version[] = "$VER: Copy 41.0 (29.08.1998)\n";
74 #define ARG_TEMPLATE "SOURCE/M/A,DEST/A"
75 #define ARG_SOURCE 0
76 #define ARG_DEST 1
77 #define ARG_NUM 2
80 #define ERROR_HEADER "Copy"
84 int copy_file(STRPTR source, STRPTR dest)
86 int result = RETURN_OK;
87 BPTR sf, df;
89 sf = Open(source, MODE_OLDFILE);
90 if(sf) {
91 df = Open(dest, MODE_NEWFILE);
92 if(df) {
93 char buffer[1024];
94 LONG read;
95 while((read = Read(sf, buffer, sizeof(buffer))) > 0)
96 Write(df, buffer, read);
97 if(read == -1) {
98 PrintFault(IoErr(), ERROR_HEADER);
99 result = RETURN_ERROR;
101 Close(df);
102 } else {
103 PrintFault(IoErr(), ERROR_HEADER);
104 result = RETURN_FAIL;
106 Close(sf);
107 } else {
108 PrintFault(IoErr(), ERROR_HEADER);
109 result = RETURN_FAIL;
112 return result;
116 STRPTR make_dest_name(STRPTR source, STRPTR destdir)
118 STRPTR dest;
119 ULONG slen = (ULONG)strlen(source);
120 ULONG dlen = (ULONG)strlen(destdir);
122 dest = AllocVec(slen + dlen + 2, MEMF_ANY);
123 if(!dest) {
124 PrintFault(ERROR_NO_FREE_STORE, ERROR_HEADER);
125 return NULL;
128 strcpy(dest, destdir);
129 AddPart(dest, source, slen + dlen + 2);
131 return dest;
135 int copy_files(STRPTR *source, STRPTR dest)
137 int result = RETURN_OK;
138 BOOL dest_is_dir = FALSE;
139 BOOL multiple_sources = FALSE;
141 BPTR lock;
143 /* find out, if dest is a directory */
144 lock = Lock(dest, SHARED_LOCK);
145 if(!lock) {
146 /* if IoErr() == ERROR_OBJECT_NOT_FOUND, dest is a plain file */
147 if(IoErr() != ERROR_OBJECT_NOT_FOUND) {
148 PrintFault(IoErr(), ERROR_HEADER);
149 result = RETURN_FAIL;
151 } else {
152 struct FileInfoBlock *fib;
153 fib = AllocDosObject(DOS_FIB, NULL);
154 if(fib) {
155 if(Examine(lock, fib) == DOSTRUE) {
156 if(fib->fib_DirEntryType >= 0)
157 dest_is_dir = TRUE;
158 } else {
159 PrintFault(IoErr(), ERROR_HEADER);
160 result = RETURN_FAIL;
162 FreeDosObject(DOS_FIB, fib);
163 } else {
164 PrintFault(IoErr(), ERROR_HEADER);
165 result = RETURN_FAIL;
167 UnLock(lock);
169 if(result)
170 return result;
172 /* find out, if we have multiple source files */
173 if(dest[1])
174 multiple_sources = TRUE;
175 else {
176 #warning FIXME: pattern matching
179 if(multiple_sources && !dest_is_dir) {
180 PrintFault(ERROR_OBJECT_WRONG_TYPE, ERROR_HEADER);
181 result = RETURN_FAIL;
184 if(multiple_sources) {
185 unsigned int pos = 0;
186 STRPTR dest_name = NULL;
187 while(source[pos] && result == RETURN_OK) {
188 #warning FIXME: pattern matching
189 dest_name = make_dest_name(source[pos], dest);
190 if(dest_name) {
191 result = copy_file(source[pos], dest_name);
192 FreeVec(dest_name);
193 } else
194 result = RETURN_FAIL;
195 pos++;
198 } else { /* !multiple_sources */
199 if(dest_is_dir) {
200 STRPTR dest_name = make_dest_name(*source, dest);
201 if(dest_name) {
202 result = copy_file(*source, dest_name);
203 FreeVec(dest_name);
204 } else
205 result = RETURN_FAIL;
206 } else
207 result = copy_file(*source, dest);
210 return result;
214 int main(int argc, char *argv[])
216 int result = RETURN_OK;
217 struct RDArgs *rda;
218 IPTR argarray[ARG_NUM] = { NULL, NULL };
220 RT_Init();
222 rda = ReadArgs(ARG_TEMPLATE, argarray, NULL);
223 if(rda) {
224 result = copy_files((STRPTR *)argarray[ARG_SOURCE], (STRPTR)argarray[ARG_DEST]);
225 FreeArgs(rda);
226 } else {
227 PrintFault(IoErr(), ERROR_HEADER);
228 result = RETURN_FAIL;
231 RT_Exit();
233 return result;