1405 Universally unique identifiers. |
1405 Universally unique identifiers. |
1406 |
1406 |
1407 See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/uuid.scala\<close>. |
1407 See \<^file>\<open>$ISABELLE_HOME/src/Pure/General/uuid.scala\<close>. |
1408 -} |
1408 -} |
1409 |
1409 |
1410 module Isabelle.UUID (T, random, random_string, parse) |
1410 module Isabelle.UUID ( |
|
1411 T, |
|
1412 parse_string, parse_bytes, |
|
1413 string, bytes, |
|
1414 random, random_string, random_bytes |
|
1415 ) |
1411 where |
1416 where |
1412 |
1417 |
|
1418 import Data.ByteString (ByteString) |
|
1419 import qualified Data.ByteString |
1413 import Data.UUID (UUID) |
1420 import Data.UUID (UUID) |
1414 import qualified Data.UUID as UUID |
1421 import qualified Data.UUID as UUID |
1415 import Data.UUID.V4 (nextRandom) |
1422 import Data.UUID.V4 (nextRandom) |
1416 |
1423 |
1417 |
1424 |
1418 type T = UUID |
1425 type T = UUID |
1419 |
1426 |
|
1427 |
|
1428 {- parse -} |
|
1429 |
|
1430 parse_string :: String -> Maybe T |
|
1431 parse_string = UUID.fromString |
|
1432 |
|
1433 parse_bytes :: ByteString -> Maybe T |
|
1434 parse_bytes = UUID.fromASCIIBytes |
|
1435 |
|
1436 |
|
1437 {- print -} |
|
1438 |
|
1439 string :: T -> String |
|
1440 string = UUID.toString |
|
1441 |
|
1442 bytes :: T -> ByteString |
|
1443 bytes = UUID.toASCIIBytes |
|
1444 |
|
1445 |
|
1446 {- random id -} |
|
1447 |
1420 random :: IO T |
1448 random :: IO T |
1421 random = nextRandom |
1449 random = nextRandom |
1422 |
1450 |
1423 random_string :: IO String |
1451 random_string :: IO String |
1424 random_string = UUID.toString <$> random |
1452 random_string = string <$> random |
1425 |
1453 |
1426 parse :: String -> Maybe T |
1454 random_bytes :: IO ByteString |
1427 parse = UUID.fromString |
1455 random_bytes = bytes <$> random |
1428 \<close> |
1456 \<close> |
1429 |
1457 |
1430 generate_file "Isabelle/Byte_Message.hs" = \<open> |
1458 generate_file "Isabelle/Byte_Message.hs" = \<open> |
1431 {- Title: Isabelle/Byte_Message.hs |
1459 {- Title: Isabelle/Byte_Message.hs |
1432 Author: Makarius |
1460 Author: Makarius |
1587 LICENSE: BSD 3-clause (Isabelle) |
1615 LICENSE: BSD 3-clause (Isabelle) |
1588 |
1616 |
1589 TCP server on localhost. |
1617 TCP server on localhost. |
1590 -} |
1618 -} |
1591 |
1619 |
1592 module Isabelle.Server (localhost_name, localhost, publish_text, publish_stdout, server) where |
1620 module Isabelle.Server ( |
1593 |
1621 localhost_name, localhost, publish_text, publish_stdout, |
1594 import Control.Monad (forever) |
1622 server |
|
1623 ) |
|
1624 where |
|
1625 |
|
1626 import Data.ByteString (ByteString) |
|
1627 import Control.Monad (forever, when) |
1595 import qualified Control.Exception as Exception |
1628 import qualified Control.Exception as Exception |
1596 import Network.Socket (Socket) |
1629 import Network.Socket (Socket) |
1597 import qualified Network.Socket as Socket |
1630 import qualified Network.Socket as Socket |
1598 import qualified Control.Concurrent as Concurrent |
1631 import qualified Control.Concurrent as Concurrent |
1599 |
1632 |
1600 import Isabelle.Library |
1633 import Isabelle.Library |
1601 import qualified Isabelle.UUID as UUID |
1634 import qualified Isabelle.UUID as UUID |
|
1635 import qualified Isabelle.Byte_Message as Byte_Message |
1602 |
1636 |
1603 |
1637 |
1604 {- server address -} |
1638 {- server address -} |
1605 |
1639 |
1606 localhost_name :: String |
1640 localhost_name :: String |
1621 |
1655 |
1622 server :: (String -> UUID.T -> IO ()) -> (Socket -> IO ()) -> IO () |
1656 server :: (String -> UUID.T -> IO ()) -> (Socket -> IO ()) -> IO () |
1623 server publish handle = |
1657 server publish handle = |
1624 Socket.withSocketsDo $ Exception.bracket open (Socket.close . fst) (uncurry loop) |
1658 Socket.withSocketsDo $ Exception.bracket open (Socket.close . fst) (uncurry loop) |
1625 where |
1659 where |
1626 open :: IO (Socket, UUID.T) |
1660 open :: IO (Socket, ByteString) |
1627 open = do |
1661 open = do |
1628 socket <- Socket.socket Socket.AF_INET Socket.Stream Socket.defaultProtocol |
1662 socket <- Socket.socket Socket.AF_INET Socket.Stream Socket.defaultProtocol |
1629 Socket.bind socket (Socket.SockAddrInet 0 localhost) |
1663 Socket.bind socket (Socket.SockAddrInet 0 localhost) |
1630 Socket.listen socket 50 |
1664 Socket.listen socket 50 |
1631 |
1665 |
1632 port <- Socket.socketPort socket |
1666 port <- Socket.socketPort socket |
1633 let address = localhost_name ++ ":" ++ show port |
1667 let address = localhost_name ++ ":" ++ show port |
1634 password <- UUID.random |
1668 password <- UUID.random |
1635 publish address password |
1669 publish address password |
1636 |
1670 |
1637 return (socket, password) |
1671 return (socket, UUID.bytes password) |
1638 |
1672 |
1639 loop :: Socket -> UUID.T -> IO () |
1673 loop :: Socket -> ByteString -> IO () |
1640 loop socket password = forever $ do |
1674 loop socket password = forever $ do |
1641 (connection, peer) <- Socket.accept socket |
1675 (connection, peer) <- Socket.accept socket |
1642 Concurrent.forkFinally |
1676 Concurrent.forkFinally |
1643 (handle connection) -- FIXME check password |
1677 (do |
|
1678 line <- Byte_Message.read_line connection |
|
1679 when (line == Just password) $ handle connection) |
1644 (\_ -> Socket.close connection) |
1680 (\_ -> Socket.close connection) |
1645 return () |
1681 return () |
1646 \<close> |
1682 \<close> |
1647 |
1683 |
1648 end |
1684 end |