/*
 * tagput - tag writer wrapper for `id3put' and `vorbiscomment'
 * Copyright 2002, 2008 by HIROSE Yuuji [yuuji@gentei.org]
 * $Id: tagput.c,v 1.2 2008/05/16 14:12:53 yuuji Exp $
 * Last modified Fri May 16 23:12:14 2008 on firestorm
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>

char *newogg;

void erase()
{
    unlink(newogg);
    exit(200);
}


void do_ogg(target)
     char *target;
{
    int fds[2];
    pid_t pid;
    struct stat tg;
    int tmplen;
    long origsz;
    signal(SIGINT, erase);
    if (-1 == pipe(fds)) {
        fputs("Pipe error", stderr);
        exit(1);
    }
    /* fds[0] -- for read
     * fds[1] -- for write (from the viewpoint of parent)
     */
    if (-1 == stat(target, &tg)) {
        fprintf(stderr, "No such file %s\n", target);
        exit(2);
    }
    if ((tg.st_mode&S_IRUSR) == 0) {
        fprintf(stderr, "Cannot read file %s\n", target);
        exit(3);
    }
    origsz = tg.st_size;
    /* Create temp file name */
    tmplen = strlen(target)+strlen(".XXXXXX")+1;
    if (NULL == (newogg=(char*)malloc(tmplen))) {
        fputs("Cannot allocate memory for newoggname\n", stderr);
        exit(4);
    }
    snprintf(newogg, tmplen, "%s.XXXXXX", target);
    mktemp(newogg);        /* mktemp is OK, not mkstemp */
    if (0 == (pid=fork())) {      /* child */
        
        close(fds[1]);          /* no need to write */
        close(0);               /* close stdin */
        dup(fds[0]);            /* substitute fds[0] to stdin  */
        close(fds[0]);

        execlp("vorbiscomment", "vorbiscomment", "-w", target, newogg, '\0');
        execlp("tee", "tee", "tee", '\0'); /* for debug */
        fputs("exec failed\n", stderr);
        exit(1);
        
    } else {                    /* parent */
        int c;
        char *attr[] = {"title", "artist", "album", "year",
                        "comment", "genre"};
        int i, s, nattr=6;
        // puts("oge");
        close(fds[0]);          /* no need to read */
        close(1);               /* close stdout */
        dup(fds[1]);
        close(fds[1]);
        for (i=0; i<nattr; i++) {
            write(1, attr[i], strlen(attr[i]));
            write(1, "=", 1);
            while (EOF != (c=getchar())) {
                switch (c) {
                case '\n':
                    write(1, &c, 1);
                    goto mainloop;
                case '\r':
                    continue;
                default:
                    write(1, &c, 1);
                }
            }
            break;
        mainloop:
            continue;
        }
        close(1);
        waitpid(pid, &s, 0);
        fprintf(stderr, "done[%d],%d\n", s, pid);
        if (-1 == stat(newogg, &tg) || tg.st_size == 0) {
            fprintf(stderr, "Failed to output %s\n", newogg);
            unlink(newogg);
            exit(4);
        }
        rename(newogg, target);
        exit(0);
    }
}
int main(argc, argv)
     int argc;
     char *argv[];
{
    char *target;
    if (argc < 2) {
        fprintf(stderr, "Usage: %s soundfile\n", argv[0]);
        fprintf(stderr, "This is a wrapper for id3put/vorbiscomment.\
Call this program via id3.el (by kurati).\
Install this program into some directory where command search path($PATH)\
points to. (ex. /usr/local/bin)\n");
        exit(0);
    }
    target=argv[1];
    if (strlen(target) < 5) {
        fprintf(stderr, "soundfile name should end with `.mp3' or `.ogg'\n");
        exit(1);
    }
    if (strncasecmp(".mp3", target+strlen(target)-4, 4)==0) {
        argv[0] = "id3put";
        execvp("id3put", argv);
        fputs("Fail", stderr);
        exit(1);
    }
    if (strncasecmp(".ogg", target+strlen(target)-4, 4)==0) {
        do_ogg(argv[1]);
    }
    exit(0);
}
