/* $Cambridge: hermes/src/prayer/accountd/fullname.c,v 1.2 2004/10/01 12:42:27 dpc22 Exp $ */
/************************************************
 *    Prayer - a Webmail Interface              *
 ************************************************/

/* Copyright (c) University of Cambridge 2000 - 2002 */
/* See the file NOTICE for conditions of use and distribution. */

#include "accountd.h"

/* fullname_change_internal() ********************************************
 *
 * Start up passwd program and chat with it to change fullname
 *   config: Accountd configuration
 * password: Account password, if needed
 *  newname: New fullname
 *
 * Returns: Error string. NIL => all okay
 ************************************************************************/

static char *fullname_change_internal(struct config *config,
                                      char *password, char *new)
{
    struct pool *pool = pool_create(0);
    struct assoc *h = assoc_create(pool, 16, T);
    struct process process;
    char *error;
    char *cmdline;

    assoc_update(h, "password", password, T);
    assoc_update(h, "newname", new, T);

    /* Expand */
    cmdline = string_expand(pool, h, config->full_cmdline);

    process_clear(&process);

    if (!process_start(&process, cmdline,
                       config->full_pty, config->child_timeout)) {
        pool_free(pool);
        return ("Couldn't start the password program");
    }

    error = process_run_script(&process, pool, h,
                               pool_strdup(pool, config->full_script), NIL,
                               0L);

    if (!process_stop(&process)) {
        pool_free(pool);
        return ("Error code from password program");
    }

    pool_free(pool);
    return (error);
}


/* fullname_change() *****************************************************
 *
 * Change passwd using the passwd program
 *  config: Accountd configuration
 *  stream: iostream connection to client
 *    line: Arguments for FULLNAME command.
 *          Should be new fullname.
 *
 * Returns: T  in all situations
 *   OK [text]. Password changed
 *   NO [text]. Failed to change password
 *  BAD [text]. Protocol error
 ************************************************************************/

BOOL
fullname_change(struct config * config, struct iostream * stream,
                char *line)
{
    char *s1, *s2, *password, *newname, *errmsg;

    if (!((s1 = string_get_token(&line)) && (s1[0]))) {
        ioputs(stream, "BAD No new fullname" CRLF);
        ioflush(stream);
        return (T);
    }

    if ((s2 = string_get_token(&line)) && (s2[0])) {
        password = s1;          /* New format, "password Newname" */
        newname = s2;
        string_canon_decode(password);
        string_canon_decode(newname);
    } else {
        password = "";          /* Old format, single "Newname" argument */
        newname = s1;
        string_canon_decode(newname);
    }

    if (!(errmsg = fullname_change_internal(config, password, newname)))
        ioputs(stream, "OK Changed fullname" CRLF);
    else if (errmsg[0])
        ioprintf(stream, "NO %s" CRLF, errmsg);
    else
        ioputs(stream, "NO Failed to change fullname" CRLF);
    ioflush(stream);
    return (T);
}

/* ====================================================================== */

/* fullname_check() ******************************************************
 *
 * Check fullname with server.
 *   config: Accountd configuration
 *   stream: iostream connection to client
 ************************************************************************/

BOOL fullname_check(struct config * config, struct iostream * stream)
{
    struct pool *pool = pool_create(0);
    struct assoc *h = assoc_create(pool, 16, T);
    char buffer[MAXLENGTH];
    char *error;
    struct process process;

    process_clear(&process);
    if (!process_start(&process, config->checkfull_cmdline,
                       config->checkfull_pty, config->child_timeout)) {
        pool_free(pool);
        ioputs(stream, "NO Couldn't fetch Fullname from server" CRLF);
        ioflush(stream);
        return (NIL);
    }

    error = process_run_script(&process, pool, h,
                               pool_strdup(pool, config->checkfull_script),
                               buffer, MAXLENGTH);

    process_stop(&process);
    pool_free(pool);

    if (error) {
        ioprintf(stream, "NO Couldn't fetch Fullname from server: %s" CRLF,
                 error);
        ioflush(stream);
        return (NIL);
    }

    ioprintf(stream, "OK %s" CRLF, buffer);
    ioflush(stream);
    return (T);
}
