/* $Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/moira/dbck/phase4.dc,v 1.4 1996/06/02 07:42:32 ghudson Exp $
 *
 *  (c) Copyright 1988 by the Massachusetts Institute of Technology.
 *  For copying and distribution information, please see the file
 *  <mit-copyright.h>.
 */

#include <mit-copyright.h>
#include <moira.h>
#include "dbck.h"
EXEC SQL INCLUDE sqlca;

static char phase4_qc_rcsid[] = "$Header: /afs/sipb.mit.edu/project/sipb-athena/repository/src/moira/dbck/phase4.dc,v 1.4 1996/06/02 07:42:32 ghudson Exp $";


count_boxes(id, u, boxes)
int id;
struct user *u;
struct hash *boxes;
{
    int i;

    if (u->potype == 'P') {
	if (i = (int) hash_lookup(boxes, u->pobox_id))
	  hash_store(boxes, u->pobox_id, i+1);
	else {
	  printf("User %s(%s) has pobox on non-POP server %d\n",
		 u->fullname, u->login, u->pobox_id);
	  printf("Not fixing this error\n");
        }
    }
}


check_box_counts(id, cnt, counts)
EXEC SQL BEGIN DECLARE SECTION; 
int id, cnt;
EXEC SQL END DECLARE SECTION; 
struct hash *counts;
{
    EXEC SQL BEGIN DECLARE SECTION; 
    int oldval, rowcount;
    EXEC SQL END DECLARE SECTION; 

    oldval = (int) hash_lookup(counts, id);
    cnt--;
    if (oldval != cnt) {
	printf("Count wrong on POBox machine %s; is %d in db, counted %d\n",
	       ((struct machine *) hash_lookup(machines, id))->name,
	       oldval, cnt);
	if (single_fix("Update", 1)) {
	    EXEC SQL UPDATE serverhosts SET value1 = :cnt
		WHERE service='POP' AND mach_id = :id;
  	    EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
	    if (rowcount > 0)
	      printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies");
	    else
	      printf("Not fixed\n");
	    modified("serverhosts");
	}
    }
}


check_nfs_counts(id, n, hint)
EXEC SQL BEGIN DECLARE SECTION; 
int id, hint;
EXEC SQL END DECLARE SECTION; 
struct nfsphys *n;
{
    EXEC SQL BEGIN DECLARE SECTION; 
    int val, rowcount;
    EXEC SQL END DECLARE SECTION; 

    val = n->count;
    if (n->allocated != val) {
	printf("Count wrong on NFSphys %s:%s; is %d in db, counted %d\n",
	       ((struct machine *) hash_lookup(machines, n->mach_id))->name,
	       n->dir, n->allocated, val);
	if (single_fix("Update", 1)) {
	    EXEC SQL UPDATE nfsphys SET allocated = :val 
		WHERE nfsphys_id = :id;
  	    EXEC SQL INQUIRE_SQL(:rowcount = rowcount);
	    if (rowcount > 0)
	      printf("%d entr%s fixed\n", rowcount, rowcount==1?"y":"ies");
	    else
	      printf("Not fixed\n");
	    modified("nfsphys");
	}
    }
}


phase4()
{
    struct hash *boxes, *counts;
    EXEC SQL BEGIN DECLARE SECTION; 
    int id, cnt;
    EXEC SQL END DECLARE SECTION; 

    printf("Phase 4 - Checking counts\n");

    dprintf("Doing POBoxes...\n");
    boxes = create_hash(10);
    counts = create_hash(10);
    EXEC SQL DECLARE csr401 CURSOR FOR
	SELECT mach_id, value1 FROM serverhosts
	    WHERE service='POP';
    if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode);
    EXEC SQL OPEN csr401;
    while(1) {
	EXEC SQL FETCH csr401 INTO :id, :cnt;
	if (sqlca.sqlcode != 0) {
	  ingerr(&sqlca.sqlcode);
	  break;
	} 
	
	hash_store(boxes, id, 1);
	hash_store(counts, id, cnt);
    }
    EXEC SQL CLOSE csr401; 
    hash_step(users, count_boxes, boxes);
    hash_step(boxes, check_box_counts, counts);

    dprintf("Doing NFSphys...\n");
    hash_step(nfsphys, check_nfs_counts, 0);
}


count_only_setup()
{
    EXEC SQL BEGIN DECLARE SECTION; 
    int id, status, id2, id3;
    char name[33], last[17], first[17], buf[257];
    EXEC SQL END DECLARE SECTION; 
    struct save_queue *sq;
    struct user *u;
    struct nfsphys *n;
    struct machine *m;

    dprintf("Loading users...\n");
    users = create_hash(10000);
    EXEC SQL DECLARE csr402 CURSOR FOR
	SELECT users_id, login, last, first, status, 
	       potype, pop_id, box_id FROM users
	    WHERE potype='POP';
    if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode);
    EXEC SQL OPEN csr402;
    while(1) {
	EXEC SQL FETCH csr402 INTO :id, :name, :last, :first, :status, 
	    :buf, :id2, :id3;
	if (sqlca.sqlcode != 0) {
	  ingerr(&sqlca.sqlcode);
	  break;
	} 

    	u = (struct user *) malloc(sizeof(struct user));
	if (u == NULL)
	  out_of_mem("storing users");
	strcpy(u->login, strtrim(name));
	u->potype = buf[0];
	sprintf(buf, "%s, %s", strtrim(last), strtrim(first));
	u->fullname = strsave(buf);
	u->status = status;
	u->users_id = id;
	switch (u->potype) {
	case 'P':
	    u->pobox_id = id2;
	    break;
	case 'S':
	    u->pobox_id = id3;
	    break;
	default:
	    u->pobox_id = 0;
	}
	hash_store(users, id, u);
	}
    EXEC SQL CLOSE csr402; 

    dprintf("Loading machines...\n");
    machines = create_hash(1000);
    EXEC SQL DECLARE csr403 CURSOR FOR
	SELECT mach_id, name FROM machine;
    if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode);
    EXEC SQL OPEN csr403;
    while(1) {
	EXEC SQL FETCH csr403 INTO :id, :name;
	if (sqlca.sqlcode != 0) {
	  ingerr(&sqlca.sqlcode);
	  break;
	} 

    	m = (struct machine *) malloc(sizeof(struct machine));
	if (m == NULL)
	  out_of_mem("storing machines");
	strcpy(m->name, strtrim(name));
	m->mach_id = id;
	hash_store(machines, id, m);
    }
    EXEC SQL CLOSE csr403; 

    dprintf("Loading nfsphys...\n");
    nfsphys = create_hash(500);
    EXEC SQL DECLARE csr404 CURSOR FOR
	SELECT nfsphys_id, dir, mach_id, allocated FROM nfsphys;
    if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode);
    EXEC SQL OPEN csr404;
    while(1) {
	EXEC SQL FETCH csr404 INTO :id, :name, :id2, :id3;
	if (sqlca.sqlcode != 0) {
	  ingerr(&sqlca.sqlcode);
	  break;
	} 

    	n = (struct nfsphys *) malloc(sizeof(struct nfsphys));
	if (n == NULL)
	  out_of_mem("storing nfsphys");
	strcpy(n->dir, strtrim(name));
	n->mach_id = id2;
	n->nfsphys_id = id;
	n->allocated = id3;
	n->count = 0;
	hash_store(nfsphys, id, n);
	}
    EXEC SQL CLOSE csr404; 

    dprintf("Counting quotas...\n");
    EXEC SQL DECLARE csr405 CURSOR FOR
	SELECT phys_id, quota FROM quota;
    if (sqlca.sqlcode != 0) ingerr(&sqlca.sqlcode);
    EXEC SQL OPEN csr405;
    while(1) {
	EXEC SQL FETCH csr405 INTO :id, :id2;
	if (sqlca.sqlcode != 0) {
	  ingerr(&sqlca.sqlcode);
	  break;
	} 
	
        if (n = (struct nfsphys  *) hash_lookup(nfsphys, id)) {
	    n->count += id2;
	}
    }
    EXEC SQL CLOSE csr405; 
}
