[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.20

1.20    ! xsa         1: /*     $OpenBSD: edit.c,v 1.19 2007/01/05 08:52:37 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.20    ! xsa       247:        char *bfpath, timebuf[64], thishost[MAXHOSTNAMELEN];
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.18      xsa       267:        (void)fprintf(fp, "E%s\t%s GMT\t%s\t%s\t\n",
1.20    ! xsa       268:            cf->file_name, timebuf, thishost, cf->file_wd);
1.18      xsa       269:
                    270:        if (edit_aflags & E_EDIT)
                    271:                (void)fprintf(fp, "E");
                    272:        if (edit_aflags & E_UNEDIT)
                    273:                (void)fprintf(fp, "U");
                    274:        if (edit_aflags & E_COMMIT)
                    275:                (void)fprintf(fp, "C");
                    276:
                    277:        (void)fprintf(fp, "\n");
                    278:
                    279:        (void)fclose(fp);
                    280:
                    281:        if (fchmod(cf->fd, 0644) == -1)
                    282:                fatal("cvs_edit_local: fchmod %s", strerror(errno));
                    283:
                    284:        bfpath = xmalloc(MAXPATHLEN);
                    285:        if (cvs_path_cat(CVS_PATH_BASEDIR, cf->file_name, bfpath,
                    286:            MAXPATHLEN) >= MAXPATHLEN)
                    287:                fatal("cvs_edit_local: truncation");
                    288:
                    289:        /* XXX: copy cf->file_path to bfpath */
                    290:
                    291:        xfree(bfpath);
                    292:
                    293:        /* XXX: Update revision number in CVS/Baserev from CVS/Entries */
1.15      xsa       294: }
                    295:
1.14      xsa       296: static void
                    297: cvs_editors_local(struct cvs_file *cf)
                    298: {
1.15      xsa       299: }
                    300:
                    301: static void
                    302: cvs_unedit_local(struct cvs_file *cf)
                    303: {
                    304:        FILE *fp;
                    305:        struct stat st;
                    306:        struct tm *t;
                    307:        time_t now;
1.20    ! xsa       308:        char *bfpath, timebuf[64], thishost[MAXHOSTNAMELEN];
1.15      xsa       309:
                    310:        if (cvs_noexec == 1)
                    311:                return;
                    312:
                    313:        bfpath = xmalloc(MAXPATHLEN);
                    314:        if (cvs_path_cat(CVS_PATH_BASEDIR, cf->file_name, bfpath,
                    315:            MAXPATHLEN) >= MAXPATHLEN)
                    316:                fatal("cvs_unedit_local: truncation");
                    317:
                    318:        if (stat(bfpath, &st) == -1) {
                    319:                xfree(bfpath);
                    320:                return;
                    321:        }
                    322:
1.17      xsa       323:        if (cvs_file_cmp(cf->file_path, bfpath) != 0) {
                    324:                cvs_printf("%s has been modified; revert changes? ",
                    325:                    cf->file_name);
                    326:
                    327:                if (cvs_yesno() == -1) {
                    328:                        xfree(bfpath);
                    329:                        return;
                    330:                }
                    331:        }
1.15      xsa       332:
                    333:        cvs_rename(bfpath, cf->file_path);
                    334:        xfree(bfpath);
                    335:
                    336:        if ((fp = fopen(CVS_PATH_NOTIFY, "a")) == NULL)
                    337:                fatal("cvs_unedit_local: fopen: `%s': %s",
                    338:                    CVS_PATH_NOTIFY, strerror(errno));
                    339:
                    340:        (void)time(&now);
                    341:        if ((t = gmtime(&now)) == NULL)
                    342:                fatal("gmtime failed");
                    343:
1.20    ! xsa       344:        asctime_r(t, timebuf);
        !           345:        if (timebuf[strlen(timebuf) - 1] == '\n')
        !           346:                 timebuf[strlen(timebuf) - 1] = '\0';
1.15      xsa       347:
1.19      xsa       348:        if (gethostname(thishost, sizeof(thishost)) == -1)
                    349:                fatal("gethostname failed");
                    350:
1.15      xsa       351:        (void)fprintf(fp, "U%s\t%s GMT\t%s\t%s\t\n",
1.20    ! xsa       352:            cf->file_name, timebuf, thishost, cf->file_wd);
1.15      xsa       353:
                    354:        (void)fclose(fp);
                    355:
                    356:        /* XXX: Update revision number in CVS/Entries from CVS/Baserev */
1.16      xsa       357:
                    358:        if (fchmod(cf->fd, 0644) == -1)
                    359:                fatal("cvs_unedit_local: fchmod %s", strerror(errno));
1.1       jfb       360: }