13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <unistd.h>
33e12c5d1SDavid du Colombier #include <string.h>
43e12c5d1SDavid du Colombier #include <stdio.h>
53e12c5d1SDavid du Colombier #include <errno.h>
69a747e4fSDavid du Colombier #include <stdlib.h>
73e12c5d1SDavid du Colombier #include "sys9.h"
83e12c5d1SDavid du Colombier #include "dir.h"
93e12c5d1SDavid du Colombier
103e12c5d1SDavid du Colombier int
rename(const char * from,const char * to)113e12c5d1SDavid du Colombier rename(const char *from, const char *to)
123e12c5d1SDavid du Colombier {
13*781103c4SDavid du Colombier int n;
143e12c5d1SDavid du Colombier char *f, *t;
15d3c05884SDavid du Colombier Dir *d, nd;
163e12c5d1SDavid du Colombier
173e12c5d1SDavid du Colombier if(access(to, 0) >= 0){
183e12c5d1SDavid du Colombier if(_REMOVE(to) < 0){
193e12c5d1SDavid du Colombier _syserrno();
203e12c5d1SDavid du Colombier return -1;
213e12c5d1SDavid du Colombier }
223e12c5d1SDavid du Colombier }
239a747e4fSDavid du Colombier if((d = _dirstat(to)) != nil){
249a747e4fSDavid du Colombier free(d);
253e12c5d1SDavid du Colombier errno = EEXIST;
263e12c5d1SDavid du Colombier return -1;
273e12c5d1SDavid du Colombier }
289a747e4fSDavid du Colombier if((d = _dirstat(from)) == nil){
293e12c5d1SDavid du Colombier _syserrno();
303e12c5d1SDavid du Colombier return -1;
313e12c5d1SDavid du Colombier }
323e12c5d1SDavid du Colombier f = strrchr(from, '/');
333e12c5d1SDavid du Colombier t = strrchr(to, '/');
34*781103c4SDavid du Colombier f = f? f+1 : (char *)from;
35*781103c4SDavid du Colombier t = t? t+1 : (char *)to;
363e12c5d1SDavid du Colombier n = 0;
373e12c5d1SDavid du Colombier if(f-from==t-to && strncmp(from, to, f-from)==0){
383e12c5d1SDavid du Colombier /* from and to are in same directory (we miss some cases) */
39d3c05884SDavid du Colombier _nulldir(&nd);
40d3c05884SDavid du Colombier nd.name = t;
41d3c05884SDavid du Colombier if(_dirwstat(from, &nd) < 0){
423e12c5d1SDavid du Colombier _syserrno();
433e12c5d1SDavid du Colombier n = -1;
443e12c5d1SDavid du Colombier }
453e12c5d1SDavid du Colombier }else{
463e12c5d1SDavid du Colombier /* different directories: have to copy */
473e12c5d1SDavid du Colombier int ffd, tfd;
483e12c5d1SDavid du Colombier char buf[8192];
493e12c5d1SDavid du Colombier
50*781103c4SDavid du Colombier tfd = -1;
513e12c5d1SDavid du Colombier if((ffd = _OPEN(from, 0)) < 0 ||
529a747e4fSDavid du Colombier (tfd = _CREATE(to, 1, d->mode)) < 0){
533e12c5d1SDavid du Colombier _CLOSE(ffd);
543e12c5d1SDavid du Colombier _syserrno();
553e12c5d1SDavid du Colombier n = -1;
563e12c5d1SDavid du Colombier }
577dd7cddfSDavid du Colombier while(n>=0 && (n = _READ(ffd, buf, 8192)) > 0)
583e12c5d1SDavid du Colombier if(_WRITE(tfd, buf, n) != n){
593e12c5d1SDavid du Colombier _syserrno();
603e12c5d1SDavid du Colombier n = -1;
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier _CLOSE(ffd);
633e12c5d1SDavid du Colombier _CLOSE(tfd);
643e12c5d1SDavid du Colombier if(n>0)
653e12c5d1SDavid du Colombier n = 0;
667dd7cddfSDavid du Colombier if(n == 0) {
677dd7cddfSDavid du Colombier if(_REMOVE(from) < 0){
687dd7cddfSDavid du Colombier _syserrno();
697dd7cddfSDavid du Colombier return -1;
707dd7cddfSDavid du Colombier }
717dd7cddfSDavid du Colombier }
723e12c5d1SDavid du Colombier }
739a747e4fSDavid du Colombier free(d);
743e12c5d1SDavid du Colombier return n;
753e12c5d1SDavid du Colombier }
76