示例#1
0
int main(int argc, char **argv)
{

    struct sockaddr_in src, dst;
    struct thread_resource threads[THREAD_NUM];
    pthread_t tid;
    int ports[MAX_PORT_NUM + 1] = {0};
    pcap_if_t *dev;
    char filter[256] = {0};
    int i;
    int len = sizeof(i);

    if (argc != 2)
    {
        fprintf(stderr, "Usage: sniff target_ip\n");
        exit(1);
    }    
    if (-1 == (dst_sock = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)))
        errquit("socket");

    if (NULL == (pair = (struct socket_pair *) malloc(sizeof(struct socket_pair))))
        errquit("malloc");
    pair->src = &src;
    pair->dst = &dst;

    printf("running...\n");
    configure_remote_addr(argv[1], pair->dst);
    snprintf(filter, 256, "tcp port %d", LOCAL_PORT);   // host 115.155.60.3 and dst port %d", LOCAL_PORT);

    dev = configure_local_addr(pair->src);
    pair->src->sin_port = htons(LOCAL_PORT);

#ifndef NNDEBUG
    printf("remote addr: %s\n", inet_ntoa(pair->dst->sin_addr));
    printf("local addr: %s\n", inet_ntoa(pair->src->sin_addr));
#endif

    init_resource(threads, THREAD_NUM, dst_sock, dev, filter, ports);
    for (i = 0; i < THREAD_NUM; ++i)
    {
        if (-1 == pthread_create(&threads[i].tid, NULL, capture, (void*)&threads[i]))
            errquit("pthread_create");
        pthread_detach(threads[i].tid);
    }
    sleep(1);
    if (-1 == pthread_create(&tid, NULL, detect, (void*)pair) )
        errquit("pthread_create");
    pthread_detach(tid);

    sleep(8);
    for (i = 0; i < THREAD_NUM; ++i)
        cancel_capture(&threads[i]);        
    printf("The following ports send SYN and ACK back:\n");
    for (i = 1; i < MAX_PORT_NUM + 1; ++i)
        if (0 != ports[i])
            printf("%d ", i);
    printf("\nDone!\n");
    free(pair);
    return(0);
}
示例#2
0
int main(int argc, char *argv[]){
	struct sockaddr_in cliaddr;
	char buf[MAXLINE+1];
	int i, j, nbyte, accp_sock, addrlen = sizeof(struct sockaddr_in);
	fd_set read_fds;

	if(argc != 2) {
		printf("사용법 : %s port\n", argv[0]);
		exit(0);
	}

	listen_sock = tcp_listen(INADDR_ANY, atoi(argv[1]), 5);
	while(1){
		FD_ZERO(&read_fds);
		FD_SET(listen_sock, &read_fds);
		for(i=0; i<num_chat; i++)
			FD_SET(clisock_list[i], &read_fds);
		maxfdp1 = getmax() + 1;
		puts("wait for client");
		if(select(maxfdp1, &read_fds, NULL, NULL, NULL)<0)
			errquit("select fail");

		if(FD_ISSET(listen_sock, &read_fds)){
			accp_sock=accept(listen_sock, (struct sockaddr*)&cliaddr, &addrlen);
			if(accp_sock == -1)
				errquit("accept fail");
			addClient(accp_sock, &cliaddr);
			send(accp_sock, START_STRING, strlen(START_STRING), 0);
			printf("%d번째 사용자 추가.\n", num_chat);
		}

		for(i=0; i<num_chat; i++){
			if(FD_ISSET(clisock_list[i], &read_fds)){
				nbyte = recv(clisock_list[i], buf, MAXLINE, 0);
				if(nbyte <=0){
					removeClient(i);
					continue;
				}
				buf[nbyte] = 0;
				if(strstr(buf, EXIT_STRING) != NULL) {
					removeClient(i);
					continue;
				}
				for(j=0; j<num_chat; j++)
					send(clisock_list[j], buf, nbyte, 0);
				printf("%s\n", buf);
			}
		}
	}
	return 0;
}
static void *_thread_internal2(void *arg){
    if(!arg) errquit("_thread_internal2: null arg");
    sinfo_t i = (sinfo_t) arg;
    _init_thread_context(i->tid,i->h);
//	 fprintf(stderr,"\n[%d]si = %p",tcb()->tid,i);
   // install top exception handler and execute thread if there's no exn
   if( _set_top_handler() == NULL ) {
#ifdef __RUNTIME_MEMORY_DEBUG_LOCKOP
            fprintf(stderr,"\n[%d] NEW THREAD.",	
              	 	tcb()->tid); 
#endif
	  (i->thread)((void *) (i+1));
   }
  // finalize thread context	 
//	fprintf(stderr,"\n[%d] fini_thread_context\n",i->tid);
  _fini_thread_context();
  // wake up main thread if I'm the last thread
  if(__sync_fetch_and_add(&all_done,-1) == 1)
   futex_wake((int *)&all_done,1);
  //HACK: generate segfault so as to switch
  //to the backup stack and free the current stack.
  // Mark the last page W/R. so that it can be deallocated
//  if (mprotect((void *) (((char *)i) + i->info.end_offset),1024,3))
//   errquit("__thread_internal2: mprotect failed.");

//  fprintf(stderr,"\n[%d]2 __si = %p",tcb()->tid,i);
  GC_free(i);
//  fprintf(stderr,"\n[%d]2 __si = %p. DONE",tcb()->tid,i);
  //goto_context(_thread_cleanup_stack,__second__stack,BACKUP_STK_SZ);
  //abort(); // should NOT reach this point
  pthread_exit(0); // should NOT reach this point
  return NULL;
}
void* _throw_fn(void* e, const char *filename, unsigned lineno) {
  static const int tag = 0;
  // FIX: use struct _xtunion_struct *  ??
  struct _handler_cons *my_handler = NULL;
  // pop handlers until exception handler found
  struct _ThreadKey *t = tcb();
  struct _RuntimeStack *current_frame = t->stack._current_frame;
  while (current_frame != NULL && current_frame->tag != tag) {
    if (current_frame->cleanup != NULL)
      current_frame->cleanup(current_frame);
	 current_frame = current_frame->next;
  }
  if( current_frame == NULL )
	  errquit("_throw_fn: no handler found - top handler not installed ?");
  t->stack._current_frame = current_frame->next;
  my_handler = (struct _handler_cons *) current_frame;
  t->exn._exn_thrown = e;
  t->exn._exn_filename = filename;
  t->exn._exn_lineno = lineno;
  // reached the top of the stack handlers
  if (  my_handler->handler == t->exn.top_handler.handler 
		  && !t->exn.in_uncaught_fun) {
    t->exn.in_uncaught_fun = 1;
    if(t->exn.uncaught_fun != NULL )
      (t->exn.uncaught_fun)();
  }
  longjmp(my_handler->handler,1);
  return NULL; // unreached
}
示例#5
0
int main(int argc, char *argv[])
{
	key_t shmkey, semkey;
	unsigned short initsemval[1];
	if(argc<2)
	{
		printf("Usage : %s shmkey semkey\n", argv[0]);
		exit(1);
	}

	shmkey = atoi(argv[1]);
	semkey = atoi(argv[2]);

	shmid = shmget(shmkey, 128, IPC_CREAT | 0600);
	if(shmid < 0 )
		errquit("shmget fail");

	shm_data = (char *)shmat(shmid, (void *)0, 0);

	if(shm_data == (char *)-1)
		errquit("shmat fail");

	semid = semget(semkey, 1, IPC_CREAT | 0600);

	if(semid == -1)
		errquit("semget fail");

	initsemval[0] = 1;
	semarg.array = initsemval;

	if(semctl(semid, 0, SETALL, semarg) == -1)
		errquit("semctl");

	fork_and_run();
	fork_and_run();

	busy();

	wait(NULL);
	wait(NULL);
	
	shmctl(shmid, IPC_RMID, 0);
	semctl(semid, 0, IPC_RMID, 0);

	return 0;
	
}
void _xspawn(caps_t caps, int len ,
             void * (*thread)(void *), void *arg, 
             int arg_len)
{
  pthread_attr_t attr;
  pthread_t id;
  int s;
 
  if ((s = pthread_attr_init(&attr)) != 0) {
    errno = s; perror("pthread_attr_init");
    errquit("internal error: _xspawn aborting\n");
  }

  if ((s = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED)) != 0) {
    errno = s; perror("pthread_attr_setdetachstate");
    errquit("internal error: _xspawn aborting\n");
  }

  sinfo_t si = __init_new_thread_stack(caps,len,thread,arg,arg_len);

  //force "main" to wait for the new thread
  //TODO: if pthread_create fails throw 
  //an exception and atomically decrement all_done
  __sync_fetch_and_add(&all_done,1);

  //  if(pthread_attr_setstack(&attr,
  //             ((char *)si)+si->info.begin_offset,
  //           si->info.end_offset-si->info.begin_offset))
  //      errquit("pthread_attr_setstack ");

  if (stack_space > 0) {
    if ((s = pthread_attr_setstacksize(&attr,stack_space)) != 0) {
      errno = s; perror("pthread_attr_setstacksize");
      errquit("internal error: _xspawn aborting\n");
    }
  }

  if ((s = GC_pthread_create(&id,&attr,_thread_internal2,si)) != 0) {
    errno = s; perror("pthread_create");
    errquit("internal error: _xspawn aborting\n");
  }
  if ((s = pthread_attr_destroy(&attr)) != 0) {
    errno = s; perror("pthread_attr_destroy");
    errquit("internal error: _xspawn aborting\n");
  }
}
/* treecopy assumes that n[0-n] is filled with zeros*/
 void __treecopy(caps_t o, 
                 struct _XTreeHandle *n, int len, 
                 unsigned int tid, 
                 struct hashtable **h) {
  int i;
  //initialize fresh memory
  memset(n,0,len*sizeof(struct _XTreeHandle));
  // create new tree with the appropriate capabilities
  for(i=0;i<len;i++) {
    struct _XTreeHandle *t = th(o,i);
    n[i].caps.rcnt = o[i].rc;
    n[i].caps.wr_cnt = o[i].wc;
    n[i].caps.rd_cnt= o[i].lc;
    n[i].h = t->h;
    hashtable_insert(h,n+i); // create mapping

    //increment ref count of this region
      __sync_fetch_and_add(&t->h->caps.rcnt,1);
    t->h->single_thread_key = 0; //not thread local
    if(o[i].wc) { // transfer writer capabilities
      if( tcb()->tid == t->h->caps.writer_cv) {
        t->h->caps.writer_cv = tid;
      } else
        errquit("_treecopy: writer_cv"); 
    }
    //if there exist read capabilities, increment read count
    if(o[i].lc)
      __sync_fetch_and_add(&t->h->caps.rd_cnt,1);

#ifdef __RUNTIME_MEMORY_DEBUG_LOCKOP
    print_xtree(n+i,0);
#endif
    struct _XTreeHandle *parent= t->parent_key;
    int idx;
    if(parent)
       for(idx=0;idx<len && th(o,idx) != parent;idx++);
    else
       idx = len;
    if(idx < len) {
      n[i].parent_key = n + idx;
      n[i].next_key =  n[idx].sub_keys;
      n[idx].sub_keys = n + i;
    }  else
      n[i].parent_key = 0;
  }
  //remove capabilities transferred from this tree
  //start off child nodes so that we don't bump into
  //a deallocated node (if a parent gets deallocated
  //its subregions are also removed). Notice that the
  //array "o" is already sorted in the natural 
  //allocation order.
  for(i=len-1;i>-1;i--) 
    _xregion_cap_th(-o[i].rc,-o[i].wc,-o[i].lc,th(o,i));
}
示例#8
0
void fork_and_run()
{
	pid_t pid = fork();
	if(pid < 0)
		errquit("fork() fail");
	else if(pid == 0)
	{
		busy();
		exit(0);
	}
	return;
}
// set _current_frame to its n+1'th tail (i.e. pop n+1 frames)
// Invariant: result is non-null
void _npop_frame(unsigned int n) {
  struct _ThreadKey *t = tcb();
  struct _RuntimeStack *current_frame = t->stack._current_frame;
  unsigned int i;

  for(i = n; i <= n; i--) {
    if(current_frame == NULL) 
      errquit("internal error: empty frame stack\n");
    dbgmsg("\nPOPING frame : %p code = %p" ,
             current_frame, current_frame->cleanup);
    if (current_frame->cleanup != NULL)
       current_frame->cleanup(current_frame);
    current_frame = current_frame->next;
  }
  t->stack._current_frame = current_frame;
}
示例#10
0
void echo(char *filename)
{
	int c;
	FILE *f = fopen(filename, "r");
	
	if (!f) {
		char buf[300];
		sprintf(buf, "cannot open file '%s'", filename);
		errquit(buf);
	}
	printf(">>> %s\n", filename);
	while ((c = fgetc(f)) != EOF)
		putchar(c);
	fclose(f);
	line_separator();
}
示例#11
0
int load_launchscript( lua_State * L, ebb_Options * ebboptions ) {
    char * bindir = getexec_dirpath();
    if(!bindir) {
        errquit(L, "ERROR: Failed to retreive path to this executable.\n");
    }

    char buffer[MAX_PATH_LEN]; // plenty of room
    size_t bufsize = MAX_PATH_LEN;

    if (ebboptions->uselegion) {
        snprintf(buffer, bufsize,
                 "%s/../include/ebb/src/launch_legion.t", bindir);
    } else {
        snprintf(buffer, bufsize,
                 "%s/../include/ebb/src/launch_script.t", bindir);
    }
    return terra_loadfile(L,buffer);
}
示例#12
0
static void doerror(lua_State * L) {
    errquit(L, "%s\n",luaL_checkstring(L,-1));
}
示例#13
0
void setupebb(lua_State * L, ebb_Options * ebboptions) {
    char * bindir = getexec_dirpath();
    if(!bindir) {
        errquit(L, "ERROR: Failed to retreive path to this executable.\n");
    }

    char buffer[MAX_PATH_LEN]; // plenty of room
    size_t bufsize = MAX_PATH_LEN;

    // Make sure we can find the Terra files
    snprintf(buffer, bufsize,
      "package.terrapath = package.terrapath..';%s/../include/?.t;'",
      bindir);
    if (terra_dostring(L, buffer))
        doerror(L);

    if (ebboptions->uselegion) {
        // extend the Terra include path
        snprintf(buffer, bufsize,
          "terralib.includepath = terralib.includepath.."
          "';%s/../legion/runtime;"
          "%s/../legion/runtime/legion;"
          "%s/../legion/runtime/mappers;"
          "%s/../mappers;"
          "%s/../legion_utils;"
          "%s/../legion/bindings/terra'",
          bindir, bindir, bindir, bindir, bindir, bindir);
        if (terra_dostring(L, buffer))
            doerror(L);

        // extend the Lua include path
        //snprintf(buffer, bufsize,
        //  "package.path = package.path.."
        //  "';%s/../legion/bindings/terra/?.t'",
        //  bindir);
        //if (terra_dostring(L, buffer))
        //    doerror(L);

        // Link the Legion Shared Library into Terra
        if (ebboptions->debug) {
            snprintf(buffer, bufsize,"terralib.linklibrary("
              "'%s/../legion/bindings/terra/liblegion_terra_debug.so')",
              bindir);
            if (terra_dostring(L, buffer))
                doerror(L);
            snprintf(buffer, bufsize,"terralib.linklibrary("
              "'%s/../mappers/libmapper_debug.so')",
              bindir);
            if (terra_dostring(L, buffer))
                doerror(L);
            snprintf(buffer, bufsize,"terralib.linklibrary("
              "'%s/../legion_utils/liblegion_utils_debug.so')",
              bindir);
            if (terra_dostring(L, buffer))
                doerror(L);
        } else {
            snprintf(buffer, bufsize,"terralib.linklibrary("
              "'%s/../legion/bindings/terra/liblegion_terra_release.so')",
              bindir);
            if (terra_dostring(L, buffer))
                doerror(L);
            snprintf(buffer, bufsize,"terralib.linklibrary("
              "'%s/../mappers/libmapper_release.so')",
              bindir);
            if (terra_dostring(L, buffer))
                doerror(L);
            snprintf(buffer, bufsize,"terralib.linklibrary("
              "'%s/../legion_utils/liblegion_utils_release.so')",
              bindir);
            if (terra_dostring(L, buffer))
                doerror(L);
        }

        if (ebboptions->legionspy) {
            lua_pushboolean(L, true);
            lua_setglobal(L, "EBB_LEGION_USE_SPY");
        }
        if (ebboptions->legionprof) {
            lua_pushboolean(L, true);
            lua_setglobal(L, "EBB_LEGION_USE_PROF");
        }
        if (ebboptions->partition) {
            lua_pushboolean(L, true);
            lua_setglobal(L, "EBB_PARTITION");
        }
    }

    if (ebboptions->usegpu) {
        lua_pushboolean(L, true);
        lua_setglobal(L, "EBB_USE_GPU_SIGNAL");
    }
    if (strcmp(ebboptions->additional, "")) {
        lua_pushstring(L, ebboptions->additional);
        lua_setglobal(L, "EBB_ADDITIONAL_ARGS");
    }
}
示例#14
0
/***********************************************************************
 * directive_basis
 * 
 * Parses the 'basis' section of an input file.
 **********************************************************************/
void directive_basis()
{
	extern struct elem_info ptable[];   // see ./chem.c
	struct elem_info *p = &ptable[0];
	char basis_name[30];
	int basis_type = CARTESIAN;
	
	//printf("DIRECTIVE BASIS\n");
	nextToken();
	if (ttype == '"')
		strcpy(basis_name, sval);
	else {
		strcpy(basis_name, "ao basis");
		lexerPushBack();
	}
	nextToken();
	if (ttype == TT_WORD && sval != NULL) {
		if (!strcmp(sval, "spherical"))
			basis_type = SPHERICAL;
		else if (!strcmp(sval, "cartesian"))
			basis_type = CARTESIAN;
		else
			lexerPushBack();
	}
	//printf("BASIS = %s LOOP\n", basis_type == SPHERICAL ? "SPHERICAL" : "CARTESIAN");
	
	for (;;) {
		nextToken(); /* sval == NULL ---> seg fault */
		//if (sval == NULL)
			//printf("NULL SVAL\n");
		if (ttype == TT_KW_END) {
			//printf("END OF BASIS REACHED\n");
			break;
		}
		else if (ttype != TT_WORD)
			errquit("in basis input: end keyword or element symbol is required");
		else {
			struct elem_info *elem = searchBySym(sval);
			int L, i, j, n, nprim, ncontr;
			double buf[10][10];
			
			if (!elem)
				errquit("in basis input: unknown element");
			//printf("ELEMENT Z = %d\n", elem->Z);
			match(TT_WORD);
			if (!strcmp(sval, "s"))
				L = BFN_S;
			else if (!strcmp(sval, "sp"))
				L = BFN_SP;
			else if (!strcmp(sval, "p"))
				L = BFN_P;
			else if (!strcmp(sval, "d"))
				L = BFN_D;
			else
				errquit("in basis input: wrong angular momentum (only S, SP, P, D are allowed)");
				
			if (!elem->bas) {   /* bind new basis set to element */
				elem->bas = (struct basis_set *) malloc (sizeof(struct basis_set));
				elem->bas->size = 0;
				elem->bas->type = basis_type;
				strcpy(elem->bas->name, basis_name);
			}
			
			nextToken();
			setEOLSignificant(1);
			i = 0;
			j = 0;
			ncontr = 0;
			while (ttype == TT_NUMBER) {
				buf[i][j++] = nval;
				nextToken();
				if (ttype == TT_EOL) {  // begin new row of doubles
					nextToken();
					i++;
					ncontr = j - 1;
					j = 0;
				}
			}
			nprim = i;
			setEOLSignificant(0);
			lexerPushBack();
			
			for (i = 0; i < ncontr; i++) {
				n = elem->bas->size++;
				if (i == 0 && L == BFN_SP) {
					elem->bas->cgtfs[n].L = BFN_S;
					L = BFN_P;
				}
				else
					elem->bas->cgtfs[n].L = L;
				elem->bas->cgtfs[n].nprim = nprim;
				for (j = 0; j < nprim; j++) {
					elem->bas->cgtfs[n].exp[j] = buf[j][0];
					elem->bas->cgtfs[n].c[j]   = buf[j][i+1];
				}
			}
			
			/*n = elem->bas->size;
			// config new contracted function
			elem->bas->cgtfs[n].nprim = 0;
			elem->bas->cgtfs[n].L = L;
			nprim = 0;
			// get exp & coeff
			nextToken();
			while (ttype == TT_NUMBER) {
				double exp = nval;
				if (exp <= 0)
					errquit("in basis input: exponent should be positive");
				elem->bas->cgtfs[n].exp[nprim] = exp;
				// get contraction coefficients
				match(TT_NUMBER);
				elem->bas->cgtfs[n].c[nprim] = nval;
				nprim++;
				elem->bas->cgtfs[n].nprim++; // to the next primitive
				nextToken();
			}
			elem->bas->size++;
			lexerPushBack();*/
		}
	}
	//printf("END OF DIRECTIVE BASIS\n");
	
	for (; *p->sym; p++) {
		if (!p->bas)
			continue;
		estimate_principal_numbers(p->bas);
	}
}
示例#15
0
void rhf_loop(Molecule_t *molecule, BasisFunc_t *bfns, int M)
{
	int i, n, Nelecs;
	double t0;
	double hfe, olde, deltap;
	double diiserror;
	double *H;   // core Hamiltonian
	double *S;   // overlap
	double *X;   // transformation to orthonormal basis, stored by rows
	double *F;   // Fock matrix
	double *P;   // density
	double *P0;  // stored density from previous step
	double *C;   // AO coefficients in MO
	double *E;   // orbital energies
	double *ErrM;// error matrix, e=FDS-SDF
	int nbytes;  // bytes in matrix to allocate
	int maxiter; // max # scf iterations
	int direct;  // enable direct scf (1/0)
	int do_diis; // is diis enabled (0/1)
	int diisbas; // diis subspace dimension
	int molden_out; // print vectors to molden format or not
	double Enuc; // nuclei repulsion energy
	DIISList_t *diislist; // list with stored Fock and error matrices
	
	// read parameters from the rtdb
	rtdb_get("scf:maxiter", &maxiter);
	rtdb_get("scf:direct",  &direct );
	rtdb_get("scf:diis",    &do_diis);
	rtdb_get("scf:diisbas", &diisbas);
	rtdb_get("visual:molden", &molden_out);
	
	n = 1;  // iteration number 1
	t0 = MPI_Wtime();
	nbytes = M * M * sizeof(double);
	diislist = NULL;
	Enuc = enuc(molecule);
	Nelecs = nelec(molecule);
	
	H = (double *) qalloc(nbytes);
	S = (double *) qalloc(nbytes);
	X = (double *) qalloc(nbytes);
	F = (double *) qalloc(nbytes);
	P = (double *) qalloc(nbytes);
	P0= (double *) qalloc(nbytes);
	C = (double *) qalloc(nbytes);
	E = (double *) qalloc(M*sizeof(double));
	
	// compute core Hamiltonian and overlap matrices
	read_1e_integrals(H, S, bfns, M);
	
	// basis orthogonalization
	orthobasis(S, X, M);
	
	// guess
	rhf_guess(F, H, P, S, X, C, E, molecule, bfns, M);
	olde = rhf_energy(P, F, H, M) + Enuc;
	
	printf(" iter.       Energy         Delta E       RMS-Dens       DIIS-Err     time\n");
	printf("----------------------------------------------------------------------------\n");
	while (1) {
		if (n > maxiter) {
			printf("----------------------------------------------------------------------------\n");
			printf("      not converged!\n");
			errquit("no convergence of SCF equations! Try to increase scf:maxiter\n");
		}
			
		memcpy(P0, P, nbytes);  // store actual P
		
		if (direct) {
			// integral-direct
			rhf_makefock_direct(F, H, P, bfns, M);
		}
		else {
			// conventional scf (2e int-s from disk)
			rhf_makefock(F, H, P, M);
		}
		
		// in fact, now we have Fi and Di, used to contruct this Fi
		ErrM = (double *) qalloc(nbytes);
		make_error_matrix(ErrM, F, P, S, M);
		diiserror = maxerr(ErrM, M);
		
		// if DIIS is enabled
		if (do_diis && diisbas != 0) {
			if (!diislist)
				diislist = newDIISList(ErrM, F, M);
			else
				diis_store(diislist, ErrM, F, M, diisbas);
			// extrapolate new F:
			diis_extrapolate(F, diislist, diisbas);
		}
		
		diag_fock(F, X, C, E, M);
		rhf_makedensity(P, C, Nelecs, M);
		
		deltap = rmsdens(P, P0, M);
		hfe = rhf_energy(P, F, H, M) + Enuc;
		printf("%4d%17.8f%15.8f%15.8f%15.8f%8.2f\n", n, hfe, hfe-olde, deltap, diiserror, MPI_Wtime()-t0);
		if (deltap < 1e-6)
			break;
		olde = hfe;
		n++;
	}
	printf("----------------------------------------------------------------------------\n");
	printf("          Total SCF energy =%15.8f\n", hfe);
	printf("  Nuclear repulsion energy =%15.8f\n", Enuc);
	
	printf("\n\n");
	
	/* save results to rtdb */
	rtdb_set("scf:etot", "%d", hfe);
	rtdb_set("scf:enuc", "%d", Enuc);
	
	// Освобождение ресурсов, которые были заняты DIIS
	if (do_diis && diislist)
		removeDIISList(diislist);
	
	// Вывод результатов
	// Энергии орбиталей
	printf("\n");
	printf("         Molecular Orbitals Summary\n");
	printf("  +-----+-----+----------------+----------+\n");
	printf("  | No  | Occ |     Energy     | Symmetry |\n");
	printf("  +-----+-----+----------------+----------+\n");
	for (i = 0; i < M; i++)
		printf("  | %-3d |  %1d  | %14.8f |     ?    |\n", i+1, (i < Nelecs/2) ? 2 : 0, E[i]);
	printf("  +-----+-----+----------------+----------+\n");
	
	// Вывод векторов в файл в формате Molden
	if (molden_out) {
		int i;
		int *occ = (int *) qalloc(sizeof(int) * M);
		memset(occ, 0, sizeof(int) * M);
		for (i = 0; i < Nelecs/2; i++)
			occ[i] = 2;
		vectors_molden(molecule, C, E, occ, M);
		qfree(occ, sizeof(int) * M);
	}
	
	// population analysis
	mulliken(molecule, bfns, P, S, M);
	loewdin (molecule, bfns, P, S, M);

	// properties
	scf_properties_rhf(molecule, P, M);
	
	qfree(H, nbytes);
	qfree(S, nbytes);
	qfree(X, nbytes);
	qfree(F, nbytes);
	qfree(P, nbytes);
	qfree(P0,nbytes);
	qfree(C, nbytes);
	qfree(E, M*sizeof(double));
}