mirror of
				https://github.com/go-gitea/gitea
				synced 2025-10-30 19:08:37 +00:00 
			
		
		
		
	* Dropped unused codekit config * Integrated dynamic and static bindata for public * Ignore public bindata * Add a general generate make task * Integrated flexible public assets into web command * Updated vendoring, added all missiong govendor deps * Made the linter happy with the bindata and dynamic code * Moved public bindata definition to modules directory * Ignoring the new bindata path now * Updated to the new public modules import path * Updated public bindata command and drop the new prefix
		
			
				
	
	
		
			138 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			138 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package uuid
 | |
| 
 | |
| /****************
 | |
|  * Date: 14/02/14
 | |
|  * Time: 7:43 PM
 | |
|  ***************/
 | |
| 
 | |
| import (
 | |
| 	"bytes"
 | |
| 	"log"
 | |
| 	seed "math/rand"
 | |
| 	"net"
 | |
| 	"sync"
 | |
| )
 | |
| 
 | |
| 
 | |
| // **************************************************** State
 | |
| 
 | |
| func SetupCustomStateSaver(pSaver StateSaver) {
 | |
| 	state.Lock()
 | |
| 	pSaver.Init(&state)
 | |
| 	state.init()
 | |
| 	state.Unlock()
 | |
| }
 | |
| 
 | |
| // Holds package information about the current
 | |
| // state of the UUID generator
 | |
| type State struct {
 | |
| 
 | |
| 	// A flag which informs whether to
 | |
| 	// randomly create a node id
 | |
| 	randomNode bool
 | |
| 
 | |
| 	// A flag which informs whether to
 | |
| 	// randomly create the sequence
 | |
| 	randomSequence bool
 | |
| 
 | |
| 	// the last time UUID was saved
 | |
| 	past Timestamp
 | |
| 
 | |
| 	// the next time the state will be saved
 | |
| 	next Timestamp
 | |
| 
 | |
| 	// the last node which saved a UUID
 | |
| 	node []byte
 | |
| 
 | |
| 	// An iterated value to help ensure different
 | |
| 	// values across the same domain
 | |
| 	sequence uint16
 | |
| 
 | |
| 	sync.Mutex
 | |
| 
 | |
| 	// save state interface
 | |
| 	saver StateSaver
 | |
| }
 | |
| 
 | |
| // Changes the state with current data
 | |
| // Compares the current found node to the last node stored,
 | |
| // If they are the same or randomSequence is already set due
 | |
| // to an earlier read issue then the sequence is randomly generated
 | |
| // else if there is an issue with the time the sequence is incremented
 | |
| func (o *State) read(pNow Timestamp, pNode net.HardwareAddr) {
 | |
| 	if bytes.Equal([]byte(pNode), o.node) || o.randomSequence {
 | |
| 		o.sequence = uint16(seed.Int()) & 0x3FFF
 | |
| 	} else if pNow < o.past {
 | |
| 		o.sequence++
 | |
| 	}
 | |
| 	o.past = pNow
 | |
| 	o.node = pNode
 | |
| }
 | |
| 
 | |
| func (o *State) persist() {
 | |
| 	if o.saver != nil {
 | |
| 		o.saver.Save(o)
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // Initialises the UUID state when the package is first loaded
 | |
| // it first attempts to decode the file state into State
 | |
| // if this file does not exist it will create the file and do a flush
 | |
| // of the random state which gets loaded at package runtime
 | |
| // second it will attempt to resolve the current hardware address nodeId
 | |
| // thirdly it will check the state of the clock
 | |
| func (o *State) init() {
 | |
| 	if o.saver != nil {
 | |
| 		intfcs, err := net.Interfaces()
 | |
| 		if err != nil {
 | |
| 			log.Println("uuid.State.init: address error: will generate random node id instead", err)
 | |
| 			return
 | |
| 		}
 | |
| 		a := getHardwareAddress(intfcs)
 | |
| 		if a == nil {
 | |
| 			log.Println("uuid.State.init: address error: will generate random node id instead", err)
 | |
| 			return
 | |
| 		}
 | |
| 		// Don't use random as we have a real address
 | |
| 		o.randomSequence = false
 | |
| 		if bytes.Equal([]byte(a), state.node) {
 | |
| 			state.sequence++
 | |
| 		}
 | |
| 		state.node = a
 | |
| 		state.randomNode = false
 | |
| 	}
 | |
| }
 | |
| 
 | |
| func getHardwareAddress(pInterfaces []net.Interface) net.HardwareAddr {
 | |
| 	for _, inter := range pInterfaces {
 | |
| 		// Initially I could multicast out the Flags to get
 | |
| 		// whether the interface was up but started failing
 | |
| 		if (inter.Flags & (1 << net.FlagUp)) != 0 {
 | |
| 			//if inter.Flags.String() != "0" {
 | |
| 			if addrs, err := inter.Addrs(); err == nil {
 | |
| 				for _, addr := range addrs {
 | |
| 					if addr.String() != "0.0.0.0" && !bytes.Equal([]byte(inter.HardwareAddr), make([]byte, len(inter.HardwareAddr))) {
 | |
| 						return inter.HardwareAddr
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| // *********************************************** StateSaver interface
 | |
| 
 | |
| // Use this interface to setup a custom state saver if you wish to have
 | |
| // v1 UUIDs based on your node id and constant time.
 | |
| type StateSaver interface {
 | |
| 	// Init is run if Setup() is false
 | |
| 	// Init should setup the system to save the state
 | |
| 	Init(*State)
 | |
| 
 | |
| 	// Save saves the state and is called only if const V1Save and
 | |
| 	// Setup() is true
 | |
| 	Save(*State)
 | |
| }
 | |
| 
 |