source: trunk/athena/etc/synctree/switch.c @ 10508

Revision 10508, 7.2 KB checked in by ghudson, 27 years ago (diff)
Use HAVE_LCHOWN to decide if we want to do lchown. Nuke Ultrix support.
  • Property svn:executable set to *
Line 
1/*
2 * Copyright (C) 1988  Tim Shepard              All rights reserved.
3 * Copyright (C) 1989  MIT/Project Athena       All rights reserved.
4 */
5
6#if defined(_AIX) && defined(i386)
7#define unlink(a) (rmslink(a) && unlink(a))
8#endif
9
10#define noupdate(problem) printf("Not %sing %s because %s\n",action,targname,problem)
11#define update_error(problem) printf("Error %sing %s: %s: %s\n",action,targname,problem,strerror(errno))
12
13        switch (typeofaction) {
14            int status;
15#define action "copy"
16        case ACTION_COPY:
17        case ACTION_LOCAL:
18            /* We want to ignore "virtual" files */
19            if (srctype == TYPE_V)
20                break;
21           
22            if (exists) {
23                if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)) {
24                    noupdate("the target is a local version.");
25                    break;
26                }
27                if (srctype != targtype && (srctype & TYPE_V) == 0) {
28                    if (!fflag && (targtype != TYPE_L)) {
29                        noupdate("the file types diff.  Use -f to override.");
30                        break;
31                    }
32                    if (verbosef || nflag)
33                        printf("Removing %s (file types differ).\n", targname);
34                    if (!nflag) {
35                        if (targtype == TYPE_D) {
36                            if (recursive_rmdir(targname)) {
37                                update_error("recursive rmdir failed");
38                                break;
39                            }
40                        } else                     
41                        if (unlink(targname)) {
42                            update_error("unlink failed");
43                            break;
44                        }
45                    }
46                    exists = FALSE;
47                }
48            }
49            switch (srctype) {
50            case TYPE_R:
51                if (!exists) {
52                    if (nflag) {
53                        printf("Copying %s (mode is %5.5o).\n",
54                               srcname,targname,srcmode);
55                        break;
56                    }
57                    if (copyfile(srcname,targname,srcmode))
58                        update_error("copy failed");
59                    setdates();
60                    if (pflag &&
61                        (chown(targname, -1, srcgid) ||
62                         chown(targname, srcuid, -1)))
63                        update_error("chown failed");
64                    break;
65                }
66                switch(status = filecheck3()) {
67                case UPTODATE:
68                    break;
69                case NEWERDATE:
70                    if (!fflag) {
71                        noupdate("the target is a more recent copy.");
72                        break;
73                    }
74                    /* fall through */
75                case OUTOFDATE:
76                    if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)){
77                        noupdate("the target is a local version (the target is old).");
78                        break;
79                    }
80                    if (verbosef || nflag)
81                        printf("Updating out of date %s .\n", targname);
82                    if (!nflag) {
83                        if (unlink(targname)) {
84                            update_error("unlink failed");
85                            break;
86                        } else if (copyfile(srcname,targname,srcmode)) {
87                            update_error("copy failed");
88                            break;
89                        }
90                        setdates();
91                    }
92                    /* fall through */
93                case FIXOWNANDMODE:
94                case FIXMODE:
95                    if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)){
96                        noupdate("the target is a local version (the ownership is different).");
97                        break;
98                    }
99                    if ((verbosef || nflag) && (status == FIXOWNANDMODE))
100                        printf("Fixing ownership and modes of %s .\n",
101                               targname);
102                    if ((verbosef || nflag) && (status == FIXMODE))
103                        printf("Fixing modes of %s .\n", targname);
104
105                    if (!nflag && chmod(targname, srcmode))
106                        update_error("chmod() failed");
107                    if (!nflag && pflag && (status != FIXMODE) &&
108                        (chown(targname, -1, srcgid) ||
109                         chown(targname, srcuid, -1)))
110                        update_error("chown failed");
111                    break;                 
112                default:
113                    noupdate("of an internal error: filecheck3() returned an unknown value.");
114                }
115                break;
116                 
117            case TYPE_L:
118                if (exists) {
119                    char buf1[BUFSIZ], buf2[BUFSIZ];
120                    int buf1_len, buf2_len;
121                   
122                    if (((buf1_len = readlink(srcname, buf1, BUFSIZ)) ==
123                         (buf2_len = readlink(targname, buf2, BUFSIZ))) &&
124                        !strncmp(buf1,buf2,buf1_len))
125                        break;
126                    if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)){
127                        noupdate("the target is a local link (the links are different).");
128                        break;
129                    }
130                    if (verbosef || nflag)
131                        printf("Updating symbolic link %s .\n", targname);
132                    if (!nflag && unlink(targname))
133                        update_error("unlink failed");
134                } else
135                    if (verbosef || nflag)
136                        printf("Copying symbolic link %s .\n",srcname);
137                if (nflag)
138                    break;
139                if (copylink(srcname,targname,srcmode))
140                    update_error("copy of symbolic link failed.");
141#ifdef HAVE_LCHOWN
142                else if (pflag && lchown(targname,srcuid,srcgid))
143                    update_error("lchown() failed.");
144#endif
145                break;
146             
147            case TYPE_D:
148                if (!exists) {
149                    if (verbosef || nflag)
150                        printf("Creating directory %s .\n", targname);
151                    if (nflag)
152                        break;
153                    if (mkdir(targname,0777)) {
154                        update_error("mkdir() failed");
155                        break;          /* No point continuing... */
156                    }
157                    else if (chmod(targname, srcmode))
158                        update_error("chmod() failed");
159                    else if (pflag && chown(targname, srcuid, srcgid))
160                        update_error("chown() failed");
161                } else {
162                    switch(status = dircheck()) {
163                    case FIXMODE:
164                    case FIXOWNANDMODE:
165                        if ((verbosef || nflag) &&
166                            (typeofaction == ACTION_LOCAL)) {
167                            noupdate("the target is a local version");
168                            break;
169                        }
170                        if ((verbosef || nflag) && (status == FIXMODE))
171                            printf("Fixing modes of %s .\n", targname);
172                        else if (verbosef || nflag)
173                            printf("Fixing ownership and modes of %s .\n",
174                                   targname);
175                        if (!nflag && chmod(targname, srcmode))
176                            update_error("chmod() failed");
177                        if (!nflag && pflag &&
178                            (chown(targname, -1, srcgid) ||
179                             chown(targname, srcuid, -1))) {
180                            update_error("chown() failed");
181                            break;
182                        }
183                        break;             
184                    }
185                }
186                if (dodir(srcname, targname, part))
187                    printf("The update of %s from %s aborted prematurely.\n",
188                           targname, srcname);
189                break;
190
191            case TYPE_C:
192            case TYPE_B:
193                noupdate("copying of devices is not yet supported.");
194                break;
195            }
196            break;
197           
198#undef  action
199#define action "link"
200        case ACTION_LINK:
201            if (exists) {
202                char linkbuf[MAXPATHLEN];
203                int linklen;
204               
205                switch(targtype) {
206                case TYPE_V:
207                    /* This is a virtual file... so we should ignore it */
208                    break;
209                case TYPE_L:
210                    linklen = readlink(targname, linkbuf, MAXPATHLEN);
211                    if ((!strncmp(linkbuf, srcname, linklen)) &&
212                        (*((char *)srcname + linklen) == 0))
213                        break;
214                    /* fall through */
215                default:
216                    if (!fflag && targtype != TYPE_L) {
217                        noupdate("the target was not a symlink.  Use -f to override.\n");
218                        break;
219                    }
220                    if (verbosef || nflag) printf("Removing %s .\n",targname);
221                    if (!nflag)
222                        if (targtype == TYPE_D) {
223                            if (recursive_rmdir(targname)) {
224                                update_error("recursive rmdir failed");
225                                break;
226                            }
227                        } else                     
228                        if (unlink(targname)) {
229                            update_error("unlink failed");
230                            break;
231                        }
232                    exists = FALSE;
233                    break;
234                }
235            }
236            if (exists) break;
237            if (verbosef || nflag)
238                printf("Creating symbolic link from %s to %s .\n", targname, srcname);
239            if (!nflag && symlink(srcname,targname))
240                update_error("symlink failed");
241            break;
242
243/*
244 * The action words are intentionally mispelled to
245 * get the correct spelling during message displays
246 */
247#undef  action
248#define action "ignor"
249        case ACTION_IGNORE:
250            break;
251
252#undef update_error
253#define update_error(problem) printf("Error %sing %s: %s: %s\n",action,targname,problem,strerror(errno))
254
255#undef action
256#define action "delet"
257        case ACTION_DELETE:
258            if (!exists)
259                break;
260            if (verbosef || nflag)
261                printf("Removing %s.\n", targname);
262            if (!nflag) {
263                if (targtype & TYPE_D) {
264                    if (recursive_rmdir(targname))
265                        update_error("recursive rmdir failed");
266                }
267                else if (unlink(targname))
268                    update_error("unlink failed");
269            }
270            break;
271        }
Note: See TracBrowser for help on using the repository browser.