[BACK]Return to edit.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / cvs

Annotation of src/usr.bin/cvs/edit.c, Revision 1.22

1.22    ! xsa         1: /*     $OpenBSD: edit.c,v 1.21 2007/01/05 09:32:49 xsa Exp $   */
1.1       jfb         2: /*
1.15      xsa         3:  * Copyright (c) 2006, 2007 Xavier Santolaria <xsa@openbsd.org>
1.1       jfb         4:  *
1.14      xsa         5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1       jfb        16:  */
                     17:
1.11      xsa        18: #include "includes.h"
1.1       jfb        19:
                     20: #include "cvs.h"
                     21: #include "log.h"
1.14      xsa        22: #include "remote.h"
1.1       jfb        23:
1.18      xsa        24: #define E_COMMIT       0x01
                     25: #define E_EDIT         0x02
                     26: #define E_UNEDIT       0x04
                     27: #define E_ALL          (E_EDIT|E_COMMIT|E_UNEDIT)
                     28:
                     29: static void    cvs_edit_local(struct cvs_file *);
1.14      xsa        30: static void    cvs_editors_local(struct cvs_file *);
1.15      xsa        31: static void    cvs_unedit_local(struct cvs_file *);
1.1       jfb        32:
1.18      xsa        33: static int     edit_aflags = 0;
                     34:
                     35: struct cvs_cmd cvs_cmd_edit = {
                     36:        CVS_OP_EDIT, 0, "edit",
                     37:        { },
                     38:        "Get ready to edit a watched file",
                     39:        "[-lR] [-a action] [file ...]",
                     40:        "a:lR",
                     41:        NULL,
                     42:        cvs_edit
                     43: };
                     44:
1.1       jfb        45: struct cvs_cmd cvs_cmd_editors = {
1.14      xsa        46:        CVS_OP_EDITORS, 0, "editors",
1.1       jfb        47:        { },
1.14      xsa        48:        "See who is editing a watched file",
1.3       xsa        49:        "[-lR] [file ...]",
1.1       jfb        50:        "lR",
                     51:        NULL,
1.14      xsa        52:        cvs_editors
1.1       jfb        53: };
                     54:
1.15      xsa        55: struct cvs_cmd cvs_cmd_unedit = {
                     56:        CVS_OP_UNEDIT, 0, "unedit",
                     57:        { },
                     58:        "Undo an edit command",
                     59:        "[-lR] [file ...]",
                     60:        "lR",
                     61:        NULL,
                     62:        cvs_unedit
                     63: };
                     64:
1.14      xsa        65: int
1.18      xsa        66: cvs_edit(int argc, char **argv)
                     67: {
                     68:        int ch;
                     69:        int flags;
                     70:        struct cvs_recursion cr;
                     71:
                     72:        flags = CR_RECURSE_DIRS;
                     73:
                     74:        while ((ch = getopt(argc, argv, cvs_cmd_edit.cmd_opts)) != -1) {
                     75:                switch (ch) {
                     76:                case 'a':
                     77:                        if (strcmp(optarg, "edit") == 0)
                     78:                                edit_aflags |= E_EDIT;
                     79:                        else if (strcmp(optarg, "unedit") == 0)
                     80:                                edit_aflags |= E_UNEDIT;
                     81:                        else if (strcmp(optarg, "commit") == 0)
                     82:                                edit_aflags |= E_COMMIT;
                     83:                        else if (strcmp(optarg, "all") == 0)
                     84:                                edit_aflags |= E_ALL;
                     85:                        else if (strcmp(optarg, "none") == 0)
                     86:                                edit_aflags &= ~E_ALL;
                     87:                        else
                     88:                                fatal("%s", cvs_cmd_edit.cmd_synopsis);
                     89:                        break;
                     90:                case 'l':
                     91:                        flags &= ~CR_RECURSE_DIRS;
                     92:                        break;
                     93:                case 'R':
                     94:                        break;
                     95:                default:
                     96:                        fatal("%s", cvs_cmd_edit.cmd_synopsis);
                     97:                }
                     98:        }
                     99:
                    100:        argc -= optind;
                    101:        argv += optind;
                    102:
                    103:        if (argc == 0)
                    104:                fatal("%s", cvs_cmd_edit.cmd_synopsis);
                    105:
                    106:        if (edit_aflags == 0)
                    107:                edit_aflags |= E_ALL;
                    108:
                    109:        cr.enterdir = NULL;
                    110:        cr.leavedir = NULL;
                    111:
                    112:        if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                    113:                cr.fileproc = cvs_client_sendfile;
                    114:
                    115:                if (!(flags & CR_RECURSE_DIRS))
                    116:                        cvs_client_send_request("Argument -l");
                    117:        } else {
                    118:                cr.fileproc = cvs_edit_local;
                    119:        }
                    120:
                    121:        cr.flags = flags;
                    122:
                    123:        cvs_file_run(argc, argv, &cr);
                    124:
                    125:        if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                    126:                cvs_client_send_files(argv, argc);
                    127:                cvs_client_senddir(".");
                    128:                cvs_client_send_request("edit");
                    129:                cvs_client_get_responses();
                    130:        }
                    131:
                    132:        return (0);
                    133: }
                    134:
                    135: int
1.14      xsa       136: cvs_editors(int argc, char **argv)
1.1       jfb       137: {
1.12      xsa       138:        int ch;
1.14      xsa       139:        int flags;
                    140:        struct cvs_recursion cr;
                    141:
                    142:        flags = CR_RECURSE_DIRS;
1.1       jfb       143:
1.14      xsa       144:        while ((ch = getopt(argc, argv, cvs_cmd_editors.cmd_opts)) != -1) {
1.1       jfb       145:                switch (ch) {
                    146:                case 'l':
1.14      xsa       147:                        flags &= ~CR_RECURSE_DIRS;
1.1       jfb       148:                        break;
                    149:                case 'R':
                    150:                        break;
                    151:                default:
1.14      xsa       152:                        fatal("%s", cvs_cmd_editors.cmd_synopsis);
1.1       jfb       153:                }
                    154:        }
                    155:
1.14      xsa       156:        argc -= optind;
                    157:        argv += optind;
1.1       jfb       158:
1.14      xsa       159:        if (argc == 0)
                    160:                fatal("%s", cvs_cmd_editors.cmd_synopsis);
1.1       jfb       161:
1.14      xsa       162:        cr.enterdir = NULL;
                    163:        cr.leavedir = NULL;
1.1       jfb       164:
1.14      xsa       165:        if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                    166:                cr.fileproc = cvs_client_sendfile;
                    167:
                    168:                if (!(flags & CR_RECURSE_DIRS))
                    169:                        cvs_client_send_request("Argument -l");
                    170:        } else {
                    171:                cr.fileproc = cvs_editors_local;
                    172:        }
1.1       jfb       173:
1.14      xsa       174:        cr.flags = flags;
1.9       xsa       175:
1.14      xsa       176:        cvs_file_run(argc, argv, &cr);
1.9       xsa       177:
1.14      xsa       178:        if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                    179:                cvs_client_send_files(argv, argc);
                    180:                cvs_client_senddir(".");
                    181:                cvs_client_send_request("editors");
                    182:                cvs_client_get_responses();
1.9       xsa       183:        }
                    184:
1.14      xsa       185:        return (0);
                    186: }
1.9       xsa       187:
1.15      xsa       188: int
                    189: cvs_unedit(int argc, char **argv)
                    190: {
                    191:        int ch;
                    192:        int flags;
                    193:        struct cvs_recursion cr;
                    194:
                    195:        flags = CR_RECURSE_DIRS;
                    196:
                    197:        while ((ch = getopt(argc, argv, cvs_cmd_unedit.cmd_opts)) != -1) {
                    198:                switch (ch) {
                    199:                case 'l':
                    200:                        flags &= ~CR_RECURSE_DIRS;
                    201:                        break;
                    202:                case 'R':
                    203:                        break;
                    204:                default:
                    205:                        fatal("%s", cvs_cmd_unedit.cmd_synopsis);
                    206:                }
                    207:        }
                    208:
                    209:        argc -= optind;
                    210:        argv += optind;
                    211:
                    212:        if (argc == 0)
                    213:                fatal("%s", cvs_cmd_unedit.cmd_synopsis);
                    214:
                    215:        cr.enterdir = NULL;
                    216:        cr.leavedir = NULL;
                    217:
                    218:        if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                    219:                cr.fileproc = cvs_client_sendfile;
                    220:
                    221:                if (!(flags & CR_RECURSE_DIRS))
                    222:                        cvs_client_send_request("Argument -l");
                    223:        } else {
                    224:                cr.fileproc = cvs_unedit_local;
                    225:        }
                    226:
                    227:        cr.flags = flags;
                    228:
                    229:        cvs_file_run(argc, argv, &cr);
                    230:
                    231:        if (current_cvsroot->cr_method != CVS_METHOD_LOCAL) {
                    232:                cvs_client_send_files(argv, argc);
                    233:                cvs_client_senddir(".");
                    234:                cvs_client_send_request("unedit");
                    235:                cvs_client_get_responses();
                    236:        }
                    237:
                    238:        return (0);
1.18      xsa       239: }
                    240:
                    241: static void
                    242: cvs_edit_local(struct cvs_file *cf)
                    243: {
                    244:        FILE *fp;
                    245:        struct tm *t;
                    246:        time_t now;
1.21      xsa       247:        char *bfpath, timebuf[64], thishost[MAXHOSTNAMELEN], wdir[MAXPATHLEN];
1.18      xsa       248:
                    249:        if (cvs_noexec == 1)
                    250:                return;
                    251:
                    252:        if ((fp = fopen(CVS_PATH_NOTIFY, "a")) == NULL)
                    253:                fatal("cvs_edit_local: fopen: `%s': %s",
                    254:                    CVS_PATH_NOTIFY, strerror(errno));
                    255:
                    256:        (void)time(&now);
                    257:        if ((t = gmtime(&now)) == NULL)
                    258:                fatal("gmtime failed");
                    259:
1.20      xsa       260:        asctime_r(t, timebuf);
                    261:        if (timebuf[strlen(timebuf) - 1] == '\n')
                    262:                 timebuf[strlen(timebuf) - 1] = '\0';
1.18      xsa       263:
1.19      xsa       264:        if (gethostname(thishost, sizeof(thishost)) == -1)
                    265:                fatal("gethostname failed");
                    266:
1.21      xsa       267:        if (getcwd(wdir, sizeof(wdir)) == NULL)
                    268:                fatal("getcwd failed");
                    269:
1.18      xsa       270:        (void)fprintf(fp, "E%s\t%s GMT\t%s\t%s\t\n",
1.21      xsa       271:            cf->file_name, timebuf, thishost, wdir);
1.18      xsa       272:
                    273:        if (edit_aflags & E_EDIT)
                    274:                (void)fprintf(fp, "E");
                    275:        if (edit_aflags & E_UNEDIT)
                    276:                (void)fprintf(fp, "U");
                    277:        if (edit_aflags & E_COMMIT)
                    278:                (void)fprintf(fp, "C");
                    279:
                    280:        (void)fprintf(fp, "\n");
                    281:
                    282:        (void)fclose(fp);
                    283:
                    284:        if (fchmod(cf->fd, 0644) == -1)
                    285:                fatal("cvs_edit_local: fchmod %s", strerror(errno));
                    286:
                    287:        bfpath = xmalloc(MAXPATHLEN);
                    288:        if (cvs_path_cat(CVS_PATH_BASEDIR, cf->file_name, bfpath,
                    289:            MAXPATHLEN) >= MAXPATHLEN)
                    290:                fatal("cvs_edit_local: truncation");
1.22    ! xsa       291:
        !           292:        if (mkdir(CVS_PATH_BASEDIR, 0755) == -1 && errno != EEXIST)
        !           293:                fatal("cvs_edit_local: `%s': %s", CVS_PATH_BASEDIR,
        !           294:                    strerror(errno));
1.18      xsa       295:
                    296:        /* XXX: copy cf->file_path to bfpath */
                    297:
                    298:        xfree(bfpath);
                    299:
                    300:        /* XXX: Update revision number in CVS/Baserev from CVS/Entries */
1.15      xsa       301: }
                    302:
1.14      xsa       303: static void
                    304: cvs_editors_local(struct cvs_file *cf)
                    305: {
1.15      xsa       306: }
                    307:
                    308: static void
                    309: cvs_unedit_local(struct cvs_file *cf)
                    310: {
                    311:        FILE *fp;
                    312:        struct stat st;
                    313:        struct tm *t;
                    314:        time_t now;
1.21      xsa       315:        char *bfpath, timebuf[64], thishost[MAXHOSTNAMELEN], wdir[MAXPATHLEN];
1.15      xsa       316:
                    317:        if (cvs_noexec == 1)
                    318:                return;
                    319:
                    320:        bfpath = xmalloc(MAXPATHLEN);
                    321:        if (cvs_path_cat(CVS_PATH_BASEDIR, cf->file_name, bfpath,
                    322:            MAXPATHLEN) >= MAXPATHLEN)
                    323:                fatal("cvs_unedit_local: truncation");
                    324:
                    325:        if (stat(bfpath, &st) == -1) {
                    326:                xfree(bfpath);
                    327:                return;
                    328:        }
                    329:
1.17      xsa       330:        if (cvs_file_cmp(cf->file_path, bfpath) != 0) {
                    331:                cvs_printf("%s has been modified; revert changes? ",
                    332:                    cf->file_name);
                    333:
                    334:                if (cvs_yesno() == -1) {
                    335:                        xfree(bfpath);
                    336:                        return;
                    337:                }
                    338:        }
1.15      xsa       339:
                    340:        cvs_rename(bfpath, cf->file_path);
                    341:        xfree(bfpath);
                    342:
                    343:        if ((fp = fopen(CVS_PATH_NOTIFY, "a")) == NULL)
                    344:                fatal("cvs_unedit_local: fopen: `%s': %s",
                    345:                    CVS_PATH_NOTIFY, strerror(errno));
                    346:
                    347:        (void)time(&now);
                    348:        if ((t = gmtime(&now)) == NULL)
                    349:                fatal("gmtime failed");
                    350:
1.20      xsa       351:        asctime_r(t, timebuf);
                    352:        if (timebuf[strlen(timebuf) - 1] == '\n')
                    353:                 timebuf[strlen(timebuf) - 1] = '\0';
1.15      xsa       354:
1.19      xsa       355:        if (gethostname(thishost, sizeof(thishost)) == -1)
                    356:                fatal("gethostname failed");
                    357:
1.21      xsa       358:        if (getcwd(wdir, sizeof(wdir)) == NULL)
                    359:
                    360:                fatal("getcwd failed");
1.15      xsa       361:        (void)fprintf(fp, "U%s\t%s GMT\t%s\t%s\t\n",
1.21      xsa       362:            cf->file_name, timebuf, thishost, wdir);
1.15      xsa       363:
                    364:        (void)fclose(fp);
                    365:
                    366:        /* XXX: Update revision number in CVS/Entries from CVS/Baserev */
1.16      xsa       367:
                    368:        if (fchmod(cf->fd, 0644) == -1)
                    369:                fatal("cvs_unedit_local: fchmod %s", strerror(errno));
1.1       jfb       370: }