<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  Class to read the file coming from DCS containing the information        //
//  from LHC. Everything is stored in a TMap, where:                         //
//  Key   --> DP name, as passed by LHC                                      //
//  value --> TObjArray of AliDCSArray objects                               //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <Riostream.h>
#include <time.h>

#include <TObjArray.h>
#include <TObjString.h>
#include <TObject.h>
#include <TString.h>
#include <TMap.h>
#include <TSystem.h>
#include <TError.h>

#include "AliDCSArray.h"
#include "AliLHCReader.h"
#include "AliLog.h"

//--------------------------------------------------------------------------
AliLHCReader::AliLHCReader():
	TObject(),
	fStartTime(0),
	fEndTime(0)
{
	// default ctor
}

//--------------------------------------------------------------------------
AliLHCReader::~AliLHCReader()
{
	//
	// dtor
	//
}

//--------------------------------------------------------------------------
TMap* AliLHCReader::ReadLHCDP(TString filename)
{
	//
	// reading the file with the inputs
	//

       	if( gSystem->AccessPathName( filename.Data() ) ) {
		AliError(Form( "file (%s) not found", filename.Data() ) );
		return NULL;
	}

	ifstream *file = new ifstream ( filename.Data() );
	if (!*file) {
		AliError(Form("Error opening file (%s) !",filename.Data()));
		file->close();
		delete file;
		return NULL;
	}
	TMap* mapLHC = new TMap();
	//	mapLHC->SetOwner(1);
	TString strLine;
	Int_t lhcEntries;
	Int_t nBlocks = 0;
	//	TObjArray** array;
	Int_t nline =0;
	while(strLine.ReadLine(*file)){
		nline++;
		AliDebug(3,Form("line n. = %d",nline));
		// tokenize the line with tabs
		//if (strLine.BeginsWith("=")) continue;
		//if (!strLine.CompareTo("END_OF_BLOCK")) {
		if (strLine.Contains("END_OF_BLOCK")) {
			AliInfo("END_OF_BLOCK");
			nBlocks++;
			continue;
		}
		TObjArray* tokens = strLine.Tokenize("\t");
		Int_t ntokens = tokens->GetEntriesFast();
		AliDebug(3,Form("Number of tokens = %d",ntokens));
		if (ntokens == 2 && !(((TObjString*)tokens->At(0))->String()).CompareTo("LHC_ENTRIES")){
			lhcEntries = (((TObjString*)tokens->At(1))->String()).Atoi();
			AliInfo(Form("LHC entries = %d",lhcEntries));
			AliDebug(3,Form("LHC entries = %d",lhcEntries));
			continue;
		}
		if (ntokens == 1 && !(((TObjString*)tokens->At(0))->String()).CompareTo("END_OF_DATA")){
			AliInfo("End of file reached");
			break;
		}
		if (ntokens < 4){
			AliInfo(Form("Wrong number of tokens --> # tokens = %d at line %d",ntokens,nline));
			// requiring at least the index of the DP, the DP name, the format, and the number of entries
			delete tokens;
			continue;
		}
		Int_t lhcDPindex = (((TObjString*)tokens->At(0))->String()).Atoi();
		AliDebug(2,Form("lhcDPindex = %d",lhcDPindex));
		TObjString* lhcDPname = (TObjString*)tokens->At(1);
		TString lhcDPtype = ((TObjString*)tokens->At(2))->String();
		AliInfo(Form("lhcDPname = %s",(lhcDPname->String()).Data()));
		AliDebug(2,Form("lhcDPtype = %s",lhcDPtype.Data()));
		TObjArray* typeTokens = lhcDPtype.Tokenize(":");
		if (typeTokens->GetEntriesFast() < 2 ){
			// requiring the the type and the number of elements for each measurement
			AliError(Form("The format does not match the expected one, skipping the current line for DP = %s", lhcDPtype.Data()));
			delete typeTokens;
			continue;
		}
		TString type = ((TObjString*)typeTokens->At(0))->String();
		AliDebug(2,Form("type = %s",type.Data()));
      		Int_t nelements = (((TObjString*)typeTokens->At(1))->String()).Atoi();
		AliDebug(2,Form("nelements = %i",nelements));
		Int_t nentries = (((TObjString*)tokens->At(3))->String()).Atoi();
		AliDebug(2,Form("nentries = %i",nentries));
		Int_t nValuesPerEntry = nelements+1;
		Int_t nfixed = 4; // n. of fixed entries
		TObjArray* array;
		if (mapLHC->GetValue(lhcDPname)==0x0){
			array = new TObjArray();
			array->SetOwner(1);
		}
		else{
			TPair* p = mapLHC->RemoveEntry(lhcDPname);
			array = (TObjArray*)p->Value();
			AliDebug(2,Form("entry found! --> %p",array));
		}

		for (Int_t ientry=0; ientry< nentries; ientry ++){
			Int_t indextime = nfixed+nValuesPerEntry*ientry+nelements;
			TString strTimestamp = ((TObjString*)tokens->At(indextime))->String();
			//			TObjArray* timeTokens = strTimestamp.Tokenize(".");
			//if (timeTokens->GetEntriesFast() < 2 ){
			//	// requiring both the seconds and the nseconds for the timestamp
			//		AliError(Form("The timestamp format does not match the expected one, skipping entry %d for DP = %s", ientry, lhcDPtype.Data()));
			//	continue;
			//}
			//time_t seconds = time_t((((TObjString*)timeTokens->At(0))->String()).Atoi());
			//Int_t nseconds = Int_t((((TObjString*)timeTokens->At(1))->String()).Atoi());
			//TTimeStamp* timestamp = new TTimeStamp(seconds, (Int_t)(nseconds*1E8));
			Double_t timestamp = strTimestamp.Atof();
			AliDebug(2,Form("Timestamp in unix time = %f (s)",timestamp));
			if (fStartTime!=0 && fEndTime!=0 && (fStartTime > timestamp || fEndTime < timestamp)){
				// error in case the measurement is not within the data taking time interval
				AliError(Form("Timestamp for entry %d of DP %s not in [%d,%d]", ientry, lhcDPtype.Data(),fStartTime,fEndTime));
				continue;
			}
			if (type == "i"){
				Int_t* value = new Int_t[nelements];
				for (Int_t ielement=0; ielement<nelements; ielement++){
					value[ielement] = (((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String()).Atoi();
					AliDebug(2,Form("Value at index %d = %d",nfixed+ielement+ientry*nValuesPerEntry,value[ielement]));
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else if (type == "b"){
				Bool_t* value = new Bool_t[nelements];
				for (Int_t ielement=0; ielement<nelements; ielement++){
					value[ielement] = Bool_t((((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String()).Atoi());
					AliDebug(2,Form("Value at index %d = %d",nfixed+ielement+ientry*nValuesPerEntry,Int_t(value[ielement])));
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else if (type == "f"){ // the floats should be considered as doubles
				Double_t* value = new Double_t[nelements];
				for (Int_t ielement=0; ielement<nelements; ielement++){
					TString tempstr = (TString)(((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String());
					value[ielement] = (((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String()).Atof();
					AliDebug(2,Form("Value at index %d = %f from string %s",nfixed+ielement+ientry*nValuesPerEntry,value[ielement],tempstr.Data()));
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else if (type == "s"){
				TObjArray* value = new TObjArray();
				for (Int_t ielement=0; ielement<nelements; ielement++){
					TObjString* strobj = ((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry));
					AliDebug(2,Form("Value at index %d = %s",nfixed+ielement+ientry*nValuesPerEntry,(strobj->String()).Data()));
					value->Add(strobj);
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else{
				AliError(Form("Non-expected type %s",type.Data()));
				return NULL;
			}
		}
		mapLHC->Add(lhcDPname,array);
	}
	//mapLHC->Print();
	return mapLHC;
}

<commit_msg>Changing AliInfo in AliDebug.<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

///////////////////////////////////////////////////////////////////////////////
//                                                                           //
//  Class to read the file coming from DCS containing the information        //
//  from LHC. Everything is stored in a TMap, where:                         //
//  Key   --> DP name, as passed by LHC                                      //
//  value --> TObjArray of AliDCSArray objects                               //
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <Riostream.h>
#include <time.h>

#include <TObjArray.h>
#include <TObjString.h>
#include <TObject.h>
#include <TString.h>
#include <TMap.h>
#include <TSystem.h>
#include <TError.h>

#include "AliDCSArray.h"
#include "AliLHCReader.h"
#include "AliLog.h"

//--------------------------------------------------------------------------
AliLHCReader::AliLHCReader():
	TObject(),
	fStartTime(0),
	fEndTime(0)
{
	// default ctor
}

//--------------------------------------------------------------------------
AliLHCReader::~AliLHCReader()
{
	//
	// dtor
	//
}

//--------------------------------------------------------------------------
TMap* AliLHCReader::ReadLHCDP(TString filename)
{
	//
	// reading the file with the inputs
	//

       	if( gSystem->AccessPathName( filename.Data() ) ) {
		AliError(Form( "file (%s) not found", filename.Data() ) );
		return NULL;
	}

	ifstream *file = new ifstream ( filename.Data() );
	if (!*file) {
		AliError(Form("Error opening file (%s) !",filename.Data()));
		file->close();
		delete file;
		return NULL;
	}
	TMap* mapLHC = new TMap();
	//	mapLHC->SetOwner(1);
	TString strLine;
	Int_t lhcEntries;
	Int_t nBlocks = 0;
	//	TObjArray** array;
	Int_t nline =0;
	while(strLine.ReadLine(*file)){
		nline++;
		AliDebug(3,Form("line n. = %d",nline));
		// tokenize the line with tabs
		//if (strLine.BeginsWith("=")) continue;
		//if (!strLine.CompareTo("END_OF_BLOCK")) {
		if (strLine.Contains("END_OF_BLOCK")) {
			AliDebug(2,"END_OF_BLOCK");
			nBlocks++;
			continue;
		}
		TObjArray* tokens = strLine.Tokenize("\t");
		Int_t ntokens = tokens->GetEntriesFast();
		AliDebug(3,Form("Number of tokens = %d",ntokens));
		if (ntokens == 2 && !(((TObjString*)tokens->At(0))->String()).CompareTo("LHC_ENTRIES")){
			lhcEntries = (((TObjString*)tokens->At(1))->String()).Atoi();
			AliInfo(Form("LHC entries = %d",lhcEntries));
			AliDebug(3,Form("LHC entries = %d",lhcEntries));
			continue;
		}
		if (ntokens == 1 && !(((TObjString*)tokens->At(0))->String()).CompareTo("END_OF_DATA")){
			AliDebug(2,"End of file reached");
			break;
		}
		if (ntokens < 4){
			AliInfo(Form("Wrong number of tokens --> # tokens = %d at line %d",ntokens,nline));
			// requiring at least the index of the DP, the DP name, the format, and the number of entries
			delete tokens;
			continue;
		}
		Int_t lhcDPindex = (((TObjString*)tokens->At(0))->String()).Atoi();
		AliDebug(2,Form("lhcDPindex = %d",lhcDPindex));
		TObjString* lhcDPname = (TObjString*)tokens->At(1);
		TString lhcDPtype = ((TObjString*)tokens->At(2))->String();
		AliDebug(2,Form("lhcDPname = %s",(lhcDPname->String()).Data()));
		AliDebug(2,Form("lhcDPtype = %s",lhcDPtype.Data()));
		TObjArray* typeTokens = lhcDPtype.Tokenize(":");
		if (typeTokens->GetEntriesFast() < 2 ){
			// requiring the the type and the number of elements for each measurement
			AliError(Form("The format does not match the expected one, skipping the current line for DP = %s", lhcDPtype.Data()));
			delete typeTokens;
			continue;
		}
		TString type = ((TObjString*)typeTokens->At(0))->String();
		AliDebug(2,Form("type = %s",type.Data()));
      		Int_t nelements = (((TObjString*)typeTokens->At(1))->String()).Atoi();
		AliDebug(2,Form("nelements = %i",nelements));
		Int_t nentries = (((TObjString*)tokens->At(3))->String()).Atoi();
		AliDebug(2,Form("nentries = %i",nentries));
		Int_t nValuesPerEntry = nelements+1;
		Int_t nfixed = 4; // n. of fixed entries
		TObjArray* array;
		if (mapLHC->GetValue(lhcDPname)==0x0){
			array = new TObjArray();
			array->SetOwner(1);
		}
		else{
			TPair* p = mapLHC->RemoveEntry(lhcDPname);
			array = (TObjArray*)p->Value();
			AliDebug(2,Form("entry found! --> %p",array));
		}

		for (Int_t ientry=0; ientry< nentries; ientry ++){
			Int_t indextime = nfixed+nValuesPerEntry*ientry+nelements;
			TString strTimestamp = ((TObjString*)tokens->At(indextime))->String();
			//			TObjArray* timeTokens = strTimestamp.Tokenize(".");
			//if (timeTokens->GetEntriesFast() < 2 ){
			//	// requiring both the seconds and the nseconds for the timestamp
			//		AliError(Form("The timestamp format does not match the expected one, skipping entry %d for DP = %s", ientry, lhcDPtype.Data()));
			//	continue;
			//}
			//time_t seconds = time_t((((TObjString*)timeTokens->At(0))->String()).Atoi());
			//Int_t nseconds = Int_t((((TObjString*)timeTokens->At(1))->String()).Atoi());
			//TTimeStamp* timestamp = new TTimeStamp(seconds, (Int_t)(nseconds*1E8));
			Double_t timestamp = strTimestamp.Atof();
			AliDebug(2,Form("Timestamp in unix time = %f (s)",timestamp));
			if (fStartTime!=0 && fEndTime!=0 && (fStartTime > timestamp || fEndTime < timestamp)){
				// error in case the measurement is not within the data taking time interval
				AliError(Form("Timestamp for entry %d of DP %s not in [%d,%d]", ientry, lhcDPtype.Data(),fStartTime,fEndTime));
				continue;
			}
			if (type == "i"){
				Int_t* value = new Int_t[nelements];
				for (Int_t ielement=0; ielement<nelements; ielement++){
					value[ielement] = (((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String()).Atoi();
					AliDebug(2,Form("Value at index %d = %d",nfixed+ielement+ientry*nValuesPerEntry,value[ielement]));
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else if (type == "b"){
				Bool_t* value = new Bool_t[nelements];
				for (Int_t ielement=0; ielement<nelements; ielement++){
					value[ielement] = Bool_t((((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String()).Atoi());
					AliDebug(2,Form("Value at index %d = %d",nfixed+ielement+ientry*nValuesPerEntry,Int_t(value[ielement])));
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else if (type == "f"){ // the floats should be considered as doubles
				Double_t* value = new Double_t[nelements];
				for (Int_t ielement=0; ielement<nelements; ielement++){
					TString tempstr = (TString)(((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String());
					value[ielement] = (((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry))->String()).Atof();
					AliDebug(2,Form("Value at index %d = %f from string %s",nfixed+ielement+ientry*nValuesPerEntry,value[ielement],tempstr.Data()));
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else if (type == "s"){
				TObjArray* value = new TObjArray();
				for (Int_t ielement=0; ielement<nelements; ielement++){
					TObjString* strobj = ((TObjString*)tokens->At(nfixed+ielement+ientry*nValuesPerEntry));
					AliDebug(2,Form("Value at index %d = %s",nfixed+ielement+ientry*nValuesPerEntry,(strobj->String()).Data()));
					value->Add(strobj);
				}
				AliDCSArray* dcs = new AliDCSArray(nelements,value,timestamp);
				array->Add(dcs);
			}
			else{
				AliError(Form("Non-expected type %s",type.Data()));
				return NULL;
			}
		}
		mapLHC->Add(lhcDPname,array);
	}
	//mapLHC->Print();
	return mapLHC;
}

<|endoftext|>


<commit_before>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GPL.
 *
 */

/*
    FUSE: Filesystem in Userspace
    Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>

    This program can be distributed under the terms of the GNU GPL.
    See the file COPYING.
*/

// fuse crap
#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif

#define FUSE_USE_VERSION 26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statvfs.h>

// ceph stuff
#include "include/types.h"

#include "Client.h"

#include "config.h"

// globals
static Client *client;     // the ceph client

// ------
// fuse hooks

static int ceph_getattr(const char *path, struct stat *stbuf)
{
  return client->lstat(path, stbuf);
}

static int ceph_readlink(const char *path, char *buf, size_t size)
{
  int res;

  res = client->readlink(path, buf, size - 1);
  if (res < 0) return res;

  buf[res] = '\0';
  return 0;
}

static int ceph_mknod(const char *path, mode_t mode, dev_t rdev)
{
  return client->mknod(path, mode);
}

static int ceph_mkdir(const char *path, mode_t mode)
{
  return client->mkdir(path, mode);
}

static int ceph_unlink(const char *path)
{
  return client->unlink(path);
}

static int ceph_rmdir(const char *path)
{
  return client->rmdir(path);
}

static int ceph_symlink(const char *from, const char *to)
{
  return client->symlink(from, to);
}

static int ceph_rename(const char *from, const char *to)
{
  return client->rename(from, to);
}

static int ceph_link(const char *from, const char *to)
{
  return client->link(from, to);
}

static int ceph_chmod(const char *path, mode_t mode)
{
  return client->chmod(path, mode);
}

static int ceph_chown(const char *path, uid_t uid, gid_t gid)
{
  return client->chown(path, uid, gid);
}

static int ceph_truncate(const char *path, off_t size)
{
  return client->truncate(path, size);
}

static int ceph_utime(const char *path, struct utimbuf *buf)
{
  return client->utime(path, buf);
}

// ------------------
// file i/o

static int ceph_open(const char *path, struct fuse_file_info *fi)
{
  int res;

  res = client->open(path, fi->flags, 0);
  if (res < 0) return res;
  fi->fh = res;
  return 0;  // fuse wants 0 onsucess
}

static int ceph_read(const char *path, char *buf, size_t size, off_t offset,
                     struct fuse_file_info *fi)
{
  int fd = fi->fh;
  return client->read(fd, buf, size, offset);
}

static int ceph_write(const char *path, const char *buf, size_t size,
                     off_t offset, struct fuse_file_info *fi)
{
  int fd = fi->fh;
  return client->write(fd, buf, size, offset);
}

static int ceph_flush(const char *path, struct fuse_file_info *fi)
{
  //int fh = fi->fh;
  //return client->flush(fh);
  return 0;
}

static int ceph_statfs(const char *path, struct statvfs *stbuf)
{
  return client->statfs(path, stbuf);
}

static int ceph_release(const char *path, struct fuse_file_info *fi)
{
  int fd = fi->fh;
  int r = client->close(fd);  // close the file
  return r;
}

static int ceph_fsync(const char *path, int isdatasync,
                     struct fuse_file_info *fi)
{
  int fd = fi->fh;
  return client->fsync(fd, isdatasync ? true:false);
}

// ---------------------
// directory i/o

static int ceph_opendir(const char *path, struct fuse_file_info *fi)
{
  DIR *dirp;
  int r = client->opendir(path, &dirp);
  if (r < 0) return r;
  fi->fh = (uint64_t)(void*)dirp;
  return 0;
}

static int ceph_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t off, fuse_file_info *fi)
{
  DIR *dirp = (DIR*)fi->fh;

  client->seekdir(dirp, off);

  int res = 0;
  struct dirent de;
  struct stat st;
  int stmask = 0;
  while (res == 0) {
    int r = client->readdirplus_r(dirp, &de, &st, &stmask);
    if (r != 0) break;
    int stneed = CEPH_STAT_CAP_TYPE;
    res = filler(buf,
                 de.d_name,
		 ((stmask & stneed) == stneed) ? &st:0,
		 client->telldir(dirp));
  }
  return 0;
}

static int ceph_releasedir(const char *path, struct fuse_file_info *fi)
{
  DIR *dirp = (DIR*)fi->fh;
  int r = client->closedir(dirp);  // close the file
  return r;
}

const static struct fuse_operations ceph_oper = {
  getattr: ceph_getattr,
  readlink: ceph_readlink,
  getdir: 0,
  mknod: ceph_mknod,
  mkdir: ceph_mkdir,
  unlink: ceph_unlink,
  rmdir: ceph_rmdir,
  symlink: ceph_symlink,
  rename: ceph_rename,
  link: ceph_link,
  chmod: ceph_chmod,
  chown: ceph_chown,
  truncate: ceph_truncate,
  utime: ceph_utime,
  open: ceph_open,
  read: ceph_read,
  write: ceph_write,
  statfs: ceph_statfs,
  flush: ceph_flush,
  release: ceph_release,
  fsync: ceph_fsync,
  setxattr: 0,
  getxattr: 0,
  listxattr: 0,
  removexattr: 0,
  opendir: ceph_opendir,
  readdir: ceph_readdir,
  releasedir: ceph_releasedir,
  fsyncdir : 0,
  init : 0,
  destroy : 0,
  access : 0,
  create : 0,
  ftruncate : 0,
  fgetattr : 0,
  lock : 0,
  utimens : 0,
  bmap : 0,
  flag_nullpath_ok : 0,
  flag_reserved : 0,
  ioctl : 0,
  poll : 0,
};

int ceph_fuse_main(Client *c, int argc, const char *argv[])
{
  // init client
  client = c;

  // set up fuse argc/argv
  int newargc = 0;
  const char **newargv = (const char **) malloc((argc + 10) * sizeof(char *));
  newargv[newargc++] = argv[0];

  // allow other (all!) users to see my file system
  // NOTE: echo user_allow_other >> /etc/fuse.conf
  // NB: seems broken on Darwin
#ifndef DARWIN
  newargv[newargc++] = "-o";
  newargv[newargc++] = "allow_other";
#endif // DARWIN

  // use inos
  newargv[newargc++] = "-o";
  newargv[newargc++] = "use_ino";

  // large reads, direct_io (no kernel cachine)
  //newargv[newargc++] = "-o";
  //newargv[newargc++] = "large_read";
  if (g_conf.fuse_direct_io) {
    newargv[newargc++] = "-o";
    newargv[newargc++] = "direct_io";
  }

  // disable stupid fuse unlink hiding thing
  newargv[newargc++] = "-o";
  newargv[newargc++] = "hard_remove";

  // force into foreground
  //   -> we can watch stdout this way!!
  newargv[newargc++] = "-f";

  // copy rest of cmdline (hopefully, the mount point!)
  for (int argctr = 1; argctr < argc; argctr++) newargv[newargc++] = argv[argctr];

  // go fuse go
  cout << "ok, calling fuse_main" << std::endl;
  int r = fuse_main(newargc, (char**)newargv, &ceph_oper, 0);
  return r;
}
<commit_msg>Revert "client/fuse.cc: explicity zero fuse function ptrs"<commit_after>// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
/*
 * Ceph - scalable distributed file system
 *
 * Copyright (C) 2004-2010 Sage Weil <sage@newdream.net>
 *
 * This is free software; you can redistribute it and/or
 * modify it under the terms of the GPL.
 *
 */

/*
    FUSE: Filesystem in Userspace
    Copyright (C) 2001-2005  Miklos Szeredi <miklos@szeredi.hu>

    This program can be distributed under the terms of the GNU GPL.
    See the file COPYING.
*/

// fuse crap
#ifdef linux
/* For pread()/pwrite() */
#define _XOPEN_SOURCE 500
#endif

#define FUSE_USE_VERSION 26

#include <fuse.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <dirent.h>
#include <errno.h>
#include <sys/statvfs.h>

// ceph stuff
#include "include/types.h"

#include "Client.h"

#include "config.h"

// globals
static Client *client;     // the ceph client

// ------
// fuse hooks

static int ceph_getattr(const char *path, struct stat *stbuf)
{
  return client->lstat(path, stbuf);
}

static int ceph_readlink(const char *path, char *buf, size_t size)
{
  int res;

  res = client->readlink(path, buf, size - 1);
  if (res < 0) return res;

  buf[res] = '\0';
  return 0;
}

static int ceph_mknod(const char *path, mode_t mode, dev_t rdev)
{
  return client->mknod(path, mode);
}

static int ceph_mkdir(const char *path, mode_t mode)
{
  return client->mkdir(path, mode);
}

static int ceph_unlink(const char *path)
{
  return client->unlink(path);
}

static int ceph_rmdir(const char *path)
{
  return client->rmdir(path);
}

static int ceph_symlink(const char *from, const char *to)
{
  return client->symlink(from, to);
}

static int ceph_rename(const char *from, const char *to)
{
  return client->rename(from, to);
}

static int ceph_link(const char *from, const char *to)
{
  return client->link(from, to);
}

static int ceph_chmod(const char *path, mode_t mode)
{
  return client->chmod(path, mode);
}

static int ceph_chown(const char *path, uid_t uid, gid_t gid)
{
  return client->chown(path, uid, gid);
}

static int ceph_truncate(const char *path, off_t size)
{
  return client->truncate(path, size);
}

static int ceph_utime(const char *path, struct utimbuf *buf)
{
  return client->utime(path, buf);
}

// ------------------
// file i/o

static int ceph_open(const char *path, struct fuse_file_info *fi)
{
  int res;

  res = client->open(path, fi->flags, 0);
  if (res < 0) return res;
  fi->fh = res;
  return 0;  // fuse wants 0 onsucess
}

static int ceph_read(const char *path, char *buf, size_t size, off_t offset,
                     struct fuse_file_info *fi)
{
  int fd = fi->fh;
  return client->read(fd, buf, size, offset);
}

static int ceph_write(const char *path, const char *buf, size_t size,
                     off_t offset, struct fuse_file_info *fi)
{
  int fd = fi->fh;
  return client->write(fd, buf, size, offset);
}

static int ceph_flush(const char *path, struct fuse_file_info *fi)
{
  //int fh = fi->fh;
  //return client->flush(fh);
  return 0;
}

static int ceph_statfs(const char *path, struct statvfs *stbuf)
{
  return client->statfs(path, stbuf);
}

static int ceph_release(const char *path, struct fuse_file_info *fi)
{
  int fd = fi->fh;
  int r = client->close(fd);  // close the file
  return r;
}

static int ceph_fsync(const char *path, int isdatasync,
                     struct fuse_file_info *fi)
{
  int fd = fi->fh;
  return client->fsync(fd, isdatasync ? true:false);
}

// ---------------------
// directory i/o

static int ceph_opendir(const char *path, struct fuse_file_info *fi)
{
  DIR *dirp;
  int r = client->opendir(path, &dirp);
  if (r < 0) return r;
  fi->fh = (uint64_t)(void*)dirp;
  return 0;
}

static int ceph_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t off, fuse_file_info *fi)
{
  DIR *dirp = (DIR*)fi->fh;

  client->seekdir(dirp, off);

  int res = 0;
  struct dirent de;
  struct stat st;
  int stmask = 0;
  while (res == 0) {
    int r = client->readdirplus_r(dirp, &de, &st, &stmask);
    if (r != 0) break;
    int stneed = CEPH_STAT_CAP_TYPE;
    res = filler(buf,
                 de.d_name,
		 ((stmask & stneed) == stneed) ? &st:0,
		 client->telldir(dirp));
  }
  return 0;
}

static int ceph_releasedir(const char *path, struct fuse_file_info *fi)
{
  DIR *dirp = (DIR*)fi->fh;
  int r = client->closedir(dirp);  // close the file
  return r;
}

const static struct fuse_operations ceph_oper = {
  getattr: ceph_getattr,
  readlink: ceph_readlink,
  getdir: 0,
  mknod: ceph_mknod,
  mkdir: ceph_mkdir,
  unlink: ceph_unlink,
  rmdir: ceph_rmdir,
  symlink: ceph_symlink,
  rename: ceph_rename,
  link: ceph_link,
  chmod: ceph_chmod,
  chown: ceph_chown,
  truncate: ceph_truncate,
  utime: ceph_utime,
  open: ceph_open,
  read: ceph_read,
  write: ceph_write,
  statfs: ceph_statfs,
  flush: ceph_flush,
  release: ceph_release,
  fsync: ceph_fsync,
  setxattr: 0,
  getxattr: 0,
  listxattr: 0,
  removexattr: 0,
  opendir: ceph_opendir,
  readdir: ceph_readdir,
  releasedir: ceph_releasedir
};

int ceph_fuse_main(Client *c, int argc, const char *argv[])
{
  // init client
  client = c;

  // set up fuse argc/argv
  int newargc = 0;
  const char **newargv = (const char **) malloc((argc + 10) * sizeof(char *));
  newargv[newargc++] = argv[0];

  // allow other (all!) users to see my file system
  // NOTE: echo user_allow_other >> /etc/fuse.conf
  // NB: seems broken on Darwin
#ifndef DARWIN
  newargv[newargc++] = "-o";
  newargv[newargc++] = "allow_other";
#endif // DARWIN

  // use inos
  newargv[newargc++] = "-o";
  newargv[newargc++] = "use_ino";

  // large reads, direct_io (no kernel cachine)
  //newargv[newargc++] = "-o";
  //newargv[newargc++] = "large_read";
  if (g_conf.fuse_direct_io) {
    newargv[newargc++] = "-o";
    newargv[newargc++] = "direct_io";
  }

  // disable stupid fuse unlink hiding thing
  newargv[newargc++] = "-o";
  newargv[newargc++] = "hard_remove";

  // force into foreground
  //   -> we can watch stdout this way!!
  newargv[newargc++] = "-f";

  // copy rest of cmdline (hopefully, the mount point!)
  for (int argctr = 1; argctr < argc; argctr++) newargv[newargc++] = argv[argctr];

  // go fuse go
  cout << "ok, calling fuse_main" << std::endl;
  int r = fuse_main(newargc, (char**)newargv, &ceph_oper, 0);
  return r;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#ifdef _WIN32

#define WIN32_LEAN_AND_MEAN
#define STRICT
#define UNICODE
#include <winsock2.h>
#include <shellapi.h>
#include <shlwapi.h>

// UTF-16

#define PSTR(x) L ## x

typedef wchar_t pchar;
size_t pstrlen(const pchar* p) {
    return wcslen(p);
}
int pprintf(const pchar* format, ...) {
    va_list arg;
    va_start(arg, format);
    int result = vwprintf(format, arg);
    va_end(arg);
    return result;
}

#else

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef int SOCKET; // old-school
const SOCKET INVALID_SOCKET = -1;
const ssize_t SOCKET_ERROR = -1;

// UTF-8

#define PSTR(x) x
typedef char pchar;
size_t pstrlen(const pchar* p) {
    return strlen(p);
}
int pprintf(const pchar* format, ...) {
    va_list arg;
    va_start(arg, format);
    int result = vprintf(format, arg);
    va_end(arg);
    return result;
}

#endif

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <wchar.h>

// int(md5.md5('ibb').hexdigest()[-4:], 16)
const int IBB_PORT = 26830;

int error(const char* msg) {
    fprintf(stderr, "ibb *** error: %s\n", msg);
    return 1;
}

bool openServerConnection(SOCKET* s) {
    *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (*s == INVALID_SOCKET) {
        // TODO: print error code
        error("Failed to create socket");
        return false;
    }

    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(IBB_PORT);

    int result = connect(*s, reinterpret_cast<sockaddr*>(&address), sizeof(address));
    if (result) {
        return false;
    }

    return true;
}

#ifdef _WIN32

bool startServer() {
    WCHAR executable_path[MAX_PATH * 2];
    DWORD length = GetModuleFileNameW(GetModuleHandle(NULL), executable_path, MAX_PATH);
    if (length == 0 || length == MAX_PATH) {
        fprintf(stderr, "ibb *** failed to get executable path\n");
        return false;
    }

    wchar_t* last_slash = wcsrchr(executable_path, '\\');
    if (last_slash) {
        *last_slash = 0;
    } else {
        last_slash = executable_path;
    }
    wcsncpy(last_slash, L"\\ibb_server.exe", MAX_PATH);

    if (PathFileExists(executable_path)) {
        // Launch server executable directly.

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", executable_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    } else {
        // Launch server from Python.

        WCHAR python_path[MAX_PATH + 1] = {0};
        LONG size = sizeof(python_path);
        LONG success = RegQueryValueW(
            HKEY_LOCAL_MACHINE,
            L"SOFTWARE\\Python\\PythonCore\\3.1\\InstallPath",
            python_path,
            &size);
        if (!success) {
            // TODO: print error
            fprintf(stderr, "ibb *** failed to locate Python 3.1\n");
            return false;
        }

        // TODO: use safe strings
        wcsncat(python_path, L"\\python.exe", MAX_PATH);

        wcsncpy(last_slash, L"\\src\\ibb.py", MAX_PATH);

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", python_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    }
}

#else

// Mac
#include <mach-o/dyld.h>

bool startServer() {
    uint32_t pathSize = 0;
    // should return -1
    _NSGetExecutablePath(0, &pathSize);

    char executablePath[pathSize];
    if (0 != _NSGetExecutablePath(executablePath, &pathSize)) {
        fprintf(stderr, "ibb *** failed to get executable path");
        return false;
    }

    /*
    wchar_t* last_slash = wcsrchr(executable_path, '\\');
    if (last_slash) {
        *last_slash = 0;
    } else {
        last_slash = executable_path;
    }
    wcsncpy(last_slash, L"\\ibb_server.exe", MAX_PATH);

    if (PathFileExists(executable_path)) {
        // Launch server executable directly.

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", executable_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    } else {
        // Launch server from Python.

        WCHAR python_path[MAX_PATH + 1] = {0};
        LONG size = sizeof(python_path);
        LONG success = RegQueryValueW(
            HKEY_LOCAL_MACHINE,
            L"SOFTWARE\\Python\\PythonCore\\3.1\\InstallPath",
            python_path,
            &size);
        if (!success) {
            // TODO: print error
            fprintf(stderr, "ibb *** failed to locate Python 3.1\n");
            return false;
        }

        // TODO: use safe strings
        wcsncat(python_path, L"\\python.exe", MAX_PATH);

        wcsncpy(last_slash, L"\\src\\ibb.py", MAX_PATH);

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", python_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    }
    */
    return false;
}

#endif

void sendString(SOCKET connection, const pchar* begin, const pchar* end = 0) {
    if (!end) {
        end = begin + pstrlen(begin);
    }

    // UTF-16 over the wire on Windows
    // UTF-32 on Linux and Mac
    send(
        connection,
        reinterpret_cast<const char*>(begin),
        (end - begin) * sizeof(pchar),
        0);

    // TODO: error checking
}

struct ScopedFree {
    explicit ScopedFree(char* p)
        : p(p)
    {}

    ~ScopedFree() {
        free(p);
    }

private:
    char* p;
};

bool sendBuild(SOCKET connection, int argc, const pchar* argv[], clock_t start) {
    sendString(connection, PSTR("version: 1\n"));

    sendString(connection, PSTR("cwd: "));

    #ifdef _WIN32
    WCHAR current_directory[MAX_PATH] = {0};
    GetCurrentDirectoryW(MAX_PATH, current_directory);
    #else
    char* current_directory = getcwd(0, 0);
    ScopedFree scoped_free(current_directory);
    #endif

    sendString(connection, current_directory);
    sendString(connection, PSTR("\n"));

    for (int i = 0; i < argc; ++i) {
        sendString(connection, PSTR("arg: "));
        sendString(connection, argv[i]);
        sendString(connection, PSTR("\n"));
    }

    sendString(connection, PSTR("build\n"));

    //printf("Build sent in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    for (;;) {
        const int BUFFER_LENGTH = 1024;
        pchar buffer[BUFFER_LENGTH + 1];
        const int bytes = recv(
            connection,
            reinterpret_cast<char*>(buffer),
            sizeof(pchar) * BUFFER_LENGTH,
            0);
        if (0 == bytes) {
            break;
        }
        if (SOCKET_ERROR == bytes) {
            error("Broken connection");
            break;
        }
        const int chars = bytes / sizeof(pchar); // TODO: handle odd bytes values
        buffer[chars] = 0;
        pprintf(PSTR("%s"), buffer); // %*s sometimes wrote extra crap at the end
    }

    //printf("Result recieved in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    return true;
}

int wmain(int argc, const wchar_t* argv[]) {
    clock_t start = clock();

    WSADATA wsadata;
    if (0 != WSAStartup(2, &wsadata)) {
        return error("Failed to initialize winsock");
    }

    struct cleanup_t {
        cleanup_t() {}
        ~cleanup_t() { WSACleanup(); }
    } cleanup;

    //printf("Started winsock in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    SOCKET connection;
    if (!openServerConnection(&connection)) {
        if (!startServer()) {
            return error("Failed to start server");
        }
        if (!openServerConnection(&connection)) {
            return error("Failed to connect to server");
        }
    }

    //printf("Opened connection in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    if (!sendBuild(connection, argc, argv, start)) {
        return error("Failed to submit build");
    }

    closesocket(connection);

    //printf("Socket closed in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);
    return 0;
}

// hack around mingw's lack of wmain support
int main() {
    int argc;
    WCHAR** argv = CommandLineToArgvW(
        GetCommandLineW(),
        &argc);
    return wmain(argc, const_cast<const wchar_t**>(argv));
}
<commit_msg>hey it builds<commit_after>#include <stdio.h>
#include <string.h>
#include <stdarg.h>

#ifdef _WIN32

#define WIN32_LEAN_AND_MEAN
#define STRICT
#define UNICODE
#include <winsock2.h>
#include <shellapi.h>
#include <shlwapi.h>

// UTF-16

#define PSTR(x) L ## x

typedef wchar_t pchar;
size_t pstrlen(const pchar* p) {
    return wcslen(p);
}
int pprintf(const pchar* format, ...) {
    va_list arg;
    va_start(arg, format);
    int result = vwprintf(format, arg);
    va_end(arg);
    return result;
}

#else

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
typedef int SOCKET; // old-school
const SOCKET INVALID_SOCKET = -1;
const ssize_t SOCKET_ERROR = -1;
int closesocket(SOCKET socket) {
    return close(socket);
}

// UTF-8

#define PSTR(x) x
typedef char pchar;
size_t pstrlen(const pchar* p) {
    return strlen(p);
}
int pprintf(const pchar* format, ...) {
    va_list arg;
    va_start(arg, format);
    int result = vprintf(format, arg);
    va_end(arg);
    return result;
}

#endif

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <wchar.h>

// int(md5.md5('ibb').hexdigest()[-4:], 16)
const int IBB_PORT = 26830;

int error(const char* msg) {
    fprintf(stderr, "ibb *** error: %s\n", msg);
    return 1;
}

bool openServerConnection(SOCKET* s) {
    *s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (*s == INVALID_SOCKET) {
        // TODO: print error code
        error("Failed to create socket");
        return false;
    }

    sockaddr_in address;
    address.sin_family = AF_INET;
    address.sin_addr.s_addr = inet_addr("127.0.0.1");
    address.sin_port = htons(IBB_PORT);

    int result = connect(*s, reinterpret_cast<sockaddr*>(&address), sizeof(address));
    if (result) {
        return false;
    }

    return true;
}

#ifdef _WIN32

bool startServer() {
    WCHAR executable_path[MAX_PATH * 2];
    DWORD length = GetModuleFileNameW(GetModuleHandle(NULL), executable_path, MAX_PATH);
    if (length == 0 || length == MAX_PATH) {
        fprintf(stderr, "ibb *** failed to get executable path\n");
        return false;
    }

    wchar_t* last_slash = wcsrchr(executable_path, '\\');
    if (last_slash) {
        *last_slash = 0;
    } else {
        last_slash = executable_path;
    }
    wcsncpy(last_slash, L"\\ibb_server.exe", MAX_PATH);

    if (PathFileExists(executable_path)) {
        // Launch server executable directly.

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", executable_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    } else {
        // Launch server from Python.

        WCHAR python_path[MAX_PATH + 1] = {0};
        LONG size = sizeof(python_path);
        LONG success = RegQueryValueW(
            HKEY_LOCAL_MACHINE,
            L"SOFTWARE\\Python\\PythonCore\\3.1\\InstallPath",
            python_path,
            &size);
        if (!success) {
            // TODO: print error
            fprintf(stderr, "ibb *** failed to locate Python 3.1\n");
            return false;
        }

        // TODO: use safe strings
        wcsncat(python_path, L"\\python.exe", MAX_PATH);

        wcsncpy(last_slash, L"\\src\\ibb.py", MAX_PATH);

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", python_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    }
}

#else

// Mac
#include <mach-o/dyld.h>

bool startServer() {
    uint32_t pathSize = 0;
    // should return -1
    _NSGetExecutablePath(0, &pathSize);

    char executablePath[pathSize];
    if (0 != _NSGetExecutablePath(executablePath, &pathSize)) {
        fprintf(stderr, "ibb *** failed to get executable path");
        return false;
    }

    /*
    wchar_t* last_slash = wcsrchr(executable_path, '\\');
    if (last_slash) {
        *last_slash = 0;
    } else {
        last_slash = executable_path;
    }
    wcsncpy(last_slash, L"\\ibb_server.exe", MAX_PATH);

    if (PathFileExists(executable_path)) {
        // Launch server executable directly.

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", executable_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    } else {
        // Launch server from Python.

        WCHAR python_path[MAX_PATH + 1] = {0};
        LONG size = sizeof(python_path);
        LONG success = RegQueryValueW(
            HKEY_LOCAL_MACHINE,
            L"SOFTWARE\\Python\\PythonCore\\3.1\\InstallPath",
            python_path,
            &size);
        if (!success) {
            // TODO: print error
            fprintf(stderr, "ibb *** failed to locate Python 3.1\n");
            return false;
        }

        // TODO: use safe strings
        wcsncat(python_path, L"\\python.exe", MAX_PATH);

        wcsncpy(last_slash, L"\\src\\ibb.py", MAX_PATH);

        // TODO: use CreateProcess instead of ShellExecute
        // TODO: print error code
        HINSTANCE result = ShellExecuteW(0, L"open", python_path, executable_path, NULL, SW_SHOW);
        return result > reinterpret_cast<HINSTANCE>(32);
    }
    */
    return false;
}

#endif

void sendString(SOCKET connection, const pchar* begin, const pchar* end = 0) {
    if (!end) {
        end = begin + pstrlen(begin);
    }

    // UTF-16 over the wire on Windows
    // UTF-32 on Linux and Mac
    send(
        connection,
        reinterpret_cast<const char*>(begin),
        (end - begin) * sizeof(pchar),
        0);

    // TODO: error checking
}

struct ScopedFree {
    explicit ScopedFree(char* p)
        : p(p)
    {}

    ~ScopedFree() {
        free(p);
    }

private:
    char* p;
};

bool sendBuild(SOCKET connection, int argc, const pchar* argv[], clock_t start) {
    sendString(connection, PSTR("version: 1\n"));

    sendString(connection, PSTR("cwd: "));

    #ifdef _WIN32
    WCHAR current_directory[MAX_PATH] = {0};
    GetCurrentDirectoryW(MAX_PATH, current_directory);
    #else
    char* current_directory = getcwd(0, 0);
    ScopedFree scoped_free(current_directory);
    #endif

    sendString(connection, current_directory);
    sendString(connection, PSTR("\n"));

    for (int i = 0; i < argc; ++i) {
        sendString(connection, PSTR("arg: "));
        sendString(connection, argv[i]);
        sendString(connection, PSTR("\n"));
    }

    sendString(connection, PSTR("build\n"));

    //printf("Build sent in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    for (;;) {
        const int BUFFER_LENGTH = 1024;
        pchar buffer[BUFFER_LENGTH + 1];
        const int bytes = recv(
            connection,
            reinterpret_cast<char*>(buffer),
            sizeof(pchar) * BUFFER_LENGTH,
            0);
        if (0 == bytes) {
            break;
        }
        if (SOCKET_ERROR == bytes) {
            error("Broken connection");
            break;
        }
        const int chars = bytes / sizeof(pchar); // TODO: handle odd bytes values
        buffer[chars] = 0;
        pprintf(PSTR("%s"), buffer); // %*s sometimes wrote extra crap at the end
    }

    //printf("Result recieved in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    return true;
}

int pmain(int argc, const pchar* argv[]) {
    clock_t start = clock();

#ifdef _WIN32
    WSADATA wsadata;
    if (0 != WSAStartup(2, &wsadata)) {
        return error("Failed to initialize winsock");
    }

    struct cleanup_t {
        cleanup_t() {}
        ~cleanup_t() { WSACleanup(); }
    } cleanup;
#endif

    //printf("Started winsock in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    SOCKET connection;
    if (!openServerConnection(&connection)) {
        if (!startServer()) {
            return error("Failed to start server");
        }
        if (!openServerConnection(&connection)) {
            return error("Failed to connect to server");
        }
    }

    //printf("Opened connection in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);

    if (!sendBuild(connection, argc, argv, start)) {
        return error("Failed to submit build");
    }

    closesocket(connection);

    //printf("Socket closed in %g seconds\n", float(clock() - start) / CLOCKS_PER_SEC);
    //fflush(stdout);
    return 0;
}

// hack around mingw's lack of wmain support
#ifdef _WIN32

int main() {
    int argc;
    WCHAR** argv = CommandLineToArgvW(
        GetCommandLineW(),
        &argc);
    return pmain(argc, const_cast<const wchar_t**>(argv));
}

#else

int main(int argc, const char* argv[]) {
    return pmain(argc, argv);
}

#endif
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
// SneezyMUD - All rights reserved, SneezyMUD Coding Team
//
//
//////////////////////////////////////////////////////////////////////////

#include "stdsneezy.h"
#include "cmd_trophy.h"

float trophy_exp_mod(float count)
{
  float min_mod=0.3;
  float max_mod=1.0; // shouldn't ever be above 1.0
  float free_kills=8; // how many kills you get before trophy kicks in
  float step_mod=0.5; // mod per step
  float num_steps=14.0; // number of steps

  float t1, t2, t3, t4, t5;

  t1=(double)(count-free_kills);
  t2=step_mod / num_steps;
  t3=t1*t2;
  t4=max_mod-t3;
  t5=(double)(max(t4*100, min_mod*100)/100);
  t5=(double)(min(t5*100, max_mod*100)/100);

  //  vlogf(LOG_PEEL, "%f %f %f %f %f", t1, t2, t3, t4, t5);

  return t5;
}

const char *describe_trophy_exp(float count)
{
  float f=trophy_exp_mod(count);

  return((f == 1.0) ? "<Y>full<1>" :
	 ((f >= 0.90) ? "<o>much<1>" :
	  ((f >= 0.80) ? "a fair amount" :
	   ((f >= 0.70) ? "<w>some<1>" : "<k>little<1>"))));
}

void TBeing::doTrophy(const char *arg)
{
  MYSQL_ROW row=NULL;
  MYSQL_RES *res;
  int rc, mcount=0, vnum, header=0, zcount=0, bottom=0, zcountt=0;
  int zonesearch=0, processrow=1;
  float count;
  char buf[256];
  string sb;
  unsigned int zone;

  if(!isPc()){
    sendTo("Mobs can't use this command!\n\r");
    return;
  }

  for (; isspace(*arg); arg++);

  if(!strncmp(arg, "zone", 4)){
    zonesearch=1;
    for (; !isspace(*arg); arg++);
  }

  rc=dbquery(&res, "sneezy", "doTrophy", "select mobvnum, count from trophy where name='%s' order by mobvnum", getName());

  for (zone = 0; zone < zone_table.size(); zone++) {
    zoneData &zd = zone_table[zone];

    while(1){
      if(processrow)
	row=mysql_fetch_row(res);

      if(!row)
	break;

      vlogf(LOG_PEEL, "mob=%i, top=%i", atoi(row[0]), zd.top);

      // sometimes we get an entry of 0 for med mobs I think
      vnum=atoi(row[0]);
      if(vnum==0){
	continue;
      }

      // this mob doesn't belong to this zone, so break out to the zone loop
      if(vnum>zd.top){
	processrow=0; // don't get the next row yet
	break;
      } else {
	processrow=1;
      }

      int rnum = real_mobile(atoi(row[0]));
      if (rnum < 0) {
	vlogf(LOG_BUG, "DoTrophy detected bad mobvnum=%d for name='%s'",
	      atoi(row[0]), getName());
	continue;
      }

      if(zonesearch){
	if(*arg && !isname(arg, zd.name))
	  continue;
      } else {
	if(*arg && !isname(arg, mob_index[rnum].name))
	  continue;
      }

      // print the zone header if we haven't already
      // we do it here, so we can prevent printing headers for empty zones
      if(!header){
	sprintf(buf, "\n--%s\n", zd.name);
	sb += buf;
	header=1;
      }

      count=atof(row[1]);
      sprintf(buf, "You will gain %s experience when fighting %s.\n\r",
	      describe_trophy_exp(count),
	      mob_index[rnum].short_desc);
      ++mcount;
      ++zcount;
      sb += buf;

      processrow=1; // ok to get the next row

#if 0
    sprintf(buf, "%3d %-38.38s %4dm %4dm %6d-%-6d %3d %.1f\n\r",
	    zone, buf2, zd.lifespan, zd.age, bottom, zd.top,
	    zd.zone_value,
	    (zd.num_mobs ? zd.mob_levels/zd.num_mobs : 0));
    sb += buf;
#endif
    }

    // we have some mobs for this zone, so do some tallies
    if(header){
      sprintf(buf, "Total mobs: %i\n\r", zcount);
      sb += buf;

      unsigned int objnx;
      for (objnx = 0; objnx < mob_index.size(); objnx++) {
	if(mob_index[objnx].virt >= bottom &&
	   mob_index[objnx].virt <= zd.top){
	  ++zcountt;
	}
      }

      sprintf(buf, "You have killed %1.2f%% of mobs in this zone.\n\r",((float)((float)zcount/(float)zcountt)*100.0));
      sb += buf;
    }

    header=zcount=zcountt=0;
    bottom=zd.top+1;
  }

  sprintf(buf, "\n--\nTotal mobs: %i\n\r", mcount);
  sb += buf;
  if(mcount>0){
    sprintf(buf, "You have killed %1.2f%% of all mobs.\n\r",((float)((float)mcount/(float)mob_index.size())*100.0));
    sb += buf;
  }

  if (desc)
    desc->page_string(sb.c_str(), SHOWNOW_NO, ALLOWREP_YES);

  mysql_free_result(res);

  return;
}

void wipeTrophy(const char *name){
  dbquery(NULL, "sneezy", "wipeTrophy", "delete from trophy where name='%s'", name);
}
<commit_msg>took out debugging logs and some excess code<commit_after>//////////////////////////////////////////////////////////////////////////
//
// SneezyMUD - All rights reserved, SneezyMUD Coding Team
//
//
//////////////////////////////////////////////////////////////////////////

#include "stdsneezy.h"
#include "cmd_trophy.h"

float trophy_exp_mod(float count)
{
  float min_mod=0.3;
  float max_mod=1.0; // shouldn't ever be above 1.0
  float free_kills=8; // how many kills you get before trophy kicks in
  float step_mod=0.5; // mod per step
  float num_steps=14.0; // number of steps

  float t1, t2, t3, t4, t5;

  t1=(double)(count-free_kills);
  t2=step_mod / num_steps;
  t3=t1*t2;
  t4=max_mod-t3;
  t5=(double)(max(t4*100, min_mod*100)/100);
  t5=(double)(min(t5*100, max_mod*100)/100);

  //  vlogf(LOG_PEEL, "%f %f %f %f %f", t1, t2, t3, t4, t5);

  return t5;
}

const char *describe_trophy_exp(float count)
{
  float f=trophy_exp_mod(count);

  return((f == 1.0) ? "<Y>full<1>" :
	 ((f >= 0.90) ? "<o>much<1>" :
	  ((f >= 0.80) ? "a fair amount" :
	   ((f >= 0.70) ? "<w>some<1>" : "<k>little<1>"))));
}

// this function is a little messy, I apologize
void TBeing::doTrophy(const char *arg)
{
  MYSQL_ROW row=NULL;
  MYSQL_RES *res;
  int rc, mcount=0, vnum, header=0, zcount=0, bottom=0, zcountt=0;
  int zonesearch=0, processrow=1;
  float count;
  char buf[256];
  string sb;
  unsigned int zone;

  if(!isPc()){
    sendTo("Mobs can't use this command!\n\r");
    return;
  }

  for (; isspace(*arg); arg++);

  if(!strncmp(arg, "zone", 4)){
    zonesearch=1;
    for (; !isspace(*arg); arg++);
  }

  rc=dbquery(&res, "sneezy", "doTrophy", "select mobvnum, count from trophy where name='%s' order by mobvnum", getName());

  for (zone = 0; zone < zone_table.size(); zone++) {
    zoneData &zd = zone_table[zone];

    while(1){
      if(processrow)
	row=mysql_fetch_row(res);

      if(!row)
	break;

      // sometimes we get an entry of 0 for med mobs I think
      vnum=atoi(row[0]);
      if(vnum==0){
	continue;
      }

      // this mob doesn't belong to this zone, so break out to the zone loop
      if(vnum>zd.top){
	processrow=0; // don't get the next row yet
	break;
      } else {
	processrow=1;
      }

      int rnum = real_mobile(atoi(row[0]));
      if (rnum < 0) {
	vlogf(LOG_BUG, "DoTrophy detected bad mobvnum=%d for name='%s'",
	      atoi(row[0]), getName());
	continue;
      }

      if(zonesearch){
	if(*arg && !isname(arg, zd.name))
	  continue;
      } else {
	if(*arg && !isname(arg, mob_index[rnum].name))
	  continue;
      }

      // print the zone header if we haven't already
      // we do it here, so we can prevent printing headers for empty zones
      if(!header){
	sprintf(buf, "\n--%s\n", zd.name);
	sb += buf;
	header=1;
      }

      count=atof(row[1]);
      sprintf(buf, "You will gain %s experience when fighting %s.\n\r",
	      describe_trophy_exp(count),
	      mob_index[rnum].short_desc);
      ++mcount;
      ++zcount;
      sb += buf;

      processrow=1; // ok to get the next row
    }

    // we have some mobs for this zone, so do some tallies
    if(header){
      sprintf(buf, "Total mobs: %i\n\r", zcount);
      sb += buf;

      unsigned int objnx;
      for (objnx = 0; objnx < mob_index.size(); objnx++) {
	if(mob_index[objnx].virt >= bottom &&
	   mob_index[objnx].virt <= zd.top){
	  ++zcountt;
	}
      }

      sprintf(buf, "You have killed %1.2f%% of mobs in this zone.\n\r",((float)((float)zcount/(float)zcountt)*100.0));
      sb += buf;
    }

    header=zcount=zcountt=0;
    bottom=zd.top+1;
  }

  sprintf(buf, "\n--\nTotal mobs: %i\n\r", mcount);
  sb += buf;
  if(mcount>0){
    sprintf(buf, "You have killed %1.2f%% of all mobs.\n\r",((float)((float)mcount/(float)mob_index.size())*100.0));
    sb += buf;
  }

  if (desc)
    desc->page_string(sb.c_str(), SHOWNOW_NO, ALLOWREP_YES);

  mysql_free_result(res);

  return;
}

void wipeTrophy(const char *name){
  dbquery(NULL, "sneezy", "wipeTrophy", "delete from trophy where name='%s'", name);
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "SettingsUI.h"
#include "General.h"
#include "afxdialogex.h"

#include "Settings.h"
#include "SkinInfo.h"

#define KEY_NAME L"3RVX"
#define STARTUP_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"

IMPLEMENT_DYNAMIC(General, CPropertyPage)

General::General() :
CPropertyPage(General::IDD) {

}

General::~General() {

}

void General::DoDataExchange(CDataExchange* pDX)
{
    CPropertyPage::DoDataExchange(pDX);
    DDX_Control(pDX, CHK_STARTUP, _startup);
    DDX_Control(pDX, CHK_NOTIFY, _notify);
    DDX_Control(pDX, CHK_SOUNDS, _sounds);
    DDX_Control(pDX, CMB_LANG, _lang);
    DDX_Control(pDX, GRP_SKIN, _skinGrp);
    DDX_Control(pDX, GRP_BEHAVIOR, _behaviorGrp);
    DDX_Control(pDX, GRP_LANGUAGE, _languageGrp);
    DDX_Control(pDX, LBL_AUTHOR, _author);
    DDX_Control(pDX, CMB_SKIN, _skins);
    DDX_Control(pDX, BTN_WEBSITE, _website);
}

BOOL General::OnApply() {
    OutputDebugString(L"-> General\n");
    Settings *settings = Settings::Instance();
    RunOnStartup(CHECKED(_startup));
    settings->NotifyIconEnabled(CHECKED(_notify));
    settings->SoundEffectsEnabled(CHECKED(_sounds));

    int skinIdx = _skins.GetCurSel();
    CString skinName;
    _skins.GetLBText(skinIdx, skinName);
    settings->CurrentSkin((LPCWSTR) skinName);

    UIUtils::SaveSettings(*this);
    return CPropertyPage::OnApply();
}

BOOL General::OnCommand(WPARAM wParam, LPARAM lParam) {
    SetModified();
    return CPropertyPage::OnCommand(wParam, lParam);
}

void General::LoadSettings() {
    Settings *settings = Settings::Instance();
    _startup.SetCheck(RunOnStartup());
    _notify.SetCheck(settings->NotifyIconEnabled());
    _sounds.SetCheck(settings->SoundEffectsEnabled());

    /* Determine which skins are available */
    std::list<CString> skins = FindSkins(L"../3RVX/Skins");
    for (CString skin : skins) {
        _skins.AddString(skin);
    }

    /* Update the combo box with the current skin */
    std::wstring current = settings->SkinName();
    int idx = _skins.SelectString(0, current.c_str());
    if (idx == CB_ERR) {
        _skins.SelectString(0, DEFAULT_SKIN);
    }
    LoadSkinInfo();

    /* Populate the language box */
    std::list<CString> languages = FindLanguages(
        settings->LanguagesDir().c_str());

    for (CString language : languages) {
        _lang.AddString(language);
    }
    std::wstring currentLang = settings->LanguageName();
    _lang.SelectString(0, currentLang.c_str());
}

BOOL General::OnInitDialog() {
    CPropertyPage::OnInitDialog();
    LoadSettings();
    return TRUE;
}

std::list<CString> General::FindSkins(CString dir) {
    std::list<CString> skins;

    CFileFind ff;
    dir += L"\\*";
    BOOL result = ff.FindFile(dir);
    while (result) {
        result = ff.FindNextFile();
        if (ff.IsDots()) {
            continue;
        }

        if (ff.IsDirectory()) {
            CFileFind inDir;
            CString dirPath = ff.GetFilePath();
            dirPath += L"\\skin.xml";
            if (inDir.FindFile(dirPath)) {
                /* We found a skin XML file; add the skin dir to our list. */
                skins.push_back(ff.GetFileName());
            }
        }
    }

    return skins;
}

std::list<CString> General::FindLanguages(CString dir) {
    std::list<CString> languages;

    CFileFind ff;
    dir += L"\\*.xml";
    BOOL result = ff.FindFile(dir);
    while (result) {
        result = ff.FindNextFile();
        if (ff.IsDots() || ff.IsDirectory()) {
            continue;
        }

        /* Even though we asked for *xml files, FindNextFile() will still
         * return results that start with .xml (like .xmlblah) */
        CString ext = ff.GetFileName().Right(3);
        if (ext == L"xml") {
            languages.push_back(ff.GetFileTitle());
        }
    }

    return languages;
}

void General::LoadSkinInfo() {
    CString selectedSkin;
    int selIdx = _skins.GetCurSel();
    _skins.GetLBText(selIdx, selectedSkin);

    std::wstring skinXML
        = Settings::Instance()->SkinXML((LPCWSTR) selectedSkin);
    SkinInfo s(skinXML);

    CString authorText(L"Author:");
    authorText.Append(L" ");
    authorText.Append(s.Author().c_str());
    _author.SetWindowTextW(authorText);

    _url = s.URL();
    _website.EnableWindow((_url != L""));
}
bool General::RunOnStartup() {
    CRegKey rk;
    int result = rk.Open(HKEY_CURRENT_USER, STARTUP_KEY, KEY_READ);
    if (result == ERROR_SUCCESS) {
        CString str;
        ULONG bufLen = 1024;
        LPTSTR buf = str.GetBufferSetLength(bufLen);

        int queryResult = rk.QueryStringValue(KEY_NAME, buf, &bufLen);
        if (queryResult == ERROR_SUCCESS) {
            return true;
        }
    }
    return false;
}

void General::RunOnStartup(bool enable) {
    std::wstring path = Settings::AppDir();
    CString exePath(path.c_str());
    exePath.Append(L"\\3RVX.exe");

    CRegKey rk;
    int result = rk.Open(HKEY_CURRENT_USER, STARTUP_KEY, KEY_WRITE);
    if (result == ERROR_SUCCESS) {
        if (enable) {
            rk.SetStringValue(KEY_NAME, exePath, REG_SZ);
        } else {
            rk.DeleteValue(KEY_NAME);
        }
    }
}

BEGIN_MESSAGE_MAP(General, CPropertyPage)
    ON_BN_CLICKED(BTN_WEBSITE, &General::OnBnClickedWebsite)
    ON_CBN_SELCHANGE(CMB_SKIN, &General::OnCbnSelchangeSkin)
END_MESSAGE_MAP()

void General::OnBnClickedWebsite() {
    ShellExecute(NULL, L"open", _url.c_str(), NULL, NULL, SW_SHOWNORMAL);
}

void General::OnCbnSelchangeSkin() {
    LoadSkinInfo();
}<commit_msg>Fix hardcoded skin dir loader<commit_after>#include "stdafx.h"
#include "SettingsUI.h"
#include "General.h"
#include "afxdialogex.h"

#include "Settings.h"
#include "SkinInfo.h"

#define KEY_NAME L"3RVX"
#define STARTUP_KEY L"Software\\Microsoft\\Windows\\CurrentVersion\\Run"

IMPLEMENT_DYNAMIC(General, CPropertyPage)

General::General() :
CPropertyPage(General::IDD) {

}

General::~General() {

}

void General::DoDataExchange(CDataExchange* pDX)
{
    CPropertyPage::DoDataExchange(pDX);
    DDX_Control(pDX, CHK_STARTUP, _startup);
    DDX_Control(pDX, CHK_NOTIFY, _notify);
    DDX_Control(pDX, CHK_SOUNDS, _sounds);
    DDX_Control(pDX, CMB_LANG, _lang);
    DDX_Control(pDX, GRP_SKIN, _skinGrp);
    DDX_Control(pDX, GRP_BEHAVIOR, _behaviorGrp);
    DDX_Control(pDX, GRP_LANGUAGE, _languageGrp);
    DDX_Control(pDX, LBL_AUTHOR, _author);
    DDX_Control(pDX, CMB_SKIN, _skins);
    DDX_Control(pDX, BTN_WEBSITE, _website);
}

BOOL General::OnApply() {
    OutputDebugString(L"-> General\n");
    Settings *settings = Settings::Instance();
    RunOnStartup(CHECKED(_startup));
    settings->NotifyIconEnabled(CHECKED(_notify));
    settings->SoundEffectsEnabled(CHECKED(_sounds));

    int skinIdx = _skins.GetCurSel();
    CString skinName;
    _skins.GetLBText(skinIdx, skinName);
    settings->CurrentSkin((LPCWSTR) skinName);

    UIUtils::SaveSettings(*this);
    return CPropertyPage::OnApply();
}

BOOL General::OnCommand(WPARAM wParam, LPARAM lParam) {
    SetModified();
    return CPropertyPage::OnCommand(wParam, lParam);
}

void General::LoadSettings() {
    Settings *settings = Settings::Instance();
    _startup.SetCheck(RunOnStartup());
    _notify.SetCheck(settings->NotifyIconEnabled());
    _sounds.SetCheck(settings->SoundEffectsEnabled());

    /* Determine which skins are available */
    std::list<CString> skins = FindSkins(Settings::SkinDir().c_str());
    for (CString skin : skins) {
        _skins.AddString(skin);
    }

    /* Update the combo box with the current skin */
    std::wstring current = settings->SkinName();
    int idx = _skins.SelectString(0, current.c_str());
    if (idx == CB_ERR) {
        _skins.SelectString(0, DEFAULT_SKIN);
    }
    LoadSkinInfo();

    /* Populate the language box */
    std::list<CString> languages = FindLanguages(
        settings->LanguagesDir().c_str());

    for (CString language : languages) {
        _lang.AddString(language);
    }
    std::wstring currentLang = settings->LanguageName();
    _lang.SelectString(0, currentLang.c_str());
}

BOOL General::OnInitDialog() {
    CPropertyPage::OnInitDialog();
    LoadSettings();
    return TRUE;
}

std::list<CString> General::FindSkins(CString dir) {
    std::list<CString> skins;

    CFileFind ff;
    dir += L"\\*";
    BOOL result = ff.FindFile(dir);
    while (result) {
        result = ff.FindNextFile();
        if (ff.IsDots()) {
            continue;
        }

        if (ff.IsDirectory()) {
            CFileFind inDir;
            CString dirPath = ff.GetFilePath();
            dirPath += L"\\skin.xml";
            if (inDir.FindFile(dirPath)) {
                /* We found a skin XML file; add the skin dir to our list. */
                skins.push_back(ff.GetFileName());
            }
        }
    }

    return skins;
}

std::list<CString> General::FindLanguages(CString dir) {
    std::list<CString> languages;

    CFileFind ff;
    dir += L"\\*.xml";
    BOOL result = ff.FindFile(dir);
    while (result) {
        result = ff.FindNextFile();
        if (ff.IsDots() || ff.IsDirectory()) {
            continue;
        }

        /* Even though we asked for *xml files, FindNextFile() will still
         * return results that start with .xml (like .xmlblah) */
        CString ext = ff.GetFileName().Right(3);
        if (ext == L"xml") {
            languages.push_back(ff.GetFileTitle());
        }
    }

    return languages;
}

void General::LoadSkinInfo() {
    CString selectedSkin;
    int selIdx = _skins.GetCurSel();
    _skins.GetLBText(selIdx, selectedSkin);

    std::wstring skinXML
        = Settings::Instance()->SkinXML((LPCWSTR) selectedSkin);
    SkinInfo s(skinXML);

    CString authorText(L"Author:");
    authorText.Append(L" ");
    authorText.Append(s.Author().c_str());
    _author.SetWindowTextW(authorText);

    _url = s.URL();
    _website.EnableWindow((_url != L""));
}
bool General::RunOnStartup() {
    CRegKey rk;
    int result = rk.Open(HKEY_CURRENT_USER, STARTUP_KEY, KEY_READ);
    if (result == ERROR_SUCCESS) {
        CString str;
        ULONG bufLen = 1024;
        LPTSTR buf = str.GetBufferSetLength(bufLen);

        int queryResult = rk.QueryStringValue(KEY_NAME, buf, &bufLen);
        if (queryResult == ERROR_SUCCESS) {
            return true;
        }
    }
    return false;
}

void General::RunOnStartup(bool enable) {
    std::wstring path = Settings::AppDir();
    CString exePath(path.c_str());
    exePath.Append(L"\\3RVX.exe");

    CRegKey rk;
    int result = rk.Open(HKEY_CURRENT_USER, STARTUP_KEY, KEY_WRITE);
    if (result == ERROR_SUCCESS) {
        if (enable) {
            rk.SetStringValue(KEY_NAME, exePath, REG_SZ);
        } else {
            rk.DeleteValue(KEY_NAME);
        }
    }
}

BEGIN_MESSAGE_MAP(General, CPropertyPage)
    ON_BN_CLICKED(BTN_WEBSITE, &General::OnBnClickedWebsite)
    ON_CBN_SELCHANGE(CMB_SKIN, &General::OnCbnSelchangeSkin)
END_MESSAGE_MAP()

void General::OnBnClickedWebsite() {
    ShellExecute(NULL, L"open", _url.c_str(), NULL, NULL, SW_SHOWNORMAL);
}

void General::OnCbnSelchangeSkin() {
    LoadSkinInfo();
}<|endoftext|>


<commit_before>// Copyright 2018 Google LLC. All Rights Reserved.
/*
  Copyright (C) 2016 Steven L. Scott

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
#ifndef BOOM_SPLINE_HPP
#define BOOM_SPLINE_HPP
#include "LinAlg/Vector.hpp"

namespace BOOM {
  // A base class providing features shared by different spline bases.
  // Examples inclue Bsplines, Msplines, and Isplines.
  class SplineBase {
   public:
    // Args:
    //   knots: The set of knots for the spline.  Between pairs of
    //     knots, the spline is a piecewise polynomial whose degree is
    //     given by the second argument.
    //
    // Splines also have a notion of 'degree' or 'order', but this can
    // be defined differently by different bases, so it is not part of
    // the shared base class.
    explicit SplineBase(const Vector &knots);
    virtual ~SplineBase() {}

    virtual Vector basis(double x) const = 0;

    // The dimension of the spline basis (i.e. the dimension of the
    // vector returned by a call to 'basis()'.
    virtual int basis_dimension() const = 0;

    // Adds a knot at the given  Location.  If knot_location lies
    // before the first or after the last current knot, then the
    // domain of the spline is extended to cover knot_location.
    void add_knot(double knot_location);

    // Remove the specified knot.  An exception will be thrown if
    // which_knot is outside the range of knots_.  If which_knot == 0
    // or which_knot == number_of_knots() - 1 then the domain of the
    // spline basis will be reduced.
    void remove_knot(int which_knot);

    // The vector of knots.  Implicit boundary knots are not included.
    virtual const Vector &knots() const { return knots_; }
    virtual int number_of_knots() const { return knots_.size(); }

    // If the argument is in the interior of the knots vector, return
    // knots_[i].  If it is off the end to the left return knots_[0].
    // If it is off the end to the right then include knots_.back().
    // The implicit assumption is that we have an infinite set of
    // knots piled up on the beginning and end of the actual knot
    // sequence.
    virtual double knot(int i) const;

    virtual double final_knot() const;

    // Compute the index of the largest knot less than or equal to x.
    virtual int knot_span(double x) const;

   private:
    virtual void increment_basis_dimension() = 0;
    virtual void decrement_basis_dimension() = 0;

    // The vector of knots defining the mesh points for the spline.
    // This is sorted by the constructor and it is kept sorted by
    // add_knot() and remove_knot().  The terminal knots at the
    // beginning and end of this vector are assumed to repeat an
    // infinite number of times.  If a knot is added outside the knot
    // range, then the old terminal knot becomes a single knot, and
    // the new terminal knot is infinitely repeated.
    Vector knots_;
  };

}  // namespace BOOM
#endif  // BOOM_SPLINE_HPP
<commit_msg>Add basis_matrix method to SplineBase.<commit_after>// Copyright 2018 Google LLC. All Rights Reserved.
/*
  Copyright (C) 2016 Steven L. Scott

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
#ifndef BOOM_SPLINE_HPP
#define BOOM_SPLINE_HPP
#include "LinAlg/Vector.hpp"
#include "LinAlg/Matrix.hpp"

namespace BOOM {
  // A base class providing features shared by different spline bases.
  // Examples inclue Bsplines, Msplines, and Isplines.
  class SplineBase {
   public:
    // Args:
    //   knots: The set of knots for the spline.  Between pairs of
    //     knots, the spline is a piecewise polynomial whose degree is
    //     given by the second argument.
    //
    // Splines also have a notion of 'degree' or 'order', but this can
    // be defined differently by different bases, so it is not part of
    // the shared base class.
    explicit SplineBase(const Vector &knots);
    virtual ~SplineBase() {}

    virtual Vector basis(double x) const = 0;

    Matrix basis_matrix(const Vector &x) const {
      Matrix ans(x.size(), this->basis_dimension());
      for (int i = 0; i < x.size(); ++i) {
        ans.row(i) = this->basis(x[i]);
      }
      return ans;
    }

    // The dimension of the spline basis (i.e. the dimension of the
    // vector returned by a call to 'basis()'.
    virtual int basis_dimension() const = 0;

    // Adds a knot at the given  Location.  If knot_location lies
    // before the first or after the last current knot, then the
    // domain of the spline is extended to cover knot_location.
    void add_knot(double knot_location);

    // Remove the specified knot.  An exception will be thrown if
    // which_knot is outside the range of knots_.  If which_knot == 0
    // or which_knot == number_of_knots() - 1 then the domain of the
    // spline basis will be reduced.
    void remove_knot(int which_knot);

    // The vector of knots.  Implicit boundary knots are not included.
    virtual const Vector &knots() const { return knots_; }
    virtual int number_of_knots() const { return knots_.size(); }

    // If the argument is in the interior of the knots vector, return
    // knots_[i].  If it is off the end to the left return knots_[0].
    // If it is off the end to the right then include knots_.back().
    // The implicit assumption is that we have an infinite set of
    // knots piled up on the beginning and end of the actual knot
    // sequence.
    virtual double knot(int i) const;

    virtual double final_knot() const;

    // Compute the index of the largest knot less than or equal to x.
    virtual int knot_span(double x) const;

   private:
    virtual void increment_basis_dimension() = 0;
    virtual void decrement_basis_dimension() = 0;

    // The vector of knots defining the mesh points for the spline.
    // This is sorted by the constructor and it is kept sorted by
    // add_knot() and remove_knot().  The terminal knots at the
    // beginning and end of this vector are assumed to repeat an
    // infinite number of times.  If a knot is added outside the knot
    // range, then the old terminal knot becomes a single knot, and
    // the new terminal knot is infinitely repeated.
    Vector knots_;
  };

}  // namespace BOOM
#endif  // BOOM_SPLINE_HPP
<|endoftext|>


<commit_before>#include <sys/socket.h>

#include "utils.h"
#include "client_base.h"

const int WRITE_QUEUE_SIZE = 30;

int BaseClient::total_clients = 0;

BaseClient::BaseClient(ev::loop_ref &loop, int sock_, DatabasePool *database_pool_, double active_timeout_, double idle_timeout_)
	: io(loop),
	  async(loop),
	  destroyed(false),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	sig.set<BaseClient, &BaseClient::signal_cb>(this);
	sig.start(SIGINT);

	async.set<BaseClient, &BaseClient::async_cb>(this);
	async.start();

	io.set<BaseClient, &BaseClient::io_cb>(this);
	io.start(sock, ev::READ);
}

BaseClient::~BaseClient()
{
	destroy();
	sig.stop();
	LOG_OBJ(this, "DELETED!\n");
}

void BaseClient::signal_cb(ev::sig &signal, int revents)
{
	LOG_EV(this, "Signaled destroy!!\n");
	destroy();
	delete this;
}

void BaseClient::destroy()
{
	if (destroyed) {
		return;
	}

	destroyed = true;

	close();

	// Stop and free watcher if client socket is closing
	io.stop();
	async.stop();

	::close(sock);
	LOG_OBJ(this, "DESTROYED!\n");
}

void BaseClient::close() {
	if (closed) {
		return;
	}

	closed = true;
	LOG_OBJ(this, "CLOSED!\n");
}

void BaseClient::async_cb(ev::async &watcher, int revents)
{
	if (destroyed) {
		return;
	}

	LOG_EV(this, "ASYNC_CB (sock=%d) %x\n", sock, revents);

	if (write_queue.empty()) {
		if (closed) {
			destroy();
		}
	} else {
		io.set(ev::READ|ev::WRITE);
	}

	if (destroyed) {
		delete this;
	}
}

void BaseClient::io_cb(ev::io &watcher, int revents)
{
	if (destroyed) {
		return;
	}

	LOG_EV(this, "IO_CB (sock=%d) %x\n", sock, revents);

	if (revents & EV_ERROR) {
		LOG_ERR(this, "ERROR: got invalid event (sock=%d): %s\n", sock, strerror(errno));
		destroy();
		return;
	}

	if (revents & EV_READ)
		read_cb(watcher);

	if (revents & EV_WRITE)
		write_cb(watcher);

	if (write_queue.empty()) {
		if (closed) {
			destroy();
		} else {
			io.set(ev::READ);
		}
	} else {
		io.set(ev::READ|ev::WRITE);
	}

	if (destroyed) {
		delete this;
	}
}

void BaseClient::write_cb(ev::io &watcher)
{
	if (write_queue.empty()) {
		io.set(ev::READ);
	} else {
		Buffer* buffer = write_queue.front();

		size_t buf_size = buffer->nbytes();
		const char * buf = buffer->dpos();

		LOG_CONN(this, "(sock=%d) <<-- '%s'\n", sock, repr(buf, buf_size).c_str());

		ssize_t written = ::write(watcher.fd, buf, buf_size);

		if (written < 0) {
			if (errno != EAGAIN) {
				LOG_ERR(this, "ERROR: write error (sock=%d): %s\n", sock, strerror(errno));
				destroy();
			}
		} else if (written == 0) {
			// nothing written?
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				write_queue.pop(buffer);
				delete buffer;
			}
		}
	}
}

void BaseClient::read_cb(ev::io &watcher)
{
	char buf[1024];

	ssize_t received = ::read(watcher.fd, buf, sizeof(buf));

	if (received < 0) {
		if (errno != EAGAIN) {
			LOG_ERR(this, "ERROR: read error (sock=%d): %s\n", sock, strerror(errno));
			destroy();
		}
	} else if (received == 0) {
		// The peer has closed its half side of the connection.
		LOG_CONN(this, "Received EOF (sock=%d)!\n", sock);
		destroy();
	} else {
		LOG_CONN(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
		on_read(buf, received);
	}
}

void BaseClient::write(const char *buf, size_t buf_size)
{
	Buffer *buffer = new Buffer('\0', buf, buf_size);
	write_queue.push(buffer);

	async.send();
}
<commit_msg>Write queue without limits<commit_after>#include <sys/socket.h>

#include "utils.h"
#include "client_base.h"

const int WRITE_QUEUE_SIZE = -1;

int BaseClient::total_clients = 0;

BaseClient::BaseClient(ev::loop_ref &loop, int sock_, DatabasePool *database_pool_, double active_timeout_, double idle_timeout_)
	: io(loop),
	  async(loop),
	  destroyed(false),
	  closed(false),
	  sock(sock_),
	  database_pool(database_pool_),
	  write_queue(WRITE_QUEUE_SIZE)
{
	sig.set<BaseClient, &BaseClient::signal_cb>(this);
	sig.start(SIGINT);

	async.set<BaseClient, &BaseClient::async_cb>(this);
	async.start();

	io.set<BaseClient, &BaseClient::io_cb>(this);
	io.start(sock, ev::READ);
}

BaseClient::~BaseClient()
{
	destroy();
	sig.stop();
	LOG_OBJ(this, "DELETED!\n");
}

void BaseClient::signal_cb(ev::sig &signal, int revents)
{
	LOG_EV(this, "Signaled destroy!!\n");
	destroy();
	delete this;
}

void BaseClient::destroy()
{
	if (destroyed) {
		return;
	}

	destroyed = true;

	close();

	// Stop and free watcher if client socket is closing
	io.stop();
	async.stop();

	::close(sock);
	LOG_OBJ(this, "DESTROYED!\n");
}

void BaseClient::close() {
	if (closed) {
		return;
	}

	closed = true;
	LOG_OBJ(this, "CLOSED!\n");
}

void BaseClient::async_cb(ev::async &watcher, int revents)
{
	if (destroyed) {
		return;
	}

	LOG_EV(this, "ASYNC_CB (sock=%d) %x\n", sock, revents);

	if (write_queue.empty()) {
		if (closed) {
			destroy();
		}
	} else {
		io.set(ev::READ|ev::WRITE);
	}

	if (destroyed) {
		delete this;
	}
}

void BaseClient::io_cb(ev::io &watcher, int revents)
{
	if (destroyed) {
		return;
	}

	LOG_EV(this, "IO_CB (sock=%d) %x\n", sock, revents);

	if (revents & EV_ERROR) {
		LOG_ERR(this, "ERROR: got invalid event (sock=%d): %s\n", sock, strerror(errno));
		destroy();
		return;
	}

	if (revents & EV_READ)
		read_cb(watcher);

	if (revents & EV_WRITE)
		write_cb(watcher);

	if (write_queue.empty()) {
		if (closed) {
			destroy();
		} else {
			io.set(ev::READ);
		}
	} else {
		io.set(ev::READ|ev::WRITE);
	}

	if (destroyed) {
		delete this;
	}
}

void BaseClient::write_cb(ev::io &watcher)
{
	if (write_queue.empty()) {
		io.set(ev::READ);
	} else {
		Buffer* buffer = write_queue.front();

		size_t buf_size = buffer->nbytes();
		const char * buf = buffer->dpos();

		LOG_CONN(this, "(sock=%d) <<-- '%s'\n", sock, repr(buf, buf_size).c_str());

		ssize_t written = ::write(watcher.fd, buf, buf_size);

		if (written < 0) {
			if (errno != EAGAIN) {
				LOG_ERR(this, "ERROR: write error (sock=%d): %s\n", sock, strerror(errno));
				destroy();
			}
		} else if (written == 0) {
			// nothing written?
		} else {
			buffer->pos += written;
			if (buffer->nbytes() == 0) {
				write_queue.pop(buffer);
				delete buffer;
			}
		}
	}
}

void BaseClient::read_cb(ev::io &watcher)
{
	char buf[1024];

	ssize_t received = ::read(watcher.fd, buf, sizeof(buf));

	if (received < 0) {
		if (errno != EAGAIN) {
			LOG_ERR(this, "ERROR: read error (sock=%d): %s\n", sock, strerror(errno));
			destroy();
		}
	} else if (received == 0) {
		// The peer has closed its half side of the connection.
		LOG_CONN(this, "Received EOF (sock=%d)!\n", sock);
		destroy();
	} else {
		LOG_CONN(this, "(sock=%d) -->> '%s'\n", sock, repr(buf, received).c_str());
		on_read(buf, received);
	}
}

void BaseClient::write(const char *buf, size_t buf_size)
{
	Buffer *buffer = new Buffer('\0', buf, buf_size);
	write_queue.push(buffer);

	async.send();
}
<|endoftext|>