Beispiel #1
0
Datei: exec.c Projekt: jmgc/noah
int
do_exec(const char *elf_path, int argc, char *argv[], char **envp)
{
  int err;
  int fd;
  struct stat st;
  char *data;
  
  if ((err = do_access(elf_path, X_OK)) < 0) {
    return err;
  }
  if ((fd = vkern_open(elf_path, LINUX_O_RDONLY, 0)) < 0) {
    return fd;
  }
  if (proc.nr_tasks > 1) {
    warnk("Multi-thread execve is not implemented yet\n");
    return -LINUX_EINVAL;
  }

  /* Now do exec */
  fstat(fd, &st);
  if (!S_ISREG(st.st_mode)) {
    vkern_close(fd);
    return -LINUX_EACCES;
  }

  prepare_newproc();

  data = mmap(0, st.st_size, PROT_READ | PROT_EXEC, MAP_PRIVATE, fd, 0);

  vkern_close(fd);

  drop_privilege();

  if (4 <= st.st_size && memcmp(data, ELFMAG, 4) == 0) {
    if ((err = load_elf((Elf64_Ehdr *) data, argc, argv, envp)) < 0)
      return err;
    if (st.st_mode & 04000) {
      elevate_privilege();
    }
  }
  else if (2 <= st.st_size && data[0] == '#' && data[1] == '!') {
    if ((err = load_script(data, st.st_size, elf_path, argc, argv, envp)) < 0)
      return err;
  }
  /*else if (4 <= st.st_size && memcmp(data, "\xcf\xfa\xed\xfe", 4) == 0) {
    // Mach-O
    return syswrap(execve(elf_path, argv, envp));
  }*/
  else {
    return -LINUX_ENOEXEC;                  /* unsupported file type */
  }

  munmap(data, st.st_size);
  proc.mm->current_brk = proc.mm->start_brk;

  return 0;
}
Beispiel #2
0
int restore_line(const char *filename,uint64_t lv,char *line) {
	char *ptr;
	uint32_t ts;
	int status;
	char* errormsgs[]={ ERROR_STRINGS };

	status = ERROR_MISMATCH;
	ptr = line;

	EAT(ptr,filename,lv,':');
	EAT(ptr,filename,lv,' ');
	GETU32(ts,ptr);
	EAT(ptr,filename,lv,'|');
	switch (*ptr) {
		case 'A':
			if (strncmp(ptr,"ACCESS",6)==0) {
				status = do_access(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"ATTR",4)==0) {
				status = do_attr(filename,lv,ts,ptr+4);
			} else if (strncmp(ptr,"APPEND",6)==0) {
				status = do_append(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"ACQUIRE",7)==0) {
				status = do_acquire(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"AQUIRE",6)==0) {
				status = do_acquire(filename,lv,ts,ptr+6);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'C':
			if (strncmp(ptr,"CREATE",6)==0) {
				status = do_create(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"CUSTOMER",8)==0) {	// deprecated
				status = do_session(filename,lv,ts,ptr+8);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'E':
			if (strncmp(ptr,"EMPTYTRASH",10)==0) {
				status = do_emptytrash(filename,lv,ts,ptr+10);
			} else if (strncmp(ptr,"EMPTYRESERVED",13)==0) {
				status = do_emptyreserved(filename,lv,ts,ptr+13);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'F':
			if (strncmp(ptr,"FREEINODES",10)==0) {
				status = do_freeinodes(filename,lv,ts,ptr+10);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'I':
			if (strncmp(ptr,"INCVERSION",10)==0) {
				status = do_incversion(filename,lv,ts,ptr+10);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'L':
			if (strncmp(ptr,"LENGTH",6)==0) {
				status = do_length(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"LINK",4)==0) {
				status = do_link(filename,lv,ts,ptr+4);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'M':
			if (strncmp(ptr,"MOVE",4)==0) {
				status = do_move(filename,lv,ts,ptr+4);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'P':
			if (strncmp(ptr,"PURGE",5)==0) {
				status = do_purge(filename,lv,ts,ptr+5);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'Q':
			if (strncmp(ptr,"QUOTA",5)==0) {
				status = do_quota(filename,lv,ts,ptr+5);
			}
			break;
		case 'R':
			if (strncmp(ptr,"RELEASE",7)==0) {
				status = do_release(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"REPAIR",6)==0) {
				status = do_repair(filename,lv,ts,ptr+6);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'S':
			if (strncmp(ptr,"SETEATTR",8)==0) {
				status = do_seteattr(filename,lv,ts,ptr+8);
			} else if (strncmp(ptr,"SETGOAL",7)==0) {
				status = do_setgoal(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"SETPATH",7)==0) {
				status = do_setpath(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"SETTRASHTIME",12)==0) {
				status = do_settrashtime(filename,lv,ts,ptr+12);
			} else if (strncmp(ptr,"SETXATTR",8)==0) {
				status = do_setxattr(filename,lv,ts,ptr+8);
			} else if (strncmp(ptr,"SNAPSHOT",8)==0) {
				status = do_snapshot(filename,lv,ts,ptr+8);
			} else if (strncmp(ptr,"SYMLINK",7)==0) {
				status = do_symlink(filename,lv,ts,ptr+7);
			} else if (strncmp(ptr,"SESSION",7)==0) {
				status = do_session(filename,lv,ts,ptr+7);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'T':
			if (strncmp(ptr,"TRUNC",5)==0) {
				status = do_trunc(filename,lv,ts,ptr+5);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'U':
			if (strncmp(ptr,"UNLINK",6)==0) {
				status = do_unlink(filename,lv,ts,ptr+6);
			} else if (strncmp(ptr,"UNDEL",5)==0) {
				status = do_undel(filename,lv,ts,ptr+5);
			} else if (strncmp(ptr,"UNLOCK",6)==0) {
				status = do_unlock(filename,lv,ts,ptr+6);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		case 'W':
			if (strncmp(ptr,"WRITE",5)==0) {
				status = do_write(filename,lv,ts,ptr+5);
			} else {
				printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
			}
			break;
		default:
			printf("%s:%"PRIu64": unknown entry '%s'\n",filename,lv,ptr);
	}
	if (status>STATUS_OK) {
		printf("%s:%"PRIu64": error: %d (%s)\n",filename,lv,status,errormsgs[status]);
	}
	return status;
}
Beispiel #3
0
int replay(const char *log_data) {
	uint64_t fv,lv; //fv = filesystem's version lv = log's version
	uint32_t ts;
	uint8_t status;
	char buff[10000];
	char *ptr;
	char* errormsgs[]={ ERROR_STRINGS };

	char *test_ptr;

	sprintf(buff,"%s",log_data);
	ptr = buff;
//for test
	test_ptr = buff;
	fv = shadow_fs_getversion();
	GETU64(lv,ptr);
	if(lv < fv) {
		MFSLOG(LOG_ERR,"the changelog's verison %lu is smaller than filesystem's version %lu",lv,fv);
		//more complicated method to ensure consistency
	} else {
		status = ERROR_MISMATCH; 
                EAT(ptr,lv,':');
                EAT(ptr,lv,' ');
                GETU32(ts,ptr);
                EAT(ptr,lv,'|');
                switch (*ptr) {
                	case 'A':
                                if (strncmp(ptr,"ACCESS",6)==0) {
                                        status = do_access(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"ATTR",4)==0) {
                                        status = do_attr(lv,ts,ptr+4);
                                } else if (strncmp(ptr,"APPEND",6)==0) {
                                        status = do_append(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"AQUIRE",6)==0) {
                                        status = do_aquire(lv,ts,ptr+6);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                } 
                                break;  
                        case 'C':
                                if (strncmp(ptr,"CREATE",6)==0) {
                                        status = do_create(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"CUSTOMER",8)==0) {      // deprecated
                                        status = do_session(lv,ts,ptr+8);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                } 
                                break;  
                        case 'E':
                                if (strncmp(ptr,"EMPTYTRASH",10)==0) {
                                        status = do_emptytrash(lv,ts,ptr+10);
                                } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) {
                                        status = do_emptyreserved(lv,ts,ptr+13);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                } 
                                break;  
                        case 'F': 
                                if (strncmp(ptr,"FREEINODES",10)==0) {
                                        status = do_freeinodes(lv,ts,ptr+10);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'I':
                                if (strncmp(ptr,"INCVERSION",10)==0) {
                                        status = do_incversion(lv,ts,ptr+10);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'L':
                                if (strncmp(ptr,"LENGTH",6)==0) {
                                        status = do_length(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"LINK",4)==0) {
                                        status = do_link(lv,ts,ptr+4);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'M':
                                if (strncmp(ptr,"MOVE",4)==0) {
                                        status = do_move(lv,ts,ptr+4);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'P':
                                if (strncmp(ptr,"PURGE",5)==0) {
                                        status = do_purge(lv,ts,ptr+5);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'R':
                                if (strncmp(ptr,"RELEASE",7)==0) {
                                        status = do_release(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"REPAIR",6)==0) {
                                        status = do_repair(lv,ts,ptr+6);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'S':
                                if (strncmp(ptr,"SETEATTR",8)==0) {
                                        status = do_seteattr(lv,ts,ptr+8);
                                } else if (strncmp(ptr,"SETGOAL",7)==0) {
                                        status = do_setgoal(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"SETPATH",7)==0) {
                                        status = do_setpath(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"SETTRASHTIME",12)==0) {
                                        status = do_settrashtime(lv,ts,ptr+12);
                                } else if (strncmp(ptr,"SNAPSHOT",8)==0) {
                                        status = do_snapshot(lv,ts,ptr+8);
                                } else if (strncmp(ptr,"SYMLINK",7)==0) {
                                        status = do_symlink(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"SESSION",7)==0) {
                                        status = do_session(lv,ts,ptr+7);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'T':
                                if (strncmp(ptr,"TRUNC",5)==0) {
                                        status = do_trunc(lv,ts,ptr+5);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'U':
                                if (strncmp(ptr,"UNLINK",6)==0) {
                                        status = do_unlink(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"UNDEL",5)==0) {
                                        status = do_undel(lv,ts,ptr+5);
                                } else if (strncmp(ptr,"UNLOCK",6)==0) {
                                        status = do_unlock(lv,ts,ptr+6);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'W':
                                if (strncmp(ptr,"WRITE",5)==0) {
                                        status = do_write(lv,ts,ptr+5);
                                } else {
                                        MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        default:
                                MFSLOG(LOG_ERR,"%"PRIu64": unknown entry '%s'",lv,ptr);
                        }
			/**
			  * if master is down, slave switch, we may missed some metadata 
			  * return 0 to let the process continue, otherwise, we will reply the 
			  * log forever.
			  * 
			  * Dongyang, Zhang
			  */				
			if (status!=STATUS_OK) {
				MFSLOG(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s),the log is (%s)",lv,status,errormsgs[status],test_ptr);
//                                syslog(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s)",lv,status,errormsgs[status]);
                           return 1;
                        }               
                        fv = shadow_fs_getversion();
                        if (lv+1!=fv) {
                                MFSLOG(LOG_ERR,"%"PRIu64": version mismatch fsversion:%"PRIu64"",lv,fv);
                                return 1;
                        }
	}
	return 0;
}                
Beispiel #4
0
int restore(void) {
        FILE *fd;
        char buff[10000];
        char *ptr;
        uint64_t v,lv;
        uint32_t ts;
        uint8_t status;
	uint32_t dplen;
	char *datapath = NULL;
	char *logpath = NULL;
        char* errormsgs[]={ ERROR_STRINGS };
        
        v = shadow_fs_getversion();
        lv = 0;

        MFSLOG(LOG_NOTICE,"meta data version: %"PRIu64"",v);
        
	datapath = strdup(DATA_PATH);
	dplen = strlen(datapath);
	logpath = malloc(dplen+sizeof("/changelog.0.mfs"));
	memcpy(logpath,datapath,dplen);
	memcpy(logpath+dplen,"/changelog.0.mfs",sizeof("/changelog.0.mfs"));
        fd = fopen(logpath,"r");
        if (fd==NULL) {
                MFSLOG(LOG_NOTICE,"can't open changemeta file: %s",logpath);
                return 1;
        }
        while (fgets(buff,10000,fd)) {
                ptr = buff;
                GETU64(lv,ptr);
                if (lv<v) {
                        // skip
                } else {
                        status = ERROR_MISMATCH;
                        EAT(ptr,lv,':');
                        EAT(ptr,lv,' ');
                        GETU32(ts,ptr);
                        EAT(ptr,lv,'|');
                        switch (*ptr) {
                        case 'A':
                                if (strncmp(ptr,"ACCESS",6)==0) {
                                        status = do_access(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"ATTR",4)==0) {
                                        status = do_attr(lv,ts,ptr+4);
                                } else if (strncmp(ptr,"APPEND",6)==0) {
                                        status = do_append(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"AQUIRE",6)==0) {
                                        status = do_aquire(lv,ts,ptr+6);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'C':
                                if (strncmp(ptr,"CREATE",6)==0) {
                                        status = do_create(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"CUSTOMER",8)==0) {      // deprecated
                                        status = do_session(lv,ts,ptr+8);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'E':
                                if (strncmp(ptr,"EMPTYTRASH",10)==0) {
                                        status = do_emptytrash(lv,ts,ptr+10);
                                } else if (strncmp(ptr,"EMPTYRESERVED",13)==0) {
                                        status = do_emptyreserved(lv,ts,ptr+13);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'F':
                                if (strncmp(ptr,"FREEINODES",10)==0) {
                                        status = do_freeinodes(lv,ts,ptr+10);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'I':
                                if (strncmp(ptr,"INCVERSION",10)==0) {
                                        status = do_incversion(lv,ts,ptr+10);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'L':
                                if (strncmp(ptr,"LENGTH",6)==0) {
                                        status = do_length(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"LINK",4)==0) {
                                        status = do_link(lv,ts,ptr+4);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'M':
                                if (strncmp(ptr,"MOVE",4)==0) {
                                        status = do_move(lv,ts,ptr+4);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'P':
                                if (strncmp(ptr,"PURGE",5)==0) {
                                        status = do_purge(lv,ts,ptr+5);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'R':
                                if (strncmp(ptr,"RELEASE",7)==0) {
                                        status = do_release(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"REPAIR",6)==0) {
                                        status = do_repair(lv,ts,ptr+6);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'S':
                                if (strncmp(ptr,"SETEATTR",8)==0) {
                                        status = do_seteattr(lv,ts,ptr+8);
                                } else if (strncmp(ptr,"SETGOAL",7)==0) {
                                        status = do_setgoal(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"SETPATH",7)==0) {
                                        status = do_setpath(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"SETTRASHTIME",12)==0) {
                                        status = do_settrashtime(lv,ts,ptr+12);
                                } else if (strncmp(ptr,"SNAPSHOT",8)==0) {
                                        status = do_snapshot(lv,ts,ptr+8);
                                } else if (strncmp(ptr,"SYMLINK",7)==0) {
                                        status = do_symlink(lv,ts,ptr+7);
                                } else if (strncmp(ptr,"SESSION",7)==0) {
                                        status = do_session(lv,ts,ptr+7);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'T':
                                if (strncmp(ptr,"TRUNC",5)==0) {
                                        status = do_trunc(lv,ts,ptr+5);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'U':
                                if (strncmp(ptr,"UNLINK",6)==0) {
                                        status = do_unlink(lv,ts,ptr+6);
                                } else if (strncmp(ptr,"UNDEL",5)==0) {
                                        status = do_undel(lv,ts,ptr+5);
                                } else if (strncmp(ptr,"UNLOCK",6)==0) {
                                        status = do_unlock(lv,ts,ptr+6);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        case 'W':
                                if (strncmp(ptr,"WRITE",5)==0) {
                                        status = do_write(lv,ts,ptr+5);
                                } else {
                                        MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                                }
                                break;
                        default:
                                MFSLOG(LOG_NOTICE,"%"PRIu64": unknown entry '%s'",lv,ptr);
                        }
			    /**
			      *  let the restore continue if we missed some meta data, otherwise the 
			      *
			      * Dongyang Zhang
			      */
                        if (status!=STATUS_OK) {
                                MFSLOG(LOG_ERR,"%"PRIu64": error: %"PRIu8" (%s)",lv,status,errormsgs[status]);
                                return 1;
                        }
                        v = shadow_fs_getversion();
                        if (lv+1!=v) {
                                MFSLOG(LOG_ERR,"%"PRIu64": version mismatch",lv);
                                return 1;
                        }
                }
        }
        fclose(fd);
        MFSLOG(LOG_NOTICE,"version after applying changelog: %"PRIu64"",v);
        return 0;
}
Beispiel #5
0
void client_read(client *cl)
{
  int status, pn;

  status = mr_cont_receive(cl->con, &cl->req);
  if (status == -1)
    return;
  else if (status != MR_SUCCESS)
    {
      cl->state = CL_CLOSING;
      if (status != MR_NOT_CONNECTED)
	com_err(whoami, status, "while reading from socket");
      return;
    }

  pn = cl->req.u.mr_procno;
  if (pn < 0 || pn > MR_MAX_PROC)
    {
      com_err(whoami, 0, "procno out of range");
      client_reply(cl, MR_UNKNOWN_PROC);
      goto out;
    }
  log_args(procnames[pn], 2, cl->req.mr_argc, cl->req.mr_argv);

  if (dormant == ASLEEP && pn != MR_NOOP && pn != MR_MOTD)
    {
      client_reply(cl, MR_DOWN);
      com_err(whoami, MR_DOWN, "(query refused)");
      goto out;
    }

  /* make sure this gets cleared before every operation */
  dbms_errno = 0;

  switch (pn)
    {
    case MR_NOOP:
      client_reply(cl, MR_SUCCESS);
      break;

    case MR_AUTH:
      do_auth(cl);
      break;

    case MR_QUERY:
      do_retr(cl);
      break;

    case MR_ACCESS:
      do_access(cl);
      break;

    case MR_SHUTDOWN:
      do_shutdown(cl);
      break;

    case MR_DO_UPDATE:
      client_reply(cl, MR_PERM);
      break;

    case MR_MOTD:
      get_motd(cl);
      break;

    case MR_PROXY:
      do_proxy(cl);
      break;

    case MR_SETVERSION:
      do_version(cl);
      break;

    case MR_KRB5_AUTH:
      do_krb5_auth(cl);
      break;

    }

out:
  mr_destroy_reply(cl->req);
  memset(&cl->req, 0, sizeof(mr_params));
}